@saptools/service-flow 0.1.67 → 0.1.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +20 -8
- package/TECHNICAL-NOTE.md +27 -0
- package/dist/{chunk-ZQABU7MR.js → chunk-AEM4JY22.js} +12676 -6714
- package/dist/chunk-AEM4JY22.js.map +1 -0
- package/dist/cli.js +2325 -413
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +61 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/cli/003-doctor-package-resolution.ts +68 -0
- package/src/cli/doctor.ts +25 -14
- package/src/db/000-call-fact-repository.ts +475 -342
- package/src/db/001-fact-lifecycle.ts +60 -30
- package/src/db/002-fact-json-inventory.ts +169 -0
- package/src/db/003-current-fact-semantics.ts +698 -0
- package/src/db/004-package-target-invalidation.ts +173 -0
- package/src/db/005-schema-structure.ts +201 -0
- package/src/db/006-relative-symbol-resolution.ts +443 -0
- package/src/db/007-package-fact-semantics.ts +573 -0
- package/src/db/008-relative-fact-semantics.ts +207 -0
- package/src/db/009-binding-fact-semantics.ts +347 -0
- package/src/db/010-package-symbol-surface-semantics.ts +320 -0
- package/src/db/011-symbol-call-semantics.ts +144 -0
- package/src/db/012-binding-reference-proof.ts +264 -0
- package/src/db/migrations.ts +16 -3
- package/src/db/repositories.ts +113 -6
- package/src/db/schema.ts +4 -2
- package/src/index.ts +12 -0
- package/src/indexer/repository-indexer.ts +72 -11
- package/src/indexer/workspace-indexer.ts +123 -32
- package/src/linker/003-package-import-symbol-resolver.ts +363 -131
- package/src/linker/004-event-subscription-handler-linker.ts +2 -0
- package/src/linker/005-odata-path-structure.ts +371 -0
- package/src/linker/cross-repo-linker.ts +2 -1
- package/src/linker/odata-path-normalizer.ts +273 -180
- package/src/linker/service-resolver.ts +197 -77
- package/src/parsers/002-symbol-import-bindings.ts +516 -0
- package/src/parsers/003-package-public-surface.ts +661 -0
- package/src/parsers/004-fact-identity.ts +108 -0
- package/src/parsers/005-event-subscription-facts.ts +281 -0
- package/src/parsers/006-binding-identity.ts +343 -0
- package/src/parsers/007-source-fact-reconciliation.ts +105 -0
- package/src/parsers/008-package-surface-publication.ts +82 -0
- package/src/parsers/009-symbol-call-facts.ts +528 -0
- package/src/parsers/010-package-public-surface-analysis.ts +352 -0
- package/src/parsers/011-binding-lexical-scope.ts +583 -0
- package/src/parsers/012-package-fact-contract.ts +306 -0
- package/src/parsers/013-executable-body-eligibility.ts +35 -0
- package/src/parsers/014-service-binding-helper-flow.ts +240 -0
- package/src/parsers/015-service-binding-collector.ts +693 -0
- package/src/parsers/016-local-symbol-reference.ts +261 -0
- package/src/parsers/017-symbol-derived-contexts.ts +268 -0
- package/src/parsers/018-package-commonjs-syntax.ts +142 -0
- package/src/parsers/019-binding-assignment-targets.ts +76 -0
- package/src/parsers/020-stable-local-value.ts +217 -0
- package/src/parsers/021-binding-visibility.ts +152 -0
- package/src/parsers/operation-path-analysis.ts +6 -1
- package/src/parsers/outbound-call-parser.ts +19 -6
- package/src/parsers/package-json-parser.ts +45 -3
- package/src/parsers/service-binding-parser-helpers.ts +86 -15
- package/src/parsers/service-binding-parser.ts +147 -597
- package/src/parsers/symbol-parser.ts +482 -353
- package/src/trace/002-trace-diagnostics.ts +36 -1
- package/src/trace/016-compact-projector.ts +16 -17
- package/src/trace/020-compact-field-projection.ts +48 -37
- package/src/trace/021-compact-decision-normalization.ts +105 -0
- package/src/trace/022-trace-fact-preflight.ts +21 -0
- package/src/trace/023-nested-event-scopes.ts +23 -0
- package/src/trace/024-compact-observation-decision.ts +76 -0
- package/src/trace/025-trace-implementation-scope.ts +123 -0
- package/src/trace/026-trace-start-scope.ts +335 -0
- package/src/trace/027-trace-scope-execution.ts +566 -0
- package/src/trace/028-trace-operation-execution.ts +336 -0
- package/src/trace/029-trace-start-implementation.ts +172 -0
- package/src/trace/trace-engine.ts +122 -624
- package/src/types.ts +56 -0
- package/src/utils/001-placeholders.ts +188 -10
- package/src/version.ts +1 -1
- package/dist/chunk-ZQABU7MR.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
|
|
3
3
|
type CallType = 'remote_action' | 'remote_query' | 'remote_entity_read' | 'remote_entity_mutation' | 'remote_entity_delete' | 'remote_entity_media' | 'remote_entity_candidate' | 'local_db_query' | 'external_http' | 'async_emit' | 'async_subscribe' | 'local_service_call' | 'unknown';
|
|
4
|
+
type EdgeType = 'REPO_HAS_SERVICE' | 'SERVICE_HAS_OPERATION' | 'OPERATION_IMPLEMENTED_BY_HANDLER' | 'HANDLER_REGISTERED_BY_SERVER' | 'HANDLER_CALLS_LOCAL_FUNCTION' | 'HANDLER_USES_SERVICE_ALIAS' | 'HANDLER_CALLS_REMOTE_OPERATION' | 'REMOTE_CALL_RESOLVES_TO_OPERATION' | 'LOCAL_CALL_RESOLVES_TO_OPERATION' | 'HANDLER_RUNS_DB_QUERY' | 'HANDLER_RUNS_REMOTE_QUERY' | 'HANDLER_ACCESSES_REMOTE_ENTITY' | 'HANDLER_CALLS_EXTERNAL_HTTP' | 'HANDLER_CALLS_TRANSPORT_METHOD' | 'HANDLER_EMITS_EVENT' | 'EVENT_CONSUMED_BY_HANDLER' | 'EVENT_SUBSCRIPTION_HANDLED_BY' | 'REPO_IMPORTS_HELPER_PACKAGE' | 'HELPER_PACKAGE_PROVIDES_HANDLER' | 'DYNAMIC_EDGE_CANDIDATE' | 'UNRESOLVED_EDGE';
|
|
4
5
|
interface DiscoveredRepository {
|
|
5
6
|
name: string;
|
|
6
7
|
absolutePath: string;
|
|
@@ -109,8 +110,34 @@ interface ServiceBindingFact {
|
|
|
109
110
|
placeholders: string[];
|
|
110
111
|
sourceFile: string;
|
|
111
112
|
sourceLine: number;
|
|
113
|
+
bindingSiteStartOffset?: number;
|
|
114
|
+
bindingSiteEndOffset?: number;
|
|
115
|
+
sourceSymbolQualifiedName?: string;
|
|
116
|
+
ownerResolution?: ServiceBindingOwnerResolution;
|
|
112
117
|
helperChain?: Array<Record<string, unknown>>;
|
|
113
118
|
}
|
|
119
|
+
type ServiceBindingOwnerResolution = 'owned_exact' | 'ownerless_file_scope' | 'legacy_unknown';
|
|
120
|
+
type ServiceBindingReferenceStatus = 'resolved_exact' | 'ambiguous' | 'unresolved' | 'not_applicable';
|
|
121
|
+
type ServiceBindingReferenceReason = 'binding_not_found' | 'binding_declared_after_call' | 'binding_scope_ambiguous' | 'scope_chain_limit_exceeded' | 'unsupported_reaching_assignment' | 'unsupported_var_binding' | 'binding_flow_unsupported';
|
|
122
|
+
interface LexicalScopeFact {
|
|
123
|
+
kind: 'source_file' | 'module_block' | 'function' | 'class' | 'loop' | 'case_block' | 'block' | 'catch';
|
|
124
|
+
startOffset: number;
|
|
125
|
+
endOffset: number;
|
|
126
|
+
}
|
|
127
|
+
interface ServiceBindingReference {
|
|
128
|
+
status: ServiceBindingReferenceStatus;
|
|
129
|
+
variableName?: string;
|
|
130
|
+
bindingSourceFile?: string;
|
|
131
|
+
bindingSiteStartOffset?: number;
|
|
132
|
+
bindingSiteEndOffset?: number;
|
|
133
|
+
resolutionStrategy?: 'lexical_declaration' | 'lexical_alias_declaration' | 'deterministic_reaching_assignment';
|
|
134
|
+
lexicalScopeChain?: LexicalScopeFact[];
|
|
135
|
+
bindingScopeIndex?: number;
|
|
136
|
+
scopeChainTotal: number;
|
|
137
|
+
scopeChainShown: number;
|
|
138
|
+
scopeChainOmitted: number;
|
|
139
|
+
reason?: ServiceBindingReferenceReason;
|
|
140
|
+
}
|
|
114
141
|
interface OutboundCallFact {
|
|
115
142
|
callType: CallType;
|
|
116
143
|
sourceSymbolQualifiedName?: string;
|
|
@@ -127,6 +154,7 @@ interface OutboundCallFact {
|
|
|
127
154
|
sourceLine: number;
|
|
128
155
|
callSiteStartOffset?: number;
|
|
129
156
|
callSiteEndOffset?: number;
|
|
157
|
+
serviceBindingReference?: ServiceBindingReference;
|
|
130
158
|
confidence: number;
|
|
131
159
|
unresolvedReason?: string;
|
|
132
160
|
evidence?: Record<string, unknown>;
|
|
@@ -137,6 +165,33 @@ interface OutboundCallFact {
|
|
|
137
165
|
dynamic: boolean;
|
|
138
166
|
};
|
|
139
167
|
}
|
|
168
|
+
interface ExecutableSymbolFact {
|
|
169
|
+
kind: string;
|
|
170
|
+
localName: string;
|
|
171
|
+
exportedName?: string;
|
|
172
|
+
qualifiedName: string;
|
|
173
|
+
sourceFile: string;
|
|
174
|
+
startLine: number;
|
|
175
|
+
endLine: number;
|
|
176
|
+
startOffset: number;
|
|
177
|
+
endOffset: number;
|
|
178
|
+
exported: boolean;
|
|
179
|
+
importExportEvidence?: Record<string, unknown>;
|
|
180
|
+
}
|
|
181
|
+
type SymbolCallRole = 'ordinary_call' | 'event_subscribe_handler' | 'legacy_unknown';
|
|
182
|
+
interface SymbolCallFact {
|
|
183
|
+
callerQualifiedName: string;
|
|
184
|
+
calleeExpression: string;
|
|
185
|
+
calleeLocalName?: string;
|
|
186
|
+
receiverLocalName?: string;
|
|
187
|
+
importSource?: string;
|
|
188
|
+
sourceFile: string;
|
|
189
|
+
sourceLine: number;
|
|
190
|
+
callSiteStartOffset?: number;
|
|
191
|
+
callSiteEndOffset?: number;
|
|
192
|
+
callRole: Exclude<SymbolCallRole, 'legacy_unknown'>;
|
|
193
|
+
evidence: Record<string, unknown>;
|
|
194
|
+
}
|
|
140
195
|
interface GeneratedConstantFact {
|
|
141
196
|
name: string;
|
|
142
197
|
value: string;
|
|
@@ -215,7 +270,11 @@ declare function parseHandlerRegistrations(repoPath: string, filePath: string, c
|
|
|
215
270
|
|
|
216
271
|
declare function parseServiceBindings(repoPath: string, filePath: string, context?: RepositorySourceContext): Promise<ServiceBindingFact[]>;
|
|
217
272
|
|
|
218
|
-
|
|
273
|
+
interface ClassifiedOutboundCall {
|
|
274
|
+
fact: OutboundCallFact;
|
|
275
|
+
node: ts.CallExpression;
|
|
276
|
+
}
|
|
277
|
+
declare function parseOutboundCalls(repoPath: string, filePath: string, context?: RepositorySourceContext, classified?: readonly ClassifiedOutboundCall[], preparedBindings?: readonly ServiceBindingFact[]): Promise<OutboundCallFact[]>;
|
|
219
278
|
|
|
220
279
|
declare function parseGeneratedConstants(repoPath: string, filePath: string): Promise<GeneratedConstantFact[]>;
|
|
221
280
|
|
|
@@ -465,4 +524,4 @@ declare function parseImplementationHint(value: string): ImplementationHint;
|
|
|
465
524
|
declare function redactText(text: string): string;
|
|
466
525
|
declare function redactValue(value: unknown): unknown;
|
|
467
526
|
|
|
468
|
-
export { type CompactDecisionV1, type CompactDiagnosticDetailsV1, type CompactDiagnosticRowV1, type CompactEdgeDetailsV1, type CompactEdgeRowV1, type CompactGraphV1, type CompactHintV1, type CompactNodeRowV1, type CompactQueryV1, type CompactReferenceGroupV1, type CompactReferencesV1, type CompactSourceContext, type CompactStartV1, type CompactStatus, type CompactStatusCountsV1, type CompactTraceExecution, type DynamicMode, type ImplementationHint, type RuntimeSubstitution, type TraceOptions, applyVariables, compactTrace, discoverRepositories, extractPlaceholders, linkWorkspace, parseCdsFile, parseDecorators, parseGeneratedConstants, parseHandlerRegistrations, parseImplementationHint, parseOutboundCalls, parsePackageJson, parseServiceBindings, redactText, redactValue, substituteVariables, trace, traceAndCompact };
|
|
527
|
+
export { type CallType, type CompactDecisionV1, type CompactDiagnosticDetailsV1, type CompactDiagnosticRowV1, type CompactEdgeDetailsV1, type CompactEdgeRowV1, type CompactGraphV1, type CompactHintV1, type CompactNodeRowV1, type CompactQueryV1, type CompactReferenceGroupV1, type CompactReferencesV1, type CompactSourceContext, type CompactStartV1, type CompactStatus, type CompactStatusCountsV1, type CompactTraceExecution, type Db, type DynamicMode, type EdgeType, type ExecutableSymbolFact, type ImplementationHint, type OutboundCallFact, type RuntimeSubstitution, type SymbolCallFact, type SymbolCallRole, type TraceEdge, type TraceOptions, type TraceResult, type TraceStart, applyVariables, compactTrace, discoverRepositories, extractPlaceholders, linkWorkspace, parseCdsFile, parseDecorators, parseGeneratedConstants, parseHandlerRegistrations, parseImplementationHint, parseOutboundCalls, parsePackageJson, parseServiceBindings, redactText, redactValue, substituteVariables, trace, traceAndCompact };
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Db } from '../db/connection.js';
|
|
2
|
+
|
|
3
|
+
type Diagnostic = Record<string, unknown>;
|
|
4
|
+
|
|
5
|
+
function pendingPredicate(alias: string): string {
|
|
6
|
+
return `${alias}.status='unresolved'
|
|
7
|
+
AND ${alias}.callee_symbol_id IS NULL
|
|
8
|
+
AND ${alias}.unresolved_reason='package_resolution_pending'
|
|
9
|
+
AND json_extract(${alias}.evidence_json,'$.relation')='package_import'
|
|
10
|
+
AND json_extract(${alias}.evidence_json,
|
|
11
|
+
'$.importBinding.moduleKind')='package'
|
|
12
|
+
AND json_extract(${alias}.evidence_json,
|
|
13
|
+
'$.candidateStrategy')='package_import_pending'
|
|
14
|
+
AND json_extract(${alias}.evidence_json,'$.candidateCount')=0
|
|
15
|
+
AND json_extract(${alias}.evidence_json,'$.eligibleCandidateCount')=0
|
|
16
|
+
AND json_extract(${alias}.evidence_json,'$.selectedCandidateCount')=0
|
|
17
|
+
AND json_extract(${alias}.evidence_json,'$.candidateSetComplete')=0`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function count(db: Db, sql: string): number {
|
|
21
|
+
return Number(db.prepare(sql).get()?.count ?? 0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function packagePendingDiagnostics(db: Db): Diagnostic[] {
|
|
25
|
+
const pending = count(db, `SELECT COUNT(*) count FROM symbol_calls sc
|
|
26
|
+
WHERE ${pendingPredicate('sc')}`);
|
|
27
|
+
if (pending === 0) return [];
|
|
28
|
+
const stale = count(db, `SELECT COUNT(*) count FROM repositories
|
|
29
|
+
WHERE graph_stale_reason IS NOT NULL`);
|
|
30
|
+
return [{
|
|
31
|
+
severity: 'warning',
|
|
32
|
+
code: 'package_import_resolution_pending',
|
|
33
|
+
message: 'Package-import facts await workspace linking; terminal package-resolution quality is deferred.',
|
|
34
|
+
packageResolutionState: 'pre_link_pending',
|
|
35
|
+
pendingPackageImportCount: pending,
|
|
36
|
+
graphState: 'stale',
|
|
37
|
+
staleRepositoryCount: stale,
|
|
38
|
+
requiredAction: 'relink',
|
|
39
|
+
remediation: 'service-flow link --workspace /workspace --force',
|
|
40
|
+
}];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function symbolCallQuality(db: Db): Diagnostic {
|
|
44
|
+
const terminal = `NOT (${pendingPredicate('sc')})`;
|
|
45
|
+
const row = db.prepare(`SELECT COUNT(*) total,
|
|
46
|
+
SUM(CASE WHEN sc.status='resolved' THEN 1 ELSE 0 END) resolved,
|
|
47
|
+
SUM(CASE WHEN sc.status='unresolved' THEN 1 ELSE 0 END) unresolved
|
|
48
|
+
FROM symbol_calls sc WHERE ${terminal}`).get();
|
|
49
|
+
const top = db.prepare(`SELECT sc.callee_expression calleeExpression,
|
|
50
|
+
COUNT(*) count FROM symbol_calls sc
|
|
51
|
+
WHERE sc.status='unresolved' AND ${terminal}
|
|
52
|
+
GROUP BY sc.callee_expression
|
|
53
|
+
ORDER BY count DESC,sc.callee_expression COLLATE BINARY LIMIT 5`).all();
|
|
54
|
+
const total = Number(row?.total ?? 0);
|
|
55
|
+
const unresolved = Number(row?.unresolved ?? 0);
|
|
56
|
+
const ratio = total === 0 ? 0 : Number((unresolved / total).toFixed(4));
|
|
57
|
+
return {
|
|
58
|
+
severity: ratio > 0.05 ? 'warning' : 'info',
|
|
59
|
+
code: 'strict_symbol_call_quality',
|
|
60
|
+
message: 'Terminal symbol-call quality aggregate',
|
|
61
|
+
total,
|
|
62
|
+
resolved: Number(row?.resolved ?? 0),
|
|
63
|
+
unresolved,
|
|
64
|
+
unresolvedRatio: ratio,
|
|
65
|
+
unresolvedRatioThreshold: 0.05,
|
|
66
|
+
topUnresolvedCallees: top,
|
|
67
|
+
};
|
|
68
|
+
}
|
package/src/cli/doctor.ts
CHANGED
|
@@ -7,6 +7,10 @@ import {
|
|
|
7
7
|
analyzerVersionDiagnostics,
|
|
8
8
|
schemaDriftDiagnostics,
|
|
9
9
|
} from './002-doctor-lifecycle.js';
|
|
10
|
+
import {
|
|
11
|
+
packagePendingDiagnostics,
|
|
12
|
+
symbolCallQuality,
|
|
13
|
+
} from './003-doctor-package-resolution.js';
|
|
10
14
|
export { linkUpgradeWarnings } from './002-doctor-lifecycle.js';
|
|
11
15
|
|
|
12
16
|
type Diagnostic = Record<string, unknown>;
|
|
@@ -17,13 +21,23 @@ interface DoctorOptions {
|
|
|
17
21
|
|
|
18
22
|
export function doctorDiagnostics(db: Db, strict: boolean, options: DoctorOptions = {}): Diagnostic[] {
|
|
19
23
|
const lifecycle = factLifecycleDiagnostic(db, options.workspaceId);
|
|
20
|
-
if (lifecycle
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
if (lifecycle) return boundDoctorDiagnostics([lifecycle]);
|
|
25
|
+
const globalLifecycle = options.workspaceId === undefined
|
|
26
|
+
? undefined : factLifecycleDiagnostic(db);
|
|
27
|
+
if (globalLifecycle) return boundDoctorDiagnostics([
|
|
28
|
+
...schemaDriftDiagnostics(db, strict, options.workspaceId),
|
|
29
|
+
...analyzerVersionDiagnostics(db, strict, options.workspaceId),
|
|
30
|
+
{
|
|
31
|
+
severity: 'warning',
|
|
32
|
+
code: 'workspace_detail_checks_deferred',
|
|
33
|
+
message: 'Selected-workspace lifecycle is valid, but JSON-dependent global detail checks were deferred because another workspace requires reindexing.',
|
|
34
|
+
remediation: 'Run doctor for the affected workspace after force index and link.',
|
|
35
|
+
},
|
|
36
|
+
]);
|
|
23
37
|
const diagnostics = db.prepare('SELECT severity,code,message,source_file sourceFile,source_line sourceLine FROM diagnostics ORDER BY id').all() as Diagnostic[];
|
|
24
38
|
return boundDoctorDiagnostics([
|
|
25
|
-
...(lifecycle ? [lifecycle] : []),
|
|
26
39
|
...diagnostics,
|
|
40
|
+
...packagePendingDiagnostics(db),
|
|
27
41
|
...healthDiagnostics(db, strict),
|
|
28
42
|
...remoteTargetWithoutImplementationDiagnostics(db, strict, Boolean(options.detail)),
|
|
29
43
|
...localServiceDiagnostics(db, strict),
|
|
@@ -170,15 +184,6 @@ function jsonEvidenceQuality(db: Db): Diagnostic[] {
|
|
|
170
184
|
];
|
|
171
185
|
}
|
|
172
186
|
|
|
173
|
-
function symbolCallQuality(db: Db): Diagnostic {
|
|
174
|
-
const row = db.prepare("SELECT COUNT(*) total, SUM(CASE WHEN status='resolved' THEN 1 ELSE 0 END) resolved, SUM(CASE WHEN status='unresolved' THEN 1 ELSE 0 END) unresolved FROM symbol_calls").get() as Record<string, unknown>;
|
|
175
|
-
const top = db.prepare("SELECT callee_expression calleeExpression,COUNT(*) count FROM symbol_calls WHERE status='unresolved' GROUP BY callee_expression ORDER BY count DESC,callee_expression LIMIT 5").all() as Diagnostic[];
|
|
176
|
-
const total = Number(row.total ?? 0);
|
|
177
|
-
const unresolved = Number(row.unresolved ?? 0);
|
|
178
|
-
const ratio = total === 0 ? 0 : Number((unresolved / total).toFixed(4));
|
|
179
|
-
return { severity: ratio > 0.05 ? 'warning' : 'info', code: 'strict_symbol_call_quality', message: 'Symbol-call quality aggregate', total, resolved: Number(row.resolved ?? 0), unresolved, unresolvedRatio: ratio, unresolvedRatioThreshold: 0.05, topUnresolvedCallees: top };
|
|
180
|
-
}
|
|
181
|
-
|
|
182
187
|
function dbQueryQuality(db: Db): Diagnostic {
|
|
183
188
|
const row = db.prepare("SELECT COUNT(*) total, SUM(CASE WHEN query_entity IS NOT NULL THEN 1 ELSE 0 END) known, SUM(CASE WHEN query_entity IS NULL THEN 1 ELSE 0 END) unknown FROM outbound_calls WHERE call_type='local_db_query'").get() as Record<string, unknown>;
|
|
184
189
|
const total = Number(row.total ?? 0);
|
|
@@ -418,8 +423,13 @@ function serviceBindingQuality(db: Db, detail: boolean): Diagnostic {
|
|
|
418
423
|
function bindingCategory(row: Diagnostic): string {
|
|
419
424
|
const evidence = parseObject(row.evidenceJson);
|
|
420
425
|
const resolution = parseObject(evidence.serviceBindingResolution);
|
|
426
|
+
const reference = parseObject(evidence.serviceBindingReference);
|
|
421
427
|
if (resolution.status === 'rejected_future_binding') return 'direct_binding_missing';
|
|
422
|
-
if (
|
|
428
|
+
if (reference.reason === 'binding_declared_after_call')
|
|
429
|
+
return 'direct_binding_missing';
|
|
430
|
+
if (resolution.status === 'ambiguous' || reference.status === 'ambiguous'
|
|
431
|
+
|| reference.reason === 'unsupported_reaching_assignment')
|
|
432
|
+
return 'ambiguous_binding_candidates';
|
|
423
433
|
const receiver = evidence.receiver;
|
|
424
434
|
const symbolEvidence = parseObject(row.symbolEvidenceJson);
|
|
425
435
|
if (symbolHasReceiverParameter(symbolEvidence, receiver))
|
|
@@ -448,6 +458,7 @@ function bindingExample(row: Diagnostic): Diagnostic {
|
|
|
448
458
|
receiver: evidence.receiver,
|
|
449
459
|
unresolvedReason: row.unresolvedReason,
|
|
450
460
|
bindingResolution: evidence.serviceBindingResolution,
|
|
461
|
+
bindingReference: evidence.serviceBindingReference,
|
|
451
462
|
};
|
|
452
463
|
}
|
|
453
464
|
|