Commit 0c1a4c8
feat: sub-project 1 Phase 4-6 — resolver pipeline wiring + 4 Java detector migrations (#104)
* feat(analyzer): wire ResolverRegistry bootstrap + per-file resolve
Phase 4 of sub-project 1 — pipeline wiring (plan tasks 19-21). The
orchestration boundary for the symbol-resolution pass that sits between
parse and detect.
ResolverRegistry becomes a new constructor dependency on Analyzer:
@Autowired primary ctor adds it as the 10th arg; the 6-arg backward-compat
ctor defaults to `new ResolverRegistry(List.of())` so existing tests +
direct constructor call-sites still work and observe the same behaviour
(every ctx.resolved() reads back as Optional.of(EmptyResolved.INSTANCE)).
Two private helpers do the work:
- bootstrapResolvers(Path) — called exactly once at the top of every
pipeline entry point (run / runBatchedIndex / runSmartIndex), before
any file iteration. ResolverRegistry already swallows per-resolver
failures; this catches the registry-itself-blowing-up case so the
pipeline keeps going with NOOP resolvers.
- resolveFor(DiscoveredFile, Object) — called per file at all three
DetectorContext build sites (analyzeFile, the batched-index variant,
and the regex-only fallback). Catches ResolutionException +
RuntimeException and falls back to EmptyResolved.INSTANCE so one
file's resolver blow-up cannot disrupt the rest of the pass.
Every DetectorContext now reads back ctx.resolved() == Optional.of(...) —
either the language's resolver result or EmptyResolved.INSTANCE. Detectors
that don't care simply ignore the field; migrations to consume the
resolved view follow in Phase 6.
IndexCommand reaches the resolver via Analyzer.runSmartIndex, so plan
task 21 ("mirror in IndexCommand") lands automatically with the analyzer
wiring — no separate command-side changes required.
8 wiring tests cover:
- bootstrap called exactly once per run (single file, many files,
empty repo)
- bootstrap path is the normalised absolute repoPath
- resolverFor("java") called for each java file
- ctx.resolved() is Optional.of(EmptyResolved.INSTANCE) when no
resolver is registered for the language
- legacy 6-arg ctor still produces a working analyzer with the same
observable resolved() shape
Plan: docs/plans/2026-04-27-sub-project-1-resolver-spi-and-java-pilot.md
(tasks 19, 20, 21).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(resolver/java): lazy-parse Java source so ctx.resolved() carries JavaResolved
The orchestrator (Analyzer) only parses structured-language files at the
top level (YAML/JSON/etc.) — Java is parsed independently inside
AbstractJavaParserDetector via its ThreadLocal pool. Without an extra
hook, ctx.resolved() always reads back as EmptyResolved for Java because
the SPI's resolve(file, parsedAst) was never given a CompilationUnit.
Two minimal changes flip ctx.resolved() to JavaResolved for Java files:
1. JavaSymbolResolver.resolve() now accepts a String source as well as
a CompilationUnit. When given a String, it parses with a fresh
JavaParser configured with the symbol solver, so resolution is
attached to the resulting CU. Per-call JavaParser allocation is
intentional (JavaParser instances aren't thread-safe and resolve()
is invoked from virtual threads concurrently); cost is small
relative to the parse itself.
2. Analyzer.resolveFor() now takes content as a 3rd arg and uses it as
the parsedAst fallback when the orchestrator's structured parser
produced nothing. The 3 call sites (analyzeFile, the batched-index
variant, and the regex-only fallback) all pass content.
Permissive parsing: JavaParser produces a CompilationUnit even for files
with syntax errors (with attached Problems). The resolver returns
JavaResolved in that case — production analysis must keep going across
malformed files instead of failing the whole pass. EmptyResolved is only
returned when getResult().isEmpty(), which JavaParser reserves for hard
configuration-level failures.
New tests:
- JavaSymbolResolverTest: 4 new cases — valid source string parses,
junk input doesn't throw or null, empty source produces an empty CU,
unknown AST type (e.g. a Path) → EmptyResolved (replaces the old
"wrong AST type" String case).
- AnalyzerResolverWiringTest: javaFilePicksUpJavaResolvedWhenResolverRegistered
asserts ctx.resolved() is JavaResolved (not EmptyResolved) once a
JavaSymbolResolver is registered with the registry. This is the
bridge that lets detector migrations (Phase 6 / tasks 24-29)
actually consume RESOLVED-tier resolution from ctx.resolved().
Plan: docs/plans/2026-04-27-sub-project-1-resolver-spi-and-java-pilot.md
(unblocks tasks 24-29).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(detector/jpa): consume ctx.resolved() for RESOLVED-tier MAPS_TO edges
Phase 6 task 26 (and the JPA-relationship part of task 24) — first
detector migration to the resolver SPI.
When ctx.resolved() carries a JavaResolved (Analyzer registered a
JavaSymbolResolver), the detector now:
1. Uses the resolver-parsed CompilationUnit (which has the symbol
solver attached) instead of the local ThreadLocal-pool parse — no
double-parse, and Type.resolve() works inside the AST walk.
2. Attempts to resolve each @onetomany / @manytoone / @OnetoOne /
@manytomany field's target type to a fully-qualified name via the
symbol solver:
- Generic-arg case: List<Owner> → resolves the type argument
- Direct-field case: Owner → resolves the field type
3. On resolution success, attaches target_fqn to the edge properties
and stamps Confidence.RESOLVED + source = "jpa_entity". The simple-
name edge ID + target placeholder are unchanged so EntityLinker's
post-pass keeps working — target_fqn rides as the canonical pointer.
4. On resolution failure (missing classpath, unsolvable symbol, etc.),
falls back gracefully to the existing simple-name path with the
base-class default confidence.
Existing detector behaviour is unchanged when ctx.resolved() is empty
or carries EmptyResolved — the 29 pre-existing JpaEntityDetectorExtended
tests still pass without modification.
5 new tests in JpaEntityDetectorResolvedTest cover the three plan-
required modes (resolved, fallback, mixed) plus generic-arg resolution
and the no-resolved-at-all legacy ctx path:
- resolvedModeProducesResolvedEdgeWithTargetFqn — two Owner classes
in different packages; with resolution, the imported one wins and
edge.target_fqn = "com.example.a.Owner" + RESOLVED.
- resolvedModeFindsCollectionGenericArg — @onetomany List<Owner>
resolves the generic arg, not the List type.
- fallbackModeMatchesPreSpecBaseline — EmptyResolved → no target_fqn
+ raw-default confidence (orchestrator stamps SYNTACTIC at boundary).
- fallbackModeWhenContextHasNoResolvedAtAll — Optional.empty() also
produces the same baseline shape (legacy ctx path safety).
- mixedModeUsesResolverWhereAvailable — one resolvable + one
unresolvable relationship in the same class; the resolvable edge
is RESOLVED + target_fqn, the unresolvable falls back.
Plan: docs/plans/2026-04-27-sub-project-1-resolver-spi-and-java-pilot.md
(task 26).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(detector/repository): consume ctx.resolved() for RESOLVED-tier QUERIES edges
Phase 6 task 25 (Spring Data repository migration). Same shape as the
JpaEntityDetector migration applied to RepositoryDetector — promote the
QUERIES edge from SYNTACTIC → RESOLVED with a stable target FQN when
the resolver can pin the entity type.
The detector stays regex-first (the inheritance regex is the cheapest
positive signal for "this file is a Spring Data repo"), and uses
ctx.resolved() purely for the FQN upgrade. When ctx.resolved() carries
a JavaResolved, the detector walks JavaResolved.cu(), finds the
interface declaration matching the regex-extracted name, takes the
first type argument of its first extended type (e.g. JpaRepository<User,
Long> → User), and resolves it via the attached symbol solver.
On success:
- repo node gains entity_fqn (so the RepositoryNode can be reasoned
about without a join through the entity index).
- QUERIES edge gains target_fqn + Confidence.RESOLVED + source =
"spring_repository".
On failure (no ctx.resolved(), EmptyResolved, no parent type with
generics, solver can't find the type), behaviour is unchanged from
before this commit — the simple-name placeholder edge with default
confidence is what shipped before, and tests confirm that path is
intact.
4 new tests in RepositoryDetectorResolvedTest cover the same three
modes as the JpaEntity migration:
- resolvedModeProducesResolvedEdgeWithTargetFqn — two User classes
in different packages; the imported one wins on entity_fqn +
target_fqn.
- fallbackModeMatchesPreSpecBaseline — EmptyResolved → no FQN
properties + no RESOLVED stamp.
- fallbackModeWhenContextHasNoResolvedAtAll — Optional.empty() also
safe.
- mixedModeFallsBackForUnreachableEntityType — repo whose entity has
no source: solver fails → fallback to simple-name + default tier.
Plan: docs/plans/2026-04-27-sub-project-1-resolver-spi-and-java-pilot.md
(task 25).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(detector/spring-rest): emit RESOLVED MAPS_TO edges for @RequestBody DTOs
Phase 6 task 29 (SpringRestDetector migration). Per the plan:
"Resolves @RequestBody UserDto dto and @PathVariable types. Edge:
MAPS_TO from endpoint node to the resolved DTO class."
When ctx.resolved() carries a JavaResolved, the detector now:
1. Uses the resolver-parsed CompilationUnit (symbol solver attached)
instead of the local ThreadLocal-pool parse — Type.resolve() works
inside the AST walk for parameter type resolution.
2. After emitting each ENDPOINT node + its EXPOSES edge, scans the
method's parameters for @RequestBody. For each binding parameter
whose type is a class/interface, attempts to resolve to a stable
fully-qualified name via the symbol solver.
3. On success, emits a MAPS_TO edge:
endpoint --MAPS_TO--> *:<simpleName>
stamped with target_fqn / parameter_kind=request_body /
parameter_name properties + Confidence.RESOLVED + source =
"spring_rest". Target node uses NodeKind.CLASS so EntityLinker can
resolve the FQN to a concrete class node post-pass.
4. On failure (primitive type, classpath gap, generic variable,
etc.), no MAPS_TO edge is emitted — endpoint extraction itself is
unaffected. The endpoint's `parameters` property still records the
simple type name for the lexical / SYNTACTIC tier.
This is purely additive: when ctx.resolved() is empty / EmptyResolved,
the detector behaves identically to before the migration. The 27
existing SpringRestDetectorExtended tests pass unchanged.
4 new tests in SpringRestDetectorResolvedTest cover:
- resolvedModeProducesResolvedMapsToEdge — two UserDto in different
packages; imported FQN wins on edge.target_fqn + RESOLVED stamp +
parameter_name property.
- fallbackModeProducesNoMapsToEdge — EmptyResolved → endpoint still
emitted, but no MAPS_TO (additive contract).
- fallbackModeWhenContextHasNoResolvedAtAll — Optional.empty() also
produces no MAPS_TO.
- mixedModeFallsBackForUnreachableType — endpoint with one resolvable
DTO + one unresolvable: only the resolvable one gets MAPS_TO.
Plan: docs/plans/2026-04-27-sub-project-1-resolver-spi-and-java-pilot.md
(task 29).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(detector/class-hierarchy): consume ctx.resolved() for RESOLVED EXTENDS/IMPLEMENTS edges
Phase 6 task 24-style migration applied to ClassHierarchyDetector.
Class hierarchy is high-leverage for resolution: simple-name superclass
references like "extends Service" are routine across unrelated codebases,
and EXTENDS / IMPLEMENTS edges are downstream-load-bearing for
blast-radius / dead-code / cycle / topology analysis. Pinning the
target FQN turns "Service-named-something" into a stable cross-file
reference.
When ctx.resolved() carries a JavaResolved, the detector now:
1. Uses the resolver-parsed CompilationUnit (symbol solver attached).
2. For each parent type in extendedTypes / implementedTypes, calls
a single new helper addHierarchyEdge() that:
- tries to resolve the type via the symbol solver
- on success, attaches target_fqn to edge properties + stamps
Confidence.RESOLVED + source = "java.class_hierarchy"
- on failure (and always when ctx.resolved() is empty), emits
the existing simple-name placeholder edge with raw default
confidence (orchestrator stamps SYNTACTIC at the boundary).
3. The 4 prior in-line edge-emission blocks (class-extends,
interface-extends, class-implements, enum-implements) collapse to
two-line iterations through addHierarchyEdge — net is fewer LOC
plus the new resolution capability.
Existing 30 ClassHierarchyDetectorExtended tests pass unchanged — node
emission, regex fallback, the property shapes, and the simple-name
edge IDs / target placeholders are all preserved.
5 new tests in ClassHierarchyDetectorResolvedTest:
- resolvedModeStampsResolvedTierOnExtendsEdge — two BaseService in
different packages; imported one wins on edge.target_fqn.
- resolvedModeStampsResolvedTierOnImplementsEdge — same shape for
interface implements.
- fallbackModeMatchesPreSpecBaseline — EmptyResolved → no FQN, no
RESOLVED stamp.
- fallbackModeWhenContextHasNoResolvedAtAll — Optional.empty() also
safe.
- mixedModeFallsBackForUnreachableType — class extends a known type,
implements an unknown one: EXTENDS is RESOLVED, IMPLEMENTS falls
back gracefully.
This brings the migrated-detector count to 4 (JpaEntityDetector,
RepositoryDetector, SpringRestDetector, ClassHierarchyDetector) — at
the lower bound of the plan's "4-6 Java detectors migrated as proof of
value".
Plan: docs/plans/2026-04-27-sub-project-1-resolver-spi-and-java-pilot.md
(spirit of tasks 24-29 — using the actual detectors that exist in this
repo, not the plan's hypothetical names).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(changelog): document resolver pipeline wiring + 4 Java detector migrations
Extends the [Unreleased] entry with the Phase 4 + 6 follow-up work
shipped on this branch — the resolver is now wired end-to-end into
Analyzer and four Java detectors consume ctx.resolved() to emit
RESOLVED-tier edges with stable target FQNs:
- JpaEntityDetector — @onetomany / @manytoone MAPS_TO targets
- RepositoryDetector — JpaRepository<T, ID> entity FQN
- SpringRestDetector — @RequestBody DTO MAPS_TO edges
- ClassHierarchyDetector — EXTENDS / IMPLEMENTS FQN targets
Also covers the JavaSymbolResolver lazy-parse extension that lets the
orchestrator pass raw source content for Java (the structured parser
doesn't cover Java, so without this the resolver could never receive a
CompilationUnit).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(resolver/java): add Layer 3 + Layer 6 — concurrency stress + determinism
Phase 7 of the resolver-and-Java-pilot plan, top two highest-leverage
aggressive-testing layers.
Layer 6 — JavaSymbolResolverDeterminismTest (4 tests):
- sameInputResolvesToSameFqnEveryTime — single resolver, 25 iterations
over the same source must produce the same resolved FQN
("com.example.a.Owner"). Pins the value-stable contract under repeated
calls (different identity, same value).
- twoResolverInstancesOverSameProjectAgree — two independent resolver
instances bootstrapped against the same root must produce the same
FQN for the same source — establishes that bootstrap is value-stable
across instances, not just within one.
- rebootstrapStillProducesSameFqn — resolve, rebootstrap, resolve
again; FQN is unchanged. The orchestrator calls bootstrap once, but
if the resolver were ever refreshed mid-run, the value contract must
still hold.
- deeperFqnsAreAlsoStable — same shape on a 3-segment package
(com.example.inner.deep.Marker) so a divergence on a deeper lookup
can't hide behind a 1-level passing test.
Layer 3 — JavaSymbolResolverConcurrencyTest (3 tests):
- parallelResolveNeverThrowsAndAlwaysAgrees — 256 virtual threads each
resolve the same source; the aggregated FQN set must be of size 1.
Catches "thread X's CU bleeds into thread Y" / shared-mutable-state
classes of races. Runs cleanly on the per-call-fresh-JavaParser
contract.
- parallelResolveAcrossDistinctFilesProducesPerFileResults — 200
distinct Consumer files each resolved on a virtual thread; aggregate
FQN set = {com.example.api.Target}. Catches "one thread's resolved
state survives into another thread's resolution" classes of bugs.
- parallelResolveOnGarbageInputDoesNotThrow — 256 virtual threads each
pass garbage strings; no exceptions escape and no thread returns null.
The resolver's "no throw, no null" contract holds under concurrency.
Plan: docs/plans/2026-04-27-sub-project-1-resolver-spi-and-java-pilot.md
(tasks 30 + 31).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* checkpoint: pre-yolo 2026-04-28T01:16:10
* checkpoint: pre-yolo 2026-04-28T01:20:26
* fix(resolver): four robustness fixes from dual-agent (superpowers + codex) brainstorm
Both reviewers independently identified the same four corner-cases in the
Phase 4 + 6 wiring; this lands the converged fix list.
1. JavaSymbolResolver — `volatile` on `solver` and `combined`
bootstrap() publishes; resolve() and the public accessors read from
arbitrary virtual-thread carriers. The JLS Thread Start Rule covers
the executor.submit() path but does NOT cover callers that read the
public accessors after bootstrap on a different thread. Cheap fence,
closes the visibility hole.
2. JavaSymbolResolver.resolve(String) — strict parse-success check
JavaParser is permissive and may return a partial CompilationUnit
even when the source has parse problems. Resolving against a partial
CU silently emits simple-name-only edges and looks like coverage
even though resolution is broken. Treat any non-success as
EmptyResolved so the graph never carries phantom RESOLVED-tier
edges from broken parses.
3. Analyzer.resolveFor — catch StackOverflowError
Pathological generic / type-cycle inputs can blow JavaSymbolSolver's
recursion stack. Catching the Error keeps the virtual-thread worker
alive and degrades that file's resolution to lexical. Other Errors
(OOM, ThreadDeath) remain fatal and propagate.
4. JavaSourceRootDiscovery.containsJavaFile — try-with-resources on Files.walk
Files.walk holds an open directory stream; without a close, the file
descriptor leaks for every plain-layout fallback scan. Cheap fix.
mvn test: 3592 tests / 0 failures / 31 skipped (full suite, no regressions).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* checkpoint: pre-yolo 2026-04-28T01:32:51
* checkpoint: pre-yolo 2026-04-28T01:42:48
* test(resolver): aggressive-testing layers 1, 4, 5, 7, 8 + Layer 9 PIT profile
Phase 7 of the sub-project 1 plan. Spec §12's testing matrix lands as
five new test classes (26 tests) plus a non-default Maven profile.
Layers 3 + 6 were already shipped in the prior commit on this branch.
Layer 1 — JavaSymbolResolverLayer1ExtendedTest (16):
Spec §12 Layer 1 cases not exercised by the existing
JavaSymbolResolverTest — deep generics (Map<String, List<Set<UUID>>>),
inner classes (static + non-static), records, sealed hierarchies,
enums with abstract methods, default-method interfaces, abstract
classes, annotation types, same simple name in different packages
pinned by import direction, JDK Optional/Stream/List via
ReflectionTypeSolver, multi-source-root cross-reference
(src/main ↔ src/test), wildcard imports, cyclic imports both
directions.
Layer 4 — JavaSymbolResolverPathologicalTest (3):
10K-line class, 1000 imports (most unresolvable), 10-deep generic
nesting (programmatically built so brackets are provably balanced).
@timeout per-test is the regression sentinel against quadratic
memoization; Surefire's default heap covers the spec's -Xmx512m
target many times over so we don't pin it explicitly.
Layer 5 — JavaSymbolResolverAdversarialTest (5):
Unbalanced braces (strict-success → EmptyResolved, strong assertion),
mis-tagged Kotlin (no exception/null, branch-agnostic — JavaParser's
permissiveness for "fun ... { }" is implementation-specific),
mis-tagged random bytes, mixed source root with .java + .txt siblings
(only .java enters the solver), empty source root (no Java files
anywhere) bootstraps via ReflectionTypeSolver alone.
Layer 7 — E2EResolverPetclinicTest (1, env-gated):
Runs JavaSymbolResolver against every .java under $E2E_PETCLINIC_DIR
and asserts bootstrap < 10 s (spec §9 budget), no exception, > 50%
files produce JavaResolved (i.e. strict-success isn't false-rejecting
valid Java). Lighter than spec §12 Layer 7's full precision/recall
comparison — that needs a pre-resolver baseline JSON checked into
test resources, captured at implementation time. This stand-in is the
strongest signal we have until that baseline lands.
Layer 8 — JavaSymbolResolverRandomizedTest (1, 100 samples):
Hand-rolled randomized generator with fixed seed (0xC0DE197042L). Per
the plan's license guidance, jqwik (EPL-2.0) isn't on the project's
preferred-license list (~/.claude/rules/dependencies.md prefers
MIT/Apache/BSD); this is the documented JUnit + java.util.Random
fallback. Properties: never throws unchecked, never returns null,
completes per-file in < 1 s budget.
Layer 9 — mutation Maven profile (non-default):
Adds pitest-maven 1.18.0 (Apache-2.0) targeting
intelligence.resolver.* and model.Confidence. Run with
mvn -P mutation org.pitest:pitest-maven:mutationCoverage \
-Dfrontend.skip=true -Ddependency-check.skip=true
Reports under target/pit-reports/. Non-gating per the plan; the
≥ 80% target is a follow-up signal once a first run lands.
Full suite: mvn test → 3618 / 0 failures / 32 skipped (1 new skip is
the env-gated E2EResolverPetclinicTest).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* checkpoint: pre-yolo 2026-04-28T01:47:06
* docs(claude+summary): close out sub-project 1 plan tasks 40 + 41
Plan §40 / §41 close-out — the resolver SPI, Confidence schema,
CACHE_VERSION bump, and runtime lifecycle gotchas now land in
CLAUDE.md and PROJECT_SUMMARY.md, not just CHANGELOG.md.
CLAUDE.md Gotchas:
- Cache versioning bullet updated 4 → 5 with reason (Confidence/source
schema), so future agents reading the gotcha don't propagate the
stale "4" forward.
- "Symbol resolver runs at index-time only" — bootstrapResolvers and
resolveFor are wired into run / runBatchedIndex / runSmartIndex only.
Never reached at serve. Prevents future agents from reaching for
ResolverRegistry from serve-mode code paths.
- "Confidence + source mandatory on every CodeNode/CodeEdge" —
DetectorEmissionDefaults stamps the floor; RESOLVED is opt-in via
ctx.resolved(). Reading legacy data is non-throwing.
- "JavaSymbolResolver.resolve() allocates a fresh JavaParser per call"
— intentional thread-safety boundary for virtual-thread fan-out, not
a perf bug.
- "Strict parse-success check" — resolve(String) returns EmptyResolved
on any JavaParser problem so the graph never carries phantom
RESOLVED-tier edges from partial-CU outputs.
- "Volatile fields on JavaSymbolResolver" — closes the public-accessor
visibility race per the dual-agent brainstorm fix.
PROJECT_SUMMARY.md:
- Tech-stack row updated to "AST + symbols (Java) | JavaParser 3.28.0
+ javaparser-symbol-solver-core 3.28.0".
- Cache dir line updated CACHE_VERSION=4 → 5.
- Two new gotchas (resolver-is-index-time-only, strict parse-success)
cross-referencing the canonical CLAUDE.md entries.
No source changes. Full mvn test was last green at 3618 / 0 / 32
skipped (unchanged for this docs-only commit).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 47e6404 commit 0c1a4c8
26 files changed
Lines changed: 2827 additions & 69 deletions
File tree
- src
- main/java/io/github/randomcodespace/iq
- analyzer
- detector/jvm/java
- intelligence/resolver/java
- test/java/io/github/randomcodespace/iq
- analyzer
- detector/jvm/java
- intelligence/resolver/java
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
85 | | - | |
86 | | - | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
87 | 130 | | |
88 | 131 | | |
89 | 132 | | |
| |||
97 | 140 | | |
98 | 141 | | |
99 | 142 | | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
100 | 199 | | |
101 | 200 | | |
102 | 201 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
421 | 421 | | |
422 | 422 | | |
423 | 423 | | |
424 | | - | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
425 | 430 | | |
426 | 431 | | |
427 | 432 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| |||
114 | 114 | | |
115 | 115 | | |
116 | 116 | | |
117 | | - | |
| 117 | + | |
118 | 118 | | |
119 | 119 | | |
120 | 120 | | |
| |||
138 | 138 | | |
139 | 139 | | |
140 | 140 | | |
141 | | - | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
142 | 144 | | |
143 | 145 | | |
144 | 146 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
489 | 489 | | |
490 | 490 | | |
491 | 491 | | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
492 | 528 | | |
493 | 529 | | |
494 | 530 | | |
| |||
0 commit comments