@shapeshift-labs/frontier-lang-compiler 0.2.150 → 0.2.151
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/README.md +315 -9
- package/bench/real-repo-corpus-checkout-identity.mjs +134 -0
- package/bench/real-repo-corpus-checkout-proof.mjs +263 -0
- package/bench/real-repo-corpus-command-execution.mjs +314 -0
- package/bench/real-repo-corpus-evidence.mjs +165 -0
- package/bench/real-repo-corpus-suite.mjs +273 -0
- package/bench/smoke.mjs +109 -7
- package/dist/declarations/import-adapter-core.d.ts +4 -3
- package/dist/declarations/import-adapter-options-native.d.ts +21 -0
- package/dist/declarations/js-ts-project-merge-admission-routes.d.ts +35 -0
- package/dist/declarations/js-ts-project-merge-commonjs-interop.d.ts +29 -0
- package/dist/declarations/js-ts-project-merge-confidence.d.ts +64 -0
- package/dist/declarations/js-ts-project-merge-declaration-emit-parity.d.ts +37 -0
- package/dist/declarations/js-ts-project-merge-declarations.d.ts +65 -0
- package/dist/declarations/js-ts-project-merge-diagnostics.d.ts +97 -0
- package/dist/declarations/js-ts-project-merge-global-augmentation.d.ts +30 -0
- package/dist/declarations/js-ts-project-merge-jsx-render-branch.d.ts +48 -0
- package/dist/declarations/js-ts-project-merge-proof-levels.d.ts +109 -0
- package/dist/declarations/js-ts-project-merge-quality-gates.d.ts +38 -0
- package/dist/declarations/js-ts-project-merge-semantic-equivalence-proof.d.ts +45 -0
- package/dist/declarations/js-ts-project-merge-tsconfig.d.ts +43 -0
- package/dist/declarations/js-ts-safe-merge.d.ts +47 -0
- package/dist/declarations/js-ts-safe-project-merge.d.ts +120 -38
- package/dist/declarations/native-project-compiler-assignability-oracle.d.ts +41 -0
- package/dist/declarations/native-project-compiler-callable-signatures.d.ts +31 -0
- package/dist/declarations/native-project-compiler-class-member-runtime-proof.d.ts +87 -0
- package/dist/declarations/native-project-compiler-composite-types.d.ts +23 -0
- package/dist/declarations/native-project-compiler-enum-proof.d.ts +58 -0
- package/dist/declarations/native-project-compiler-index-signature.d.ts +7 -0
- package/dist/declarations/native-project-compiler-public-api-source-binding.d.ts +8 -0
- package/dist/declarations/native-project-compiler-scope.d.ts +37 -0
- package/dist/declarations/native-project-compiler-type-reference-targets.d.ts +38 -0
- package/dist/declarations/native-project-css-modules.d.ts +90 -0
- package/dist/declarations/native-project-decorator-metadata.d.ts +126 -0
- package/dist/declarations/native-project-jsx-graph.d.ts +313 -0
- package/dist/declarations/native-project-module-declarations.d.ts +52 -0
- package/dist/declarations/native-project-module-resolution.d.ts +76 -1
- package/dist/declarations/native-project-runtime-effect-target.d.ts +29 -0
- package/dist/declarations/native-project-runtime-executable-effect-evidence.d.ts +107 -0
- package/dist/declarations/native-project-runtime-mutation-target.d.ts +33 -0
- package/dist/declarations/native-project-runtime-promise-chain.d.ts +30 -0
- package/dist/declarations/native-project-runtime-promise-combinator.d.ts +22 -0
- package/dist/declarations/native-project-runtime-reachability.d.ts +30 -0
- package/dist/declarations/native-project-runtime-resource-management.d.ts +27 -0
- package/dist/declarations/native-project-runtime-yield-delegation.d.ts +10 -0
- package/dist/declarations/native-project-scope-template-reference.d.ts +13 -0
- package/dist/declarations/native-project-source-evidence.d.ts +8 -0
- package/dist/declarations/native-project.d.ts +40 -39
- package/dist/declarations/semantic-edit-script.d.ts +10 -8
- package/dist/declarations/semantic-graph-layers.d.ts +79 -0
- package/dist/declarations/semantic-sidecar.d.ts +3 -2
- package/dist/declarations/semantic-structural-diff.d.ts +94 -0
- package/dist/declarations/source-preservation.d.ts +32 -1
- package/dist/declarations/target-adapters.d.ts +22 -2
- package/dist/index.d.ts +31 -0
- package/dist/index.js +5 -0
- package/dist/internal/index-impl/compileNativeSource.js +53 -5
- package/dist/internal/index-impl/createLightweightNativeImport.js +58 -4
- package/dist/internal/index-impl/createNativeImportFromSyntaxAst.js +17 -1
- package/dist/internal/index-impl/createNativeImportFromTypeScriptAst.js +28 -4
- package/dist/internal/index-impl/createNativeProjectImportResult.js +31 -27
- package/dist/internal/index-impl/createNativeProjectModuleResolutionFromPackageManifests.js +145 -0
- package/dist/internal/index-impl/createNativeSourcePreservation.js +34 -7
- package/dist/internal/index-impl/createSemanticImportSidecar.js +27 -1
- package/dist/internal/index-impl/createTypeScriptCompilerNativeImporterAdapter.js +16 -5
- package/dist/internal/index-impl/dynamicImportExpressionMetadata.js +80 -0
- package/dist/internal/index-impl/importMetaUrlDependencyMetadata.js +176 -0
- package/dist/internal/index-impl/importNativeSource.js +2 -3
- package/dist/internal/index-impl/moduleImportAttributeMetadata.js +232 -0
- package/dist/internal/index-impl/projectSemanticEditScriptToSource.js +8 -1
- package/dist/internal/index-impl/projectSymbolGraphClassStaticBlocks.js +148 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerAdvancedTypeMetadata.js +45 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerCallableSignatureEquivalence.js +107 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerClassPrivateAccessorRuntimeProof.js +280 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerClassShapeEquivalence.js +103 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerConditionalTypeEquivalence.js +242 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerDecoratorRuntimeProof.js +197 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerEnumEquivalence.js +188 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerFacts.js +244 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerIndexSignatureEquivalence.js +58 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerMetadata.js +168 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerTypeEquivalence.js +199 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerTypeEquivalenceProof.js +204 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerTypeReferenceTargetEquivalence.js +99 -0
- package/dist/internal/index-impl/projectSymbolGraphCssModuleRecords.js +264 -0
- package/dist/internal/index-impl/projectSymbolGraphCssModuleScanners.js +242 -0
- package/dist/internal/index-impl/projectSymbolGraphCssModuleUtils.js +152 -0
- package/dist/internal/index-impl/projectSymbolGraphCssModules.js +82 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxComponentImports.js +170 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxComponentProviderLookup.js +167 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxComponentWrappers.js +150 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxContextTargets.js +71 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxContextValues.js +212 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxEventHandlers.js +172 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxHookEffects.js +124 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxHooks.js +281 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxMemberComponents.js +139 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxPropFlows.js +320 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxPropValues.js +145 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxProviderFlows.js +133 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxRecords.js +315 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxRenderCollections.js +155 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturns.js +291 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxRenderRisk.js +279 -0
- package/dist/internal/index-impl/projectSymbolGraphModuleDeclarationShapes.js +138 -0
- package/dist/internal/index-impl/projectSymbolGraphModuleResolution.js +89 -87
- package/dist/internal/index-impl/projectSymbolGraphPackageConditions.js +314 -0
- package/dist/internal/index-impl/projectSymbolGraphReExportImportTargets.js +43 -0
- package/dist/internal/index-impl/projectSymbolGraphReExports.js +55 -1
- package/dist/internal/index-impl/projectSymbolGraphRuntimeRegions.js +108 -0
- package/dist/internal/index-impl/projectSymbolGraphScopeUseDefAliases.js +307 -0
- package/dist/internal/index-impl/projectSymbolGraphScopeUseDefLexical.js +320 -0
- package/dist/internal/index-impl/projectSymbolGraphScopeUseDefOwners.js +50 -0
- package/dist/internal/index-impl/projectSymbolGraphScopeUseDefRecordBuilders.js +112 -0
- package/dist/internal/index-impl/projectSymbolGraphScopeUseDefRecords.js +238 -0
- package/dist/internal/index-impl/projectSymbolGraphScopeUseDefStructural.js +104 -0
- package/dist/internal/index-impl/projectSymbolGraphScopeUseDefStructuralNormalize.js +242 -0
- package/dist/internal/index-impl/projectSymbolGraphScopeUseDefUseHashes.js +107 -0
- package/dist/internal/index-impl/projectSymbolGraphSourceMapGeneratedBoundary.js +111 -0
- package/dist/internal/index-impl/projectSymbolGraphSourceRecords.js +268 -0
- package/dist/internal/index-impl/projectSymbolGraphSourceRecordsOwnership.js +309 -0
- package/dist/internal/index-impl/replaySemanticEditProjection.js +53 -39
- package/dist/internal/index-impl/runtimeOrderEvidenceBinding.js +151 -0
- package/dist/internal/index-impl/runtimeOrderProofSurfaces.js +253 -0
- package/dist/internal/index-impl/semanticEditCallsiteArgumentMerge.js +319 -0
- package/dist/internal/index-impl/semanticEditExplicitSourceReplacement.js +7 -2
- package/dist/internal/index-impl/semanticEditProjectionRecord.js +8 -0
- package/dist/internal/index-impl/semanticEditReplayDiagnostics.js +7 -2
- package/dist/internal/index-impl/semanticEditReplayOutputBinding.js +61 -0
- package/dist/internal/index-impl/semanticEditReplayRerunRoute.js +27 -0
- package/dist/internal/index-impl/semanticEditReplaySourceReplacement.js +6 -1
- package/dist/internal/index-impl/semanticEditRuntimeOrderReasons.js +320 -0
- package/dist/internal/index-impl/semanticEditScriptClassification.js +90 -5
- package/dist/internal/index-impl/semanticEditScripts.js +42 -5
- package/dist/internal/index-impl/semanticEditTypeSyntaxReasons.js +134 -0
- package/dist/internal/index-impl/semanticIndexFromNativeDeclarations.js +11 -5
- package/dist/internal/index-impl/semanticStructuralDiffRecords.js +150 -0
- package/dist/internal/index-impl/sourceMapGeneratedBoundaryGate.js +185 -0
- package/dist/internal/index-impl/staticMemberLiteral.js +31 -0
- package/dist/internal/index-impl/staticOptionalMemberReference.js +22 -0
- package/dist/internal/index-impl/syntaxAstSourcePreservation.js +273 -0
- package/dist/internal/index-impl/syntaxCommonJsModuleDeclarationEntries.js +297 -0
- package/dist/internal/index-impl/syntaxModuleDeclarationEntries.js +56 -132
- package/dist/internal/index-impl/syntaxModuleEntryRecords.js +160 -0
- package/dist/internal/index-impl/typeScriptCompilerAdvancedTypeShapes.js +160 -0
- package/dist/internal/index-impl/typeScriptCompilerAssignabilityOracle.js +97 -0
- package/dist/internal/index-impl/typeScriptCompilerClassApi.js +238 -0
- package/dist/internal/index-impl/typeScriptCompilerDecoratorMetadata.js +290 -0
- package/dist/internal/index-impl/typeScriptCompilerEnumShape.js +279 -0
- package/dist/internal/index-impl/typeScriptCompilerFacts.js +294 -0
- package/dist/internal/index-impl/typeScriptCompilerInferenceSyntax.js +170 -0
- package/dist/internal/index-impl/typeScriptCompilerReferenceGraph.js +186 -0
- package/dist/internal/index-impl/typeScriptCompilerSymbolIdentity.js +294 -0
- package/dist/internal/index-impl/typeScriptCompilerTypeReferenceTargets.js +142 -0
- package/dist/internal/index-impl/typeScriptDeclaration.js +10 -38
- package/dist/internal/index-impl/typeScriptModuleDeclarationEntries.js +52 -15
- package/dist/internal/index-impl/typeScriptSourceFilePreservation.js +296 -0
- package/dist/js-ts-safe-member-class-invariants.js +247 -0
- package/dist/js-ts-safe-member-merge-result.js +23 -3
- package/dist/js-ts-safe-member-merge.js +28 -4
- package/dist/js-ts-safe-merge-binding-patterns.js +170 -0
- package/dist/js-ts-safe-merge-jsx-attribute-fallback.js +151 -157
- package/dist/js-ts-safe-merge-jsx-attribute-parser.js +277 -0
- package/dist/js-ts-safe-merge-jsx-child-expression-fallback.js +161 -0
- package/dist/js-ts-safe-merge-jsx-child-expression-merge.js +319 -0
- package/dist/js-ts-safe-merge-jsx-child-expression-parser.js +300 -0
- package/dist/js-ts-safe-merge-parse-declarations.js +46 -2
- package/dist/js-ts-safe-merge-parse-statements.js +8 -0
- package/dist/js-ts-safe-merge-semantic-edit-fallback.js +13 -5
- package/dist/js-ts-safe-merge-source-shape-fallbacks.js +3 -1
- package/dist/js-ts-safe-merge-top-level-rename-fallback.js +31 -5
- package/dist/js-ts-safe-merge-top-level-rename-result.js +7 -2
- package/dist/js-ts-safe-merge-variable-declarator-fallback.js +124 -6
- package/dist/js-ts-safe-merge-variable-declarator-parser.js +34 -4
- package/dist/js-ts-safe-merge.js +136 -0
- package/dist/js-ts-safe-project-merge-admission-routes.js +216 -0
- package/dist/js-ts-safe-project-merge-admission.js +161 -0
- package/dist/js-ts-safe-project-merge-ambient.js +110 -0
- package/dist/js-ts-safe-project-merge-core.js +85 -0
- package/dist/js-ts-safe-project-merge-css-module-conflicts.js +60 -0
- package/dist/js-ts-safe-project-merge-declaration-emit-parity.js +186 -0
- package/dist/js-ts-safe-project-merge-declarations.js +227 -0
- package/dist/js-ts-safe-project-merge-diagnostics-metadata.js +42 -0
- package/dist/js-ts-safe-project-merge-diagnostics-ts.js +73 -0
- package/dist/js-ts-safe-project-merge-diagnostics.js +283 -0
- package/dist/js-ts-safe-project-merge-evidence-routing.js +38 -0
- package/dist/js-ts-safe-project-merge-files.js +70 -0
- package/dist/js-ts-safe-project-merge-global-augmentation-compatibility.js +99 -0
- package/dist/js-ts-safe-project-merge-graph-conflicts.js +90 -2
- package/dist/js-ts-safe-project-merge-graph-delta-commonjs-interop.js +108 -0
- package/dist/js-ts-safe-project-merge-graph-delta-compiler-conflicts.js +179 -0
- package/dist/js-ts-safe-project-merge-graph-delta-compiler-details.js +189 -0
- package/dist/js-ts-safe-project-merge-graph-delta-conflicts.js +51 -184
- package/dist/js-ts-safe-project-merge-graph-delta-identity-conflicts.js +202 -0
- package/dist/js-ts-safe-project-merge-graph-delta-inference-syntax.js +80 -0
- package/dist/js-ts-safe-project-merge-graph-delta-module-declarations.js +155 -0
- package/dist/js-ts-safe-project-merge-graph-limits.js +16 -1
- package/dist/js-ts-safe-project-merge-graph.js +37 -5
- package/dist/js-ts-safe-project-merge-import-removal.js +292 -0
- package/dist/js-ts-safe-project-merge-jsx-graph-conflict-details.js +235 -0
- package/dist/js-ts-safe-project-merge-jsx-graph-conflicts.js +173 -0
- package/dist/js-ts-safe-project-merge-jsx-prop-contracts.js +86 -0
- package/dist/js-ts-safe-project-merge-jsx-render-branch-proof.js +189 -0
- package/dist/js-ts-safe-project-merge-missing-evidence.js +310 -0
- package/dist/js-ts-safe-project-merge-move-rename.js +209 -0
- package/dist/js-ts-safe-project-merge-proof-conflicts.js +44 -0
- package/dist/js-ts-safe-project-merge-proof-levels.js +320 -0
- package/dist/js-ts-safe-project-merge-quality-gates.js +140 -0
- package/dist/js-ts-safe-project-merge-routing-calibration.js +125 -0
- package/dist/js-ts-safe-project-merge-runtime-region-conflicts.js +156 -0
- package/dist/js-ts-safe-project-merge-scope-use-def-conflicts.js +292 -0
- package/dist/js-ts-safe-project-merge-semantic-equivalence-proof.js +175 -0
- package/dist/js-ts-safe-project-merge-semantic-replay-proof.js +311 -0
- package/dist/js-ts-safe-project-merge-semantic-replay-routes.js +179 -0
- package/dist/js-ts-safe-project-merge-source-span-conflicts.js +310 -0
- package/dist/js-ts-safe-project-merge-source-span-roundtrip-proof.js +172 -0
- package/dist/js-ts-safe-project-merge-split-merge-admission.js +96 -0
- package/dist/js-ts-safe-project-merge-split-merge-records.js +320 -0
- package/dist/js-ts-safe-project-merge-split-merge-shapes.js +234 -0
- package/dist/js-ts-safe-project-merge-split-merge.js +218 -0
- package/dist/js-ts-safe-project-merge-summary.js +320 -0
- package/dist/js-ts-safe-project-merge-symbol-move-admission.js +63 -0
- package/dist/js-ts-safe-project-merge-symbol-move-default-admission.js +143 -0
- package/dist/js-ts-safe-project-merge-symbol-move-risks.js +213 -0
- package/dist/js-ts-safe-project-merge-symbol-move.js +316 -0
- package/dist/js-ts-safe-project-merge-symbol-rename-admission.js +59 -0
- package/dist/js-ts-safe-project-merge-symbol-rename-default-admission.js +111 -0
- package/dist/js-ts-safe-project-merge-symbol-rename.js +319 -0
- package/dist/js-ts-safe-project-merge-ts-options.js +205 -0
- package/dist/js-ts-safe-project-merge-ts-program.js +268 -0
- package/dist/js-ts-safe-project-merge-typed-property-rename-rebase-utils.js +69 -0
- package/dist/js-ts-safe-project-merge-typed-property-rename-rebase.js +317 -0
- package/dist/js-ts-safe-project-merge-unsupported-surfaces.js +319 -0
- package/dist/js-ts-safe-project-merge.js +170 -171
- package/dist/js-ts-semantic-scope-use-def-bindings.js +287 -0
- package/dist/js-ts-semantic-scope-use-def-scan.js +241 -0
- package/dist/js-ts-semantic-scope-use-def-utils.js +132 -0
- package/dist/js-ts-semantic-scope-use-def.js +217 -0
- package/dist/lightweight-dependency-effects.js +28 -4
- package/dist/lightweight-dependency-relations.js +13 -7
- package/dist/lightweight-dependency-top-level.js +63 -0
- package/dist/native-import-language-profiles.js +27 -1
- package/dist/native-js-ts-importers.js +9 -5
- package/dist/native-parser-ast-format-profiles.js +12 -0
- package/dist/native-parser-html-css-format-profiles.js +85 -0
- package/dist/native-region-scanner-core.js +5 -3
- package/dist/native-region-scanner-js-commonjs.js +155 -0
- package/dist/native-region-scanner-js-imports.js +51 -13
- package/dist/native-region-scanner-js-reexports.js +79 -0
- package/dist/native-region-scanner-js-ts-helpers.js +23 -0
- package/dist/native-source-ledger-helpers.js +1 -1
- package/dist/native-source-ledger.js +24 -10
- package/dist/native-source-maps-ecma426.js +316 -0
- package/dist/native-source-maps.js +36 -6
- package/dist/native-source-preservation-ownership.js +292 -0
- package/dist/native-source-preservation-scanner.js +63 -25
- package/dist/native-source-preservation-types.d.ts +3 -0
- package/dist/semantic-import-effect-occurrences.js +242 -0
- package/dist/semantic-import-effect-regions.js +95 -58
- package/dist/semantic-import-graph-layers.js +224 -0
- package/dist/semantic-import-runtime-conditional-evidence.js +135 -0
- package/dist/semantic-import-runtime-effect-target-evidence.js +145 -0
- package/dist/semantic-import-runtime-exit-evidence.js +32 -0
- package/dist/semantic-import-runtime-import-meta-evidence.js +33 -0
- package/dist/semantic-import-runtime-mutation-evidence.js +155 -0
- package/dist/semantic-import-runtime-order-evidence.js +318 -0
- package/dist/semantic-import-runtime-promise-chain-evidence.js +103 -0
- package/dist/semantic-import-runtime-promise-combinator-evidence.js +166 -0
- package/dist/semantic-import-runtime-reachability-evidence.js +269 -0
- package/dist/semantic-import-runtime-resource-management-evidence.js +293 -0
- package/dist/semantic-import-runtime-switch-evidence.js +304 -0
- package/dist/semantic-import-runtime-throw-evidence.js +44 -0
- package/dist/semantic-import-runtime-try-finally-evidence.js +172 -0
- package/dist/semantic-import-sidecar-entry.js +4 -0
- package/dist/semantic-import-source-preservation.js +6 -2
- package/package.json +1 -1
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { normalizeKind, uniqueStrings } from './js-ts-semantic-merge-parse.js';
|
|
2
|
+
|
|
3
|
+
export function classBodyInvariantReasons(region, side, body) {
|
|
4
|
+
const reasonCodes = [];
|
|
5
|
+
for (const segment of splitClassElementSegments(body)) {
|
|
6
|
+
const text = segment.text.trim();
|
|
7
|
+
if (!text) continue;
|
|
8
|
+
if (hasClassDecorator(text)) reasonCodes.push(regionReason(region, `decorator-member:${side}`));
|
|
9
|
+
if (hasStaticBlock(text)) reasonCodes.push(regionReason(region, `static-block-ordering:${side}`));
|
|
10
|
+
}
|
|
11
|
+
return uniqueStrings(reasonCodes);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function classPrivateScopeReasons(region, side, baseMembers, sideMembers, sideAddedKeys) {
|
|
15
|
+
const reasonCodes = [];
|
|
16
|
+
const basePrivateNames = privateDeclarationNames(baseMembers);
|
|
17
|
+
const sidePrivateNames = privateDeclarationNames(sideMembers);
|
|
18
|
+
for (const name of duplicatePrivateDeclarationNames(sideMembers)) {
|
|
19
|
+
reasonCodes.push(regionReason(region, `private-name-scope:${side}:${name}`));
|
|
20
|
+
}
|
|
21
|
+
for (const key of sideAddedKeys) {
|
|
22
|
+
const member = sideMembers.find((candidate) => candidate.key === key);
|
|
23
|
+
if (!member) continue;
|
|
24
|
+
const declaredName = privateNameFromKey(member.key);
|
|
25
|
+
if (declaredName && basePrivateNames.has(declaredName)) {
|
|
26
|
+
reasonCodes.push(regionReason(region, `private-name-scope:${side}:${declaredName}`));
|
|
27
|
+
}
|
|
28
|
+
for (const name of privateReferences(member)) {
|
|
29
|
+
if (!basePrivateNames.has(name) && !sidePrivateNames.has(name)) {
|
|
30
|
+
reasonCodes.push(regionReason(region, `private-name-scope:${side}:${name}`));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return uniqueStrings(reasonCodes);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function classPrivateAddedCollisionReasons(region, workerAddedKeys, headAddedKeys, workerByKey, headByKey) {
|
|
38
|
+
const workerNames = privateNamesForKeys(workerAddedKeys, workerByKey);
|
|
39
|
+
const headNames = privateNamesForKeys(headAddedKeys, headByKey);
|
|
40
|
+
return [...workerNames].filter((name) => headNames.has(name))
|
|
41
|
+
.map((name) => regionReason(region, `private-name-scope:worker-head:${name}`));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function isAccessorMember(member) {
|
|
45
|
+
return member?.memberKind === 'accessor';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function isPrivateMemberKey(key) {
|
|
49
|
+
return Boolean(privateNameFromKey(key));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function privateNameFromKey(key) {
|
|
53
|
+
const normalized = String(key ?? '').replace(/^static\./, '');
|
|
54
|
+
return normalized.startsWith('#') ? normalized : undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function regionReason(region, reason) {
|
|
58
|
+
return `${reason}:${normalizeKind(region.kind)}:${region.name}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function privateNamesForKeys(keys, byKey) {
|
|
62
|
+
const names = new Set();
|
|
63
|
+
for (const key of keys) {
|
|
64
|
+
const name = privateNameFromKey(byKey.get(key)?.key);
|
|
65
|
+
if (name) names.add(name);
|
|
66
|
+
}
|
|
67
|
+
return names;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function privateDeclarationNames(members) {
|
|
71
|
+
const names = new Set();
|
|
72
|
+
for (const member of members) {
|
|
73
|
+
const name = privateNameFromKey(member.key);
|
|
74
|
+
if (name) names.add(name);
|
|
75
|
+
}
|
|
76
|
+
return names;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function duplicatePrivateDeclarationNames(members) {
|
|
80
|
+
const namesByPrivateName = new Map();
|
|
81
|
+
for (const member of members) {
|
|
82
|
+
const name = privateNameFromKey(member.key);
|
|
83
|
+
if (!name) continue;
|
|
84
|
+
const keys = namesByPrivateName.get(name) ?? new Set();
|
|
85
|
+
keys.add(member.key);
|
|
86
|
+
namesByPrivateName.set(name, keys);
|
|
87
|
+
}
|
|
88
|
+
return [...namesByPrivateName]
|
|
89
|
+
.filter(([, keys]) => keys.size > 1)
|
|
90
|
+
.map(([name]) => name);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function privateReferences(member) {
|
|
94
|
+
const declarations = new Set();
|
|
95
|
+
const declaredName = privateNameFromKey(member?.key);
|
|
96
|
+
if (declaredName) declarations.add(declaredName);
|
|
97
|
+
return privateNameTokens(member?.text).filter((name) => !declarations.has(name));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function privateNameTokens(text) {
|
|
101
|
+
const names = [];
|
|
102
|
+
const source = String(text ?? '');
|
|
103
|
+
let quote;
|
|
104
|
+
let escaped = false;
|
|
105
|
+
let blockComment = false;
|
|
106
|
+
let lineComment = false;
|
|
107
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
108
|
+
const char = source[index];
|
|
109
|
+
const next = source[index + 1];
|
|
110
|
+
if (lineComment) {
|
|
111
|
+
if (char === '\n' || char === '\r') lineComment = false;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (blockComment) {
|
|
115
|
+
if (char === '*' && next === '/') {
|
|
116
|
+
blockComment = false;
|
|
117
|
+
index += 1;
|
|
118
|
+
}
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (quote) {
|
|
122
|
+
if (escaped) escaped = false;
|
|
123
|
+
else if (char === '\\') escaped = true;
|
|
124
|
+
else if (char === quote) quote = undefined;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (char === '/' && next === '/') {
|
|
128
|
+
lineComment = true;
|
|
129
|
+
index += 1;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (char === '/' && next === '*') {
|
|
133
|
+
blockComment = true;
|
|
134
|
+
index += 1;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (char === '\'' || char === '"' || char === '`') {
|
|
138
|
+
quote = char;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (char === '#' && /[A-Za-z_$]/.test(next ?? '')) {
|
|
142
|
+
let end = index + 2;
|
|
143
|
+
while (/[\w$]/.test(source[end] ?? '')) end += 1;
|
|
144
|
+
names.push(source.slice(index, end));
|
|
145
|
+
index = end - 1;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return uniqueStrings(names);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function hasClassDecorator(text) {
|
|
152
|
+
return String(text ?? '').trimStart().startsWith('@');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function hasStaticBlock(text) {
|
|
156
|
+
return /^static\s*\{/.test(String(text ?? '').trimStart());
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function splitClassElementSegments(body) {
|
|
160
|
+
const entries = [];
|
|
161
|
+
const text = String(body ?? '');
|
|
162
|
+
let start = 0;
|
|
163
|
+
let quote;
|
|
164
|
+
let escaped = false;
|
|
165
|
+
let blockComment = false;
|
|
166
|
+
let lineComment = false;
|
|
167
|
+
let depth = 0;
|
|
168
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
169
|
+
const char = text[index];
|
|
170
|
+
const next = text[index + 1];
|
|
171
|
+
if (lineComment) {
|
|
172
|
+
if (char === '\n' || char === '\r') lineComment = false;
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (blockComment) {
|
|
176
|
+
if (char === '*' && next === '/') {
|
|
177
|
+
blockComment = false;
|
|
178
|
+
index += 1;
|
|
179
|
+
}
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (quote) {
|
|
183
|
+
if (escaped) escaped = false;
|
|
184
|
+
else if (char === '\\') escaped = true;
|
|
185
|
+
else if (char === quote) quote = undefined;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (char === '/' && next === '/') {
|
|
189
|
+
lineComment = true;
|
|
190
|
+
index += 1;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (char === '/' && next === '*') {
|
|
194
|
+
blockComment = true;
|
|
195
|
+
index += 1;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (char === '\'' || char === '"' || char === '`') {
|
|
199
|
+
quote = char;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (char === '{' || char === '[' || char === '(') {
|
|
203
|
+
depth += 1;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (char === '}' || char === ']' || char === ')') {
|
|
207
|
+
depth -= 1;
|
|
208
|
+
if (depth === 0 && char === '}') {
|
|
209
|
+
const nextIndex = nextSignificantIndex(text, index + 1);
|
|
210
|
+
if (text[nextIndex] !== ';') {
|
|
211
|
+
entries.push({ text: text.slice(start, index + 1), start, end: index + 1 });
|
|
212
|
+
start = index + 1;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (char === ';' && depth === 0) {
|
|
218
|
+
entries.push({ text: text.slice(start, index + 1), start, end: index + 1 });
|
|
219
|
+
start = index + 1;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
entries.push({ text: text.slice(start), start, end: text.length });
|
|
223
|
+
return entries.filter((entry) => entry.text.trim());
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function nextSignificantIndex(text, offset) {
|
|
227
|
+
let index = offset;
|
|
228
|
+
while (index < text.length) {
|
|
229
|
+
if (/\s/.test(text[index])) {
|
|
230
|
+
index += 1;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (text[index] === '/' && text[index + 1] === '/') {
|
|
234
|
+
index += 2;
|
|
235
|
+
while (index < text.length && text[index] !== '\n' && text[index] !== '\r') index += 1;
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
if (text[index] === '/' && text[index + 1] === '*') {
|
|
239
|
+
index += 2;
|
|
240
|
+
while (index < text.length && !(text[index] === '*' && text[index + 1] === '/')) index += 1;
|
|
241
|
+
index += 2;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
return index;
|
|
247
|
+
}
|
|
@@ -91,6 +91,10 @@ function memberConflictForReason(reason, input, index) {
|
|
|
91
91
|
|
|
92
92
|
function blockedReasonCode(reason) {
|
|
93
93
|
if (reason.includes('computed-key')) return 'computed-key';
|
|
94
|
+
if (reason.includes('decorator-member')) return 'decorator-member';
|
|
95
|
+
if (reason.includes('static-block-ordering')) return 'static-block-ordering';
|
|
96
|
+
if (reason.includes('accessor-pairing')) return 'accessor-pairing';
|
|
97
|
+
if (reason.includes('private-name-scope')) return 'private-name-scope';
|
|
94
98
|
if (reason.includes('spread-like-member') || reason.includes('spread-member')) return 'spread-like-member';
|
|
95
99
|
if (reason.includes('overload-collision')) return 'overload-collision';
|
|
96
100
|
if (reason.includes('type-alias-conflict')) return 'type-alias-conflict';
|
|
@@ -109,6 +113,9 @@ function blockedReasonCode(reason) {
|
|
|
109
113
|
|
|
110
114
|
function conflictCodeForReason(reasonCode) {
|
|
111
115
|
if (reasonCode === 'computed-key') return JsTsSafeMergeConflictCodes.computedKey;
|
|
116
|
+
if (reasonCode === 'decorator-member') return JsTsSafeMergeConflictCodes.unsupportedDecorator;
|
|
117
|
+
if (reasonCode === 'static-block-ordering') return JsTsSafeMergeConflictCodes.topLevelOrderChanged;
|
|
118
|
+
if (reasonCode === 'accessor-pairing' || reasonCode === 'private-name-scope') return JsTsSafeMergeConflictCodes.duplicateName;
|
|
112
119
|
if (reasonCode === 'overload-collision') return JsTsSafeMergeConflictCodes.unsupportedOverload;
|
|
113
120
|
if (reasonCode === 'type-alias-conflict') return JsTsSafeMergeConflictCodes.typeAliasConflict;
|
|
114
121
|
if (reasonCode === 'duplicate-member-name') return JsTsSafeMergeConflictCodes.duplicateName;
|
|
@@ -122,11 +129,15 @@ function conflictCodeForReason(reasonCode) {
|
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
function gateIdForReason(reasonCode) {
|
|
125
|
-
if (reasonCode === 'duplicate-member-name' || reasonCode === 'overload-collision')
|
|
132
|
+
if (reasonCode === 'duplicate-member-name' || reasonCode === 'overload-collision' || reasonCode === 'accessor-pairing' || reasonCode === 'private-name-scope') {
|
|
133
|
+
return JsTsSafeMergeGateIds.uniqueNames;
|
|
134
|
+
}
|
|
126
135
|
if (reasonCode === 'changed-existing-member' || reasonCode === 'removed-existing-member' || reasonCode === 'non-policy-source-change') {
|
|
127
136
|
return JsTsSafeMergeGateIds.stableExistingDeclarations;
|
|
128
137
|
}
|
|
129
|
-
if (reasonCode === 'existing-member-order-changed' || reasonCode === 'order-sensitive-region-kind')
|
|
138
|
+
if (reasonCode === 'existing-member-order-changed' || reasonCode === 'order-sensitive-region-kind' || reasonCode === 'static-block-ordering') {
|
|
139
|
+
return JsTsSafeMergeGateIds.preserveBaseOrder;
|
|
140
|
+
}
|
|
130
141
|
return JsTsSafeMergeGateIds.parseLedger;
|
|
131
142
|
}
|
|
132
143
|
|
|
@@ -137,13 +148,22 @@ function reasonDetails(reason, reasonCode) {
|
|
|
137
148
|
if (['base', 'worker', 'head'].includes(parts[2])) details.side = parts[2];
|
|
138
149
|
const kind = parts.find((part) => ['interface', 'type', 'class', 'object'].includes(part));
|
|
139
150
|
if (kind) details.regionKind = kind;
|
|
140
|
-
if (reasonCode === 'duplicate-member-name'
|
|
151
|
+
if (reasonCode === 'duplicate-member-name'
|
|
152
|
+
|| reasonCode === 'overload-collision'
|
|
153
|
+
|| reasonCode === 'accessor-pairing'
|
|
154
|
+
|| reasonCode === 'private-name-scope') {
|
|
155
|
+
details.memberName = parts.at(-3) ?? parts.at(-1);
|
|
156
|
+
}
|
|
141
157
|
if (reasonCode === 'changed-existing-member' || reasonCode === 'removed-existing-member') details.memberName = parts.at(-3);
|
|
142
158
|
return details;
|
|
143
159
|
}
|
|
144
160
|
|
|
145
161
|
function memberConflictMessage(reasonCode, details) {
|
|
146
162
|
if (reasonCode === 'computed-key') return 'Computed member keys are not safe for automatic member merge.';
|
|
163
|
+
if (reasonCode === 'decorator-member') return 'Decorated class members are not safe for automatic unordered member merge.';
|
|
164
|
+
if (reasonCode === 'static-block-ordering') return 'Class static blocks make member order observable and block unordered member merge.';
|
|
165
|
+
if (reasonCode === 'accessor-pairing') return 'Getter/setter member pairs are not safe for automatic unordered member merge.';
|
|
166
|
+
if (reasonCode === 'private-name-scope') return 'Private class names must remain scoped to one class element declaration set.';
|
|
147
167
|
if (reasonCode === 'spread-like-member') return 'Spread-like member syntax makes object member merge ambiguous.';
|
|
148
168
|
if (reasonCode === 'overload-collision') return 'Member overloads or duplicate method signatures collide in an unordered member region.';
|
|
149
169
|
if (reasonCode === 'changed-existing-member') return 'An existing member changed inside a safe member-addition region.';
|
|
@@ -9,6 +9,14 @@ import {
|
|
|
9
9
|
removePreparedMemberAdditions,
|
|
10
10
|
uniqueStrings
|
|
11
11
|
} from './js-ts-semantic-merge-parse.js';
|
|
12
|
+
import {
|
|
13
|
+
classBodyInvariantReasons,
|
|
14
|
+
classPrivateAddedCollisionReasons,
|
|
15
|
+
classPrivateScopeReasons,
|
|
16
|
+
isAccessorMember,
|
|
17
|
+
isPrivateMemberKey,
|
|
18
|
+
privateNameFromKey
|
|
19
|
+
} from './js-ts-safe-member-class-invariants.js';
|
|
12
20
|
import { mergeResult } from './js-ts-safe-member-merge-result.js';
|
|
13
21
|
|
|
14
22
|
const NonSemanticRegionKinds = new Set(['property', 'type', 'config', 'content']);
|
|
@@ -155,6 +163,11 @@ function prepareRegion(input) {
|
|
|
155
163
|
const baseMembers = parseMembers(base.value.body, kind);
|
|
156
164
|
const workerMembers = parseMembers(worker.value.body, kind);
|
|
157
165
|
const headMembers = parseMembers(head.value.body, kind);
|
|
166
|
+
if (kind === 'class') {
|
|
167
|
+
reasonCodes.push(...classBodyInvariantReasons(input.region, 'base', base.value.body));
|
|
168
|
+
reasonCodes.push(...classBodyInvariantReasons(input.region, 'worker', worker.value.body));
|
|
169
|
+
reasonCodes.push(...classBodyInvariantReasons(input.region, 'head', head.value.body));
|
|
170
|
+
}
|
|
158
171
|
reasonCodes.push(...regionParseReasons(input.region, 'base', baseMembers));
|
|
159
172
|
reasonCodes.push(...regionParseReasons(input.region, 'worker', workerMembers));
|
|
160
173
|
reasonCodes.push(...regionParseReasons(input.region, 'head', headMembers));
|
|
@@ -170,6 +183,11 @@ function prepareRegion(input) {
|
|
|
170
183
|
const workerAddedKeys = workerMembers.members.map((member) => member.key).filter((key) => !baseByKey.has(key));
|
|
171
184
|
const headAddedKeys = headMembers.members.map((member) => member.key).filter((key) => !baseByKey.has(key));
|
|
172
185
|
reasonCodes.push(...duplicateAddedReasons(input.region, workerAddedKeys, workerByKey, headByKey));
|
|
186
|
+
if (kind === 'class') {
|
|
187
|
+
reasonCodes.push(...classPrivateScopeReasons(input.region, 'worker', baseMembers.members, workerMembers.members, workerAddedKeys));
|
|
188
|
+
reasonCodes.push(...classPrivateScopeReasons(input.region, 'head', baseMembers.members, headMembers.members, headAddedKeys));
|
|
189
|
+
reasonCodes.push(...classPrivateAddedCollisionReasons(input.region, workerAddedKeys, headAddedKeys, workerByKey, headByKey));
|
|
190
|
+
}
|
|
173
191
|
if (reasonCodes.length) return { ok: false, reasonCodes };
|
|
174
192
|
return {
|
|
175
193
|
ok: true,
|
|
@@ -209,7 +227,11 @@ function duplicateReasons(region, side, members) {
|
|
|
209
227
|
}
|
|
210
228
|
}
|
|
211
229
|
return [...duplicateGroups].map(([key, group]) => {
|
|
212
|
-
|
|
230
|
+
let reason;
|
|
231
|
+
if (group.some(isOverloadLikeMember)) reason = `overload-collision:${side}:${key}`;
|
|
232
|
+
else if (group.every(isAccessorMember)) reason = `accessor-pairing:${side}:${key}`;
|
|
233
|
+
else if (isPrivateMemberKey(key)) reason = `private-name-scope:${side}:${privateNameFromKey(key)}`;
|
|
234
|
+
else reason = `duplicate-key:${side}:${key}`;
|
|
213
235
|
return regionReason(region, reason);
|
|
214
236
|
});
|
|
215
237
|
}
|
|
@@ -239,9 +261,11 @@ function duplicateAddedReasons(region, workerAddedKeys, workerByKey, headByKey)
|
|
|
239
261
|
return duplicateAddedKeys.map((key) => {
|
|
240
262
|
const workerMember = workerByKey.get(key);
|
|
241
263
|
const headMember = headByKey.get(key);
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
264
|
+
let reason;
|
|
265
|
+
if (isOverloadLikeMember(workerMember) || isOverloadLikeMember(headMember)) reason = `overload-collision:worker-head:${key}`;
|
|
266
|
+
else if (isAccessorMember(workerMember) || isAccessorMember(headMember)) reason = `accessor-pairing:worker-head:${key}`;
|
|
267
|
+
else if (isPrivateMemberKey(key)) reason = `private-name-scope:worker-head:${privateNameFromKey(key)}`;
|
|
268
|
+
else reason = `duplicate-added-key:${key}`;
|
|
245
269
|
return regionReason(region, reason);
|
|
246
270
|
});
|
|
247
271
|
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { uniqueStrings } from './js-ts-safe-merge-context.js';
|
|
2
|
+
|
|
3
|
+
function analyzeJsTsBindingPattern(patternText, patternKind) {
|
|
4
|
+
const reasonCodes = [];
|
|
5
|
+
const inner = patternText.slice(1, -1);
|
|
6
|
+
if (patternKind === 'array') reasonCodes.push('binding-pattern-array-order-blocked');
|
|
7
|
+
if (containsJsTsCodeToken(patternText, '...')) reasonCodes.push('binding-pattern-rest-spread-blocked');
|
|
8
|
+
if (containsJsTsCodeToken(patternText, '=')) reasonCodes.push('binding-pattern-default-initializer-blocked');
|
|
9
|
+
if (patternKind === 'object' && containsJsTsCodeToken(patternText, ':')) reasonCodes.push('binding-pattern-rename-blocked');
|
|
10
|
+
const entries = splitJsTsTopLevelCommaText(inner).filter((part) => part.trim());
|
|
11
|
+
const bindingNames = patternKind === 'object' && reasonCodes.length === 0
|
|
12
|
+
? entries.map((part) => simpleIdentifier(part.trim())).filter(Boolean)
|
|
13
|
+
: [];
|
|
14
|
+
if (patternKind === 'object' && reasonCodes.length === 0 && bindingNames.length !== entries.length) {
|
|
15
|
+
reasonCodes.push('binding-pattern-unsupported-shape-blocked');
|
|
16
|
+
}
|
|
17
|
+
if (patternKind === 'object' && reasonCodes.length === 0 && bindingNames.length === 0) {
|
|
18
|
+
reasonCodes.push('binding-pattern-empty-object-blocked');
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
patternKind,
|
|
22
|
+
bindingNames,
|
|
23
|
+
reasonCodes: uniqueStrings([
|
|
24
|
+
...reasonCodes,
|
|
25
|
+
...(reasonCodes.length ? ['binding-pattern-merge-requires-binding-use-evidence'] : [])
|
|
26
|
+
])
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function jsTsFunctionParameterBindingPatternReasonCodes(baseText, workerText) {
|
|
31
|
+
const baseParameters = functionParameterText(baseText);
|
|
32
|
+
const workerParameters = functionParameterText(workerText);
|
|
33
|
+
if (baseParameters === undefined || workerParameters === undefined) return [];
|
|
34
|
+
if (sameParameterText(baseParameters, workerParameters)) return [];
|
|
35
|
+
const base = bindingPatternParameterAnalysis(baseParameters);
|
|
36
|
+
const worker = bindingPatternParameterAnalysis(workerParameters);
|
|
37
|
+
if (!base.hasBindingPattern && !worker.hasBindingPattern) return [];
|
|
38
|
+
return uniqueStrings([
|
|
39
|
+
...base.reasonCodes,
|
|
40
|
+
...worker.reasonCodes,
|
|
41
|
+
'binding-pattern-parameter-merge-requires-binding-use-evidence'
|
|
42
|
+
]);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function bindingPatternParameterAnalysis(parameters) {
|
|
46
|
+
const reasonCodes = [];
|
|
47
|
+
let hasBindingPattern = false;
|
|
48
|
+
for (const parameter of splitJsTsTopLevelCommaText(parameters).map((part) => part.trim()).filter(Boolean)) {
|
|
49
|
+
const text = parameter.startsWith('...') ? parameter.slice(3).trim() : parameter;
|
|
50
|
+
if (parameter.startsWith('...')) reasonCodes.push('binding-pattern-rest-spread-blocked');
|
|
51
|
+
if (!text.startsWith('{') && !text.startsWith('[')) continue;
|
|
52
|
+
hasBindingPattern = true;
|
|
53
|
+
const patternKind = text[0] === '{' ? 'object' : 'array';
|
|
54
|
+
const patternText = leadingJsTsBindingPatternText(text, patternKind);
|
|
55
|
+
if (!patternText) {
|
|
56
|
+
reasonCodes.push('binding-pattern-unsupported-shape-blocked');
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
reasonCodes.push(...analyzeJsTsBindingPattern(patternText, patternKind).reasonCodes);
|
|
60
|
+
}
|
|
61
|
+
return { hasBindingPattern, reasonCodes: uniqueStrings(reasonCodes) };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function leadingJsTsBindingPatternText(text, patternKind) {
|
|
65
|
+
const open = patternKind === 'object' ? '{' : '[';
|
|
66
|
+
const close = patternKind === 'object' ? '}' : ']';
|
|
67
|
+
if (text[0] !== open) return undefined;
|
|
68
|
+
const end = matchingJsTsBracketEnd(text, 0, open, close);
|
|
69
|
+
return end === undefined ? undefined : text.slice(0, end + 1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function matchingJsTsBracketEnd(text, start, open, close) {
|
|
73
|
+
let state = 'code';
|
|
74
|
+
let depth = 0;
|
|
75
|
+
for (let index = start; index < text.length; index += 1) {
|
|
76
|
+
const step = scanStep(text, index, state);
|
|
77
|
+
state = step.state;
|
|
78
|
+
if (step.skipTo !== undefined) {
|
|
79
|
+
index = step.skipTo;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (state !== 'code') continue;
|
|
83
|
+
const char = text[index];
|
|
84
|
+
if (char === open || char === '{' || char === '[') depth += 1;
|
|
85
|
+
else if (char === close || char === '}' || char === ']') {
|
|
86
|
+
depth -= 1;
|
|
87
|
+
if (depth === 0) return index;
|
|
88
|
+
}
|
|
89
|
+
if (depth < 0) return undefined;
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function functionParameterText(text) {
|
|
95
|
+
const source = String(text ?? '');
|
|
96
|
+
const open = source.indexOf('(');
|
|
97
|
+
if (open < 0) return undefined;
|
|
98
|
+
const end = matchingJsTsBracketEnd(source, open, '(', ')');
|
|
99
|
+
return end === undefined ? undefined : source.slice(open + 1, end);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function splitJsTsTopLevelCommaText(text) {
|
|
103
|
+
const parts = [];
|
|
104
|
+
let start = 0;
|
|
105
|
+
let state = 'code';
|
|
106
|
+
let depth = 0;
|
|
107
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
108
|
+
const step = scanStep(text, index, state);
|
|
109
|
+
state = step.state;
|
|
110
|
+
if (step.skipTo !== undefined) {
|
|
111
|
+
index = step.skipTo;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (state !== 'code') continue;
|
|
115
|
+
const char = text[index];
|
|
116
|
+
if (char === '(' || char === '[' || char === '{') depth += 1;
|
|
117
|
+
else if (char === ')' || char === ']' || char === '}') depth -= 1;
|
|
118
|
+
else if (char === ',' && depth === 0) {
|
|
119
|
+
parts.push(text.slice(start, index));
|
|
120
|
+
start = index + 1;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
parts.push(text.slice(start));
|
|
124
|
+
return parts;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function containsJsTsCodeToken(text, token) {
|
|
128
|
+
let state = 'code';
|
|
129
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
130
|
+
const step = scanStep(text, index, state);
|
|
131
|
+
state = step.state;
|
|
132
|
+
if (step.skipTo !== undefined) {
|
|
133
|
+
index = step.skipTo;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (state === 'code' && text.startsWith(token, index)) return true;
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function scanStep(text, index, state) {
|
|
142
|
+
const char = text[index];
|
|
143
|
+
const next = text[index + 1];
|
|
144
|
+
if (state === 'line-comment') return { state: char === '\n' ? 'code' : state };
|
|
145
|
+
if (state === 'block-comment') {
|
|
146
|
+
return char === '*' && next === '/' ? { state: 'code', skipTo: index + 1 } : { state };
|
|
147
|
+
}
|
|
148
|
+
if (state !== 'code') {
|
|
149
|
+
if (char === '\\') return { state, skipTo: index + 1 };
|
|
150
|
+
return { state: char === state ? 'code' : state };
|
|
151
|
+
}
|
|
152
|
+
if (char === '/' && next === '/') return { state: 'line-comment', skipTo: index + 1 };
|
|
153
|
+
if (char === '/' && next === '*') return { state: 'block-comment', skipTo: index + 1 };
|
|
154
|
+
if (char === '"' || char === "'" || char === '`') return { state: char };
|
|
155
|
+
return { state };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function sameParameterText(left, right) {
|
|
159
|
+
return String(left ?? '').replace(/\s+/g, ' ').trim() === String(right ?? '').replace(/\s+/g, ' ').trim();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function simpleIdentifier(text) {
|
|
163
|
+
return /^[A-Za-z_$][\w$]*$/u.test(text) ? text : undefined;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export {
|
|
167
|
+
analyzeJsTsBindingPattern,
|
|
168
|
+
jsTsFunctionParameterBindingPatternReasonCodes,
|
|
169
|
+
leadingJsTsBindingPatternText
|
|
170
|
+
};
|