Commit f2feed1
Feat: Carrier class optimization for PrebuiltDispatch chains (#10)
* Feat: Carrier class optimization for PrebuiltDispatch chains (#9)
Replace multi-allocation interceptor chains with a single file-sealed
carrier class per analyzed chain. The carrier carries only the fields
actually used (execution context, typed params, optional mask) and flows
through interceptors via Unsafe.As casts.
- Add QRY033 forked chain diagnostic (error) for builder variables
consumed by multiple execution paths
- Add InterceptorKind.WithTimeout for chain analysis tracking
- Add QueryExecutor carrier execution methods that bypass QueryState
(ExecuteCarrierAsync, ExecuteCarrierFirstAsync, etc.)
- Add CarrierClassInfo/CarrierField/ChainParameterInfo models
- Add CarrierClassBuilder to construct carrier class descriptions
- Add InterceptorCodeGenerator.Carrier.cs for carrier class emission
and carrier-aware clause body generation
- Thread carrier info through existing interceptor generators so method
signatures are shared and only the body differs
- Carrier eligibility: single-expression fluent chains and linear
variable-reassignment chains with unconditional first clause,
SELECT queries only, no collection params or unresolved types
Closes #9
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Refactor: Change entity set accessors from properties to methods
Change QuarryContext entity set accessors from partial properties
(db.Users) to partial methods (db.Users()) to enable [InterceptsLocation]
interception of chain roots. This is a breaking API change required for
carrier optimization of conditional variable-based chains.
- Update ContextCodeGenerator to emit method syntax instead of property
- Update ContextParser.DiscoverEntities to find MethodDeclarationSyntax
- Update ScaffoldCodeGenerator for method syntax
- Convert all 102 partial property declarations across 13 context files
- Convert all 614 property access usages across 36 source files
- Update doc comment examples in QuarryContext, QueryBuilder, Sql
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add carrier base classes with interface implementations
Add 8 abstract carrier base classes (CarrierBase<T>, CarrierBase<T,R>,
JoinedCarrierBase variants for 2/3/4-entity joins) that implement all
builder interface methods as explicit impls throwing InvalidOperationException.
Generated carrier classes now inherit from the appropriate base class
and declare only chain-specific fields (params, mask, pagination, timeout).
The Ctx field moves to the base class.
- Create CarrierBase.cs, JoinedCarrierBase.cs, JoinedCarrierBase3.cs,
JoinedCarrierBase4.cs in Quarry/Internal/
- Update CarrierClassBuilder with base class selection algorithm
- Add ResolveCarrierBaseClass in InterceptorCodeGenerator.Carrier.cs
using proper tuple result type sanitization
- Carrier classes now properly implement IQueryBuilder interfaces,
enabling runtime type checks (builder is Chain_X)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add Limit/Offset/Distinct/WithTimeout carrier interceptors
Generate carrier-aware interceptors for Limit, Offset, Distinct, and
WithTimeout clause types. Chains containing these clauses are now
carrier-eligible instead of falling back to the non-carrier path.
- Update early-skip in GenerateInterceptorMethod to allow carrier sites
- Add GenerateCarrierPaginationInterceptor (Limit/Offset field setters)
- Add GenerateCarrierDistinctInterceptor (noop — baked into SQL)
- Add GenerateCarrierWithTimeoutInterceptor (Timeout field setter)
- Add ResolveCarrierReceiverType helper with proper tuple handling
- Remove Limit/Offset/Distinct/WithTimeout from eligibility exclusions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add Delete/Update carrier branches and base classes
Add carrier support for Delete and Update modification chains.
- Create DeleteCarrierBase<T> and UpdateCarrierBase<T> in
ModificationCarrierBase.cs implementing IDeleteBuilder, IUpdateBuilder,
IExecutableDeleteBuilder, IExecutableUpdateBuilder interfaces
- Add carrier branches to GenerateDeleteWhereInterceptor and
GenerateUpdateWhereInterceptor in Modifications.cs
- Update ResolveCarrierBaseClass to select Delete/Update base classes
- Remove QueryKind.Select restriction from carrier eligibility
- Remove DeleteWhere/UpdateWhere clause exclusions
- Note: Set/UpdateSet clauses with open generic signatures remain
excluded from carrier eligibility (they use BindParam on real builder)
- Fix EmitCarrierClauseBody to use Unsafe.As for return type to handle
interface crossings (IUpdateBuilder -> IExecutableUpdateBuilder)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add nullable heuristic for carrier parameter fields
Normalize carrier parameter field types:
- Convert Nullable<T> to T? syntax
- Append ? to reference types (string, class names) for #nullable enable
- Preserve value types (int, decimal, etc.) without nullable annotation
- Pass through already-nullable types, generics, and arrays
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: Carrier eligibility validation and QRY033 false positive
- Add WouldExecutionTerminalBeEmitted check to prevent carrier
activation when the execution terminal would be skipped
- Fix QRY033 false positive: skip fork detection for QuarryContext
variables (context reuse across queries is expected)
- Add ResolveExecutionResultTypePublic for cross-class access
- Add 8 carrier generation snapshot tests
Note: 95 integration test failures remain from the factory method
refactor (§2) changing chain analysis for context-local-variable chains.
The ResolveReceiverVariable now walks past db.Users() to find db as
the receiver variable, changing chains from direct-fluent to
variable-based analysis. This needs a deeper fix in chain analysis.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add ChainRoot interception and fix chain analysis regression
Register entity set factory methods (db.Users()) as InterceptorKind.ChainRoot.
The ChainRoot interceptor creates the carrier directly from the context
(zero QueryBuilder allocation) and is the unconditional entry point for
all carrier chains.
Fix chain analysis regression from factory method refactor:
- ResolveReceiverVariable now skips QuarryContext locals/parameters
(treats chains rooted on context as direct fluent)
- DetectForkedChain skips context variables (QRY033 false positive fix)
- Add WouldExecutionTerminalBeEmitted validation to prevent carrier
activation when execution terminal would be skipped
- Update inline test source strings for method syntax (db.Users())
Add ChainRoot to InterceptorKind and ClauseRole enums.
Update UsageSiteDiscovery to detect context entity factory methods.
Add GenerateCarrierChainRootInterceptor for carrier path.
Add ResolveExecutionResultTypePublic for cross-class eligibility checks.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: AnalyzabilityChecker and UsageSiteDiscovery for method-based accessors
- Add InvocationExpressionSyntax handler in AnalyzabilityChecker for
db.Users() pattern (method call on context returns builder)
- Refine IsQuarryMethodCandidate to accept PascalCase parameterless
method calls as potential context entity factory methods
- IPropertySymbol audit: all 11 usages in generator confirmed safe —
they naturally filter out methods via type checks
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add IEntityAccessor<T> slim interface and EntityAccessor<T> struct
IEntityAccessor<T> is the unified entry point for all entity operations.
It does NOT extend IQueryBuilder<T> — it contains only chain-starting
methods (Where, Select, Join, Distinct, WithTimeout, ToSql) plus
modification entry points (Delete, Update, Insert, InsertMany).
EntityAccessor<T> is a zero-allocation readonly struct for the runtime
fallback path. Each method creates the appropriate builder on demand.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* WIP: IEntityAccessor unification — partial (136 build errors remain)
Add IEntityAccessor<T> slim interface and EntityAccessor<T> struct as
the unified entry point for all entity operations. Context methods now
return IEntityAccessor<T> instead of IQueryBuilder<T>.
Completed:
- IEntityAccessor<T> interface (Where, Select, Join, Delete, Update, Insert)
- EntityAccessor<T> readonly struct with public methods
- ContextCodeGenerator returns IEntityAccessor<T>
- ContextParser/UsageSiteDiscovery/ChainAnalyzer recognize EntityAccessor
- CarrierBase<T> and CarrierBase<T,R> implement IEntityAccessor<T>
- CarrierChainRoot interceptor returns IEntityAccessor<T>
- 111 partial declarations updated
- 171 Delete/Update/Insert call sites migrated
- QuarryContext base Delete/Update/Insert methods removed
Remaining (136 errors):
- DeleteCarrierBase/UpdateCarrierBase need IEntityAccessor<T> stubs
- All JoinedCarrierBase variants need IEntityAccessor<T> stubs
- Test code using db.Users().GroupBy/Limit/OrderBy directly needs
Where/Select first (not on slim accessor)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* WIP: IEntityAccessor — 0 build errors, runtime failures remain
- Added IEntityAccessor<T> stubs to all carrier base classes
(ModificationCarrierBase, JoinedCarrierBase, JoinedCarrierBase3/4)
- Fixed GroupBy/Limit/OrderBy calls on accessor with Where(u => true)
- Fixed cross-context Insert interceptor CS9144 with pragma and test simplification
- Changed return type to IEntityAccessor<T> (interface) for carrier compatibility
- 0 build errors achieved
Runtime failures (~200): interceptor this parameter type mismatch.
Generated interceptors have `this IQueryBuilder<T>` but call site receiver
is now `IEntityAccessor<T>` (since db.Users() returns IEntityAccessor<T>).
The interceptor generator needs to emit IEntityAccessor<T> as the
receiver type for chain-starting methods.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Complete IEntityAccessor unification — 0 build errors, 2 pre-existing failures
Complete the IEntityAccessor<T> unification:
- Add IEntityAccessor<T> to BuilderTypeNames for interceptor discovery
- Add ToReturnTypeName() mapping IEntityAccessor→IQueryBuilder for return types
- Update all interceptor generators to use returnType for returns, thisType for receiver
- Fix ResolveCarrierReceiverType to return IEntityAccessor when appropriate
- Fix CarrierDistinctInterceptor return type for IEntityAccessor→IQueryBuilder crossing
- Add IEntityAccessor<T> stubs to all carrier base classes (8 query + 2 modification)
- Fix 112 test code patterns for slim accessor (GroupBy/Limit/OrderBy need Where first)
- Fix generator assertion patterns for EntityAccessor return types
- Suppress CS9144 for pre-existing cross-context Insert interceptor type mismatch
- Remove QuarryContext Delete/Update/Insert base methods
Remaining failures (2, both pre-existing):
- Integration_DialectAwareMapping: NullRef in QueryState on fallback path
- Generator_WithValidEntityReader: inline compilation interceptor discovery
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: IEntityAccessor Unsafe.As crash in standalone interceptors
When a standalone interceptor (Select, Where, Join) receives
IEntityAccessor<T>, the builder is a boxed EntityAccessor struct —
not a QueryBuilder. Unsafe.As<QueryBuilder<T>>(builder) reinterpreted
the struct's memory layout as a class, causing NullReferenceException
on QueryState.Parameters.
Fix: Generator now emits ((EntityAccessor<T>)(object)builder)
.CreateQueryBuilder() before Unsafe.As when receiver is IEntityAccessor.
EntityAccessor.CreateQueryBuilder() made public for this purpose.
Also fixes GeneratorTests.Generator_WithValidEntityReader test syntax
(db.Users property → db.Users() method, complete chain with terminal).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Delete/Update/All transitions, WHERE TRUE elision, ExecuteScalar carrier fix
- Add DeleteTransition, UpdateTransition, AllTransition InterceptorKinds
so .Delete()/.Update()/.All() are recognized chain nodes with carrier
noop interceptors (Unsafe.As cast between implemented interfaces)
- Elide constant-true WHERE clauses (.Where(u => true) → "TRUE"/"1")
in both standalone interceptors and prebuilt SQL dispatch tables
- Fix ExecuteScalar carrier terminal: was missing from carrier executor
switch, causing Unsafe.As<QueryBuilder> on carrier → AccessViolation
- Fix EntityAccessor.ToSql() to delegate to CreateQueryBuilder().ToSql()
instead of throwing
- Update scaffold test expectations for IEntityAccessor<T> return type
0 build errors, 2777 passed, 1 skipped (inline projection analysis)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add QueryPlan API, remove CS9144 suppression, document IParameterSymbol
- Add QueryPlan type (Sql, Tier, Dialect) and QueryPlanTier enum
- Add IEntityAccessor<T>.ToQueryPlan() for query diagnostics
- Implement on EntityAccessor (delegates to CreateQueryBuilder().ToSql())
- Add throwing stubs to all 12 carrier base classes
- Remove CS9144 NoWarn from test project — cross-context Insert
interceptors are correctly scoped by the existing GroupByFileAndProcess
logic; the suppression was vestigial
- Remove stale CS9144 pragma and TODO comments from schema tests
- Document IParameterSymbol handling in ResolveReceiverVariable:
parameters lack declaration sites for variable-flow analysis,
correctly treated as direct fluent chains
0 build errors, 2777 passed, 1 skipped
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add ExecutionMode enum and 7 WithCommand carrier execution methods
Phase 1 of carrier inline parameter binding. Adds command-based executor
methods that accept a pre-built DbCommand from the terminal interceptor,
separating command creation (terminal) from execution/materialization (executor).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add IsSensitive, IsEnum, EnumUnderlyingType to chain parameter model
Phase 2 of carrier inline parameter binding. Propagates enum type info
from expression translation through ParameterInfo to ChainParameterInfo,
enabling compile-time enum cast codegen in the terminal interceptor.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add CarrierStaticField model, emit static FieldInfo caches on carrier class
Phase 3 of carrier inline parameter binding. Carrier classes now declare
static FieldInfo? F0, F1, ... fields for cached expression extraction,
and the remark reflects the 1-allocation design.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Terminal inline parameter binding — eliminate param array allocation
Phase 4 of carrier inline parameter binding. The carrier terminal now
creates DbCommand inline with per-parameter CreateParameter/Value/Add,
replacing the object?[] array + CreateCarrierCommand loop. Includes
sensitivity-aware parameter logging and BoundSensitive log method.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Remap FieldInfo caches to carrier class, skip interceptor-class emission
Phase 5 of carrier inline parameter binding. Clause interceptors now
reference static FieldInfo caches on the carrier class (Chain_N.F0)
instead of the interceptor class. FieldInfo declarations for carrier
chain members are no longer emitted on the interceptor class.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Remove old array-based carrier executor methods and helpers
Phase 7 cleanup. Removes ExecuteCarrierAsync (7 overloads),
CreateCarrierCommand (2 overloads), and LogCarrierParameters — all
superseded by the inline command-based WithCommand methods.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: Only emit static FieldInfo cache for captured parameters
Static FieldInfo? fields on the carrier class are only needed for
parameters extracted via expression tree reflection. Skip emission
for non-captured parameters to eliminate CS0649 warnings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: Inline __timeout variable and fix UPDATE parameter offset for conditional WHERE clauses
Inline the __timeout variable directly into CommandTimeout assignment, and fix a bug where
conditional WHERE clause parameters in UPDATE statements were bound to the same index as the
SET parameter (@p0) instead of being offset correctly (@p1). The root cause was that
BuildTemplates did not create synthetic templates for UpdateSet clauses whose SetClauseInfo
was lost during enrichment fallback, so ComputeParameterBaseOffsets did not account for the
SET parameter in the running offset.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Refactor: Unify Delete/Update Where interceptors and extract shared modification helpers
- Merge GenerateDeleteWhereInterceptor and GenerateUpdateWhereInterceptor into
a single GenerateModificationWhereInterceptor parameterized by isDelete flag,
eliminating ~160 lines of near-duplicate code
- Extract GetColumnValueExpression helper for FK navigation and type mapping
used across Insert, Update POCO, and other entity property extraction
- Extract EmitInsertColumnSetup and EmitInsertEntityBindings shared helpers
to deduplicate insert interceptor code
- Fix CS8604 nullable warning in EmitCarrierExecutionTerminal parameter
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Feat: Add carrier optimization for Insert operations
- Add InsertTransition InterceptorKind and ClauseRole for .Insert(entity) calls
- Add QueryKind.Insert with pre-built INSERT SQL via CompileTimeSqlBuilder
- Create InsertCarrierBase<T> runtime base class with IInsertBuilder<T> stubs
- Add Entity field (FieldRole.Entity) to carrier class for insert chains
- Generate carrier insert transition interceptor (stores entity on carrier)
- Generate carrier insert execution terminals with inline parameter binding
from entity properties (ExecuteNonQuery, ExecuteScalar, ToSql)
- Extend chain analysis pipeline: IsExecutionKind, MapInterceptorKindToClauseRole,
DetermineQueryKind, BuildChainParameters, and BuildPrebuiltChainInfo
- Skip carrier path for MySQL ExecuteScalar inserts (requires separate
SELECT LAST_INSERT_ID() query incompatible with single-command carrier)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: Include execution sites in chain member tracking and add carrier tests
- Add execution site UniqueIds to chainMemberUniqueIds and fileChainMemberIds
so non-analyzable execution sites (like InsertExecuteNonQuery) are included
in the site list passed to the code generator
- Skip ShouldSkipNonTranslatableClause for carrier-optimized sites since their
metadata is on the chain, not the individual site
- Add carrier generation tests for Insert ExecuteNonQuery, Insert ExecuteScalar,
and Update with Set+Where chains
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: Address PR review items for carrier optimization
- Suppress CS8602 warnings in generated interceptor code via pragma
- Remove planning documents (impl-plan*.md) from repo
- Guard against null EnumUnderlyingType in GetParameterValueExpression
- Extract shared terminal eligibility predicates (CanEmitReaderTerminal,
CanEmitScalarTerminal, CanEmitNonQueryTerminal, CanEmitInsertTerminal)
used by both WouldExecutionTerminalBeEmitted and terminal generators
- Fix mapping field name reference (s_ prefix → GetMappingFieldName)
- Add IDialectAwareTypeMapping.ConfigureParameter for mapped types in
inline command creation, matching QueryExecutor.CreateCommand behavior
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: Reject 3+ param lambdas in two-entity join translator to enable carrier optimization
ExtractTwoParameterLambdaExpression used `< 2` instead of `!= 2`, causing it
to accept chained join lambdas (e.g., 4-param `(u, o, oi, p) => ...`) and
return only the first two parameter names. This produced a "successful" but
incorrect JoinClauseInfo during discovery (e.g., `ON @p0 = @p1` instead of
column references), which prevented the enrichment phase from re-translating
with the correct multi-entity context via TranslateChainedJoinFromEntityInfo.
With the fix, chained join lambdas now correctly fall through to the enrichment
path, producing proper column-to-column SQL (e.g., `ON "t2"."ProductName" =
"t3"."ProductName"`). Since join conditions resolve to zero runtime parameters,
BuildChainParameters returns an empty list, making 4-way join chains
carrier-eligible using the existing JoinedCarrierBase4 infrastructure.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent 3cc8fdc commit f2feed1
92 files changed
Lines changed: 6361 additions & 1404 deletions
File tree
- src
- Quarry.Benchmarks
- Benchmarks
- Context
- Quarry.Generator
- Generation
- Models
- Parsing
- Sql
- Translation
- Quarry.Tests
- Generation
- Integration
- Samples
- Scaffold
- SqlOutput
- Quarry
- Context
- Internal
- Logging
- Query
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
| 36 | + | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| |||
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
67 | | - | |
| 67 | + | |
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
| |||
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
98 | | - | |
| 98 | + | |
99 | 99 | | |
100 | 100 | | |
101 | 101 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
119 | | - | |
| 119 | + | |
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
| 53 | + | |
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
| |||
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
112 | | - | |
| 112 | + | |
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| |||
163 | 163 | | |
164 | 164 | | |
165 | 165 | | |
166 | | - | |
| 166 | + | |
167 | 167 | | |
168 | 168 | | |
169 | 169 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
68 | | - | |
| 68 | + | |
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
| |||
134 | 134 | | |
135 | 135 | | |
136 | 136 | | |
137 | | - | |
| 137 | + | |
138 | 138 | | |
139 | 139 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
50 | | - | |
| 50 | + | |
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
| |||
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
115 | | - | |
| 115 | + | |
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
| 54 | + | |
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| |||
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
111 | | - | |
| 111 | + | |
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
51 | | - | |
| 51 | + | |
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
| |||
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
108 | | - | |
| 108 | + | |
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
56 | | - | |
| 56 | + | |
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| |||
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
112 | | - | |
| 112 | + | |
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
9 | | - | |
10 | | - | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
11 | 11 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
444 | 444 | | |
445 | 445 | | |
446 | 446 | | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
447 | 462 | | |
448 | 463 | | |
449 | 464 | | |
| |||
0 commit comments