@codeyam/codeyam-cli 0.1.0-bleeding-edge.8afd3ee → 0.1.0-staging.09652b8
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/analyzer-template/.build-info.json +7 -7
- package/analyzer-template/log.txt +3 -3
- package/analyzer-template/package.json +1 -1
- package/analyzer-template/packages/ai/index.ts +0 -1
- package/analyzer-template/packages/ai/scripts/ai-test-matrix.mjs +424 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +6 -16
- package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +197 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/paths.ts +28 -2
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +113 -4
- package/analyzer-template/packages/ai/src/lib/checkAllAttributes.ts +1 -3
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +430 -7
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +12 -6
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityDocumentation.ts +20 -2
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarioData.ts +56 -160
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarios.ts +79 -265
- package/analyzer-template/packages/ai/src/lib/generateEntityDocumentation.ts +16 -2
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +53 -154
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +84 -254
- package/analyzer-template/packages/ai/src/lib/generateStatementAnalysis.ts +48 -71
- package/analyzer-template/packages/ai/src/lib/getLLMCallStats.ts +0 -14
- package/analyzer-template/packages/ai/src/lib/modelInfo.ts +15 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityDocumentationGenerator.ts +8 -33
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.ts +54 -62
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.ts +93 -109
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityDocumentationGenerator.ts +8 -27
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +33 -38
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.ts +30 -30
- package/analyzer-template/packages/ai/src/lib/types/index.ts +2 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +15 -7
- package/analyzer-template/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.ts +28 -21
- package/analyzer-template/packages/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.ts +18 -11
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +28 -21
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js +18 -11
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/index.d.ts +1 -0
- package/analyzer-template/packages/github/dist/utils/index.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/index.js +1 -0
- package/analyzer-template/packages/github/dist/utils/index.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getNextRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getNextRoutePath.js +2 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getNextRoutePath.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.js +2 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts +12 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js +32 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js.map +1 -0
- package/analyzer-template/packages/ui-components/src/scenario-editor/components/DataItemEditor.tsx +1 -1
- package/analyzer-template/packages/utils/dist/utils/index.d.ts +1 -0
- package/analyzer-template/packages/utils/dist/utils/index.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/index.js +1 -0
- package/analyzer-template/packages/utils/dist/utils/index.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getNextRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getNextRoutePath.js +2 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getNextRoutePath.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.js +2 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts +12 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts.map +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js +32 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js.map +1 -0
- package/analyzer-template/packages/utils/index.ts +1 -0
- package/analyzer-template/packages/utils/src/lib/frameworks/getNextRoutePath.ts +2 -1
- package/analyzer-template/packages/utils/src/lib/frameworks/nextRouteFileNameToRoute.ts +2 -1
- package/analyzer-template/packages/utils/src/lib/frameworks/sanitizeNextRouteSegments.ts +33 -0
- package/analyzer-template/project/startScenarioCapture.ts +24 -0
- package/analyzer-template/project/trackGeneratedFiles.ts +41 -0
- package/analyzer-template/project/writeMockDataTsx.ts +94 -4
- package/analyzer-template/project/writeScenarioComponents.ts +35 -27
- package/background/src/lib/virtualized/project/startScenarioCapture.js +18 -0
- package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/trackGeneratedFiles.js +30 -0
- package/background/src/lib/virtualized/project/trackGeneratedFiles.js.map +1 -0
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +71 -3
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +15 -11
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/codeyam-cli/src/commands/init.js +4 -23
- package/codeyam-cli/src/commands/init.js.map +1 -1
- package/codeyam-cli/src/utils/webappDetection.js +2 -1
- package/codeyam-cli/src/utils/webappDetection.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-B9Sf8e9w.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-B0oiPem-.js → InteractivePreview-CDnfNKKQ.js} +3 -3
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-DUS-3h7I.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-BKKG1s2B.js → LogViewer-TJzDQku1.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-BgdlWM6p.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-Bl6GY-OE.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DmjXUj6m.js → ScenarioViewer-BDq8RX50.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/_index-Bh3y3Wsl.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-tq7Bl6-t.js +10 -0
- package/codeyam-cli/src/webserver/build/client/assets/{chart-column-VXBS6qOn.js → chart-column-q9_nHfwv.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-WWGJGFF6-DvL0YqDJ.js +26 -0
- package/codeyam-cli/src/webserver/build/client/assets/{circle-alert-n5GUC2AS.js → circle-alert-CKMpA1v_.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{clock-DKqtX8js.js → clock-Wnfog8Qw.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-C_ixaqqh.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-BHiWkb_W.js → entity._sha._-3bYjyojg.js} +10 -10
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-DtfwpN9J.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-QecTs_sq.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-hnkEgHrC.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/file-text-CvCVdKLW.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/files-DgUCYhbd.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/git-WoKohOtW.js +12 -0
- package/codeyam-cli/src/webserver/build/client/assets/globals-DZfbt0u5.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/index-Vvbl94Xc.js +8 -0
- package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-v3c6DFp4.js → loader-circle-Bxm63UxG.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-c90b8608.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/root-DrVZQamX.js +16 -0
- package/codeyam-cli/src/webserver/build/client/assets/{search-DA14wXpu.js → search-CJkk16Ct.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{settings-COJUrwGu.js → settings-ConzHeiL.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-LuiJ1UIm.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/simulations-B9LRwAej.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-Lumm1t01.js → useLastLogLine-CpUcCv1V.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useToast-DOxmMaSg.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{zap-BvukH0eN.js → zap-D5R1FAcH.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-DzbqTxoN.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/server-build-DGGis3OZ.js +166 -0
- package/codeyam-cli/src/webserver/build/server/index.js +1 -1
- package/codeyam-cli/src/webserver/build-info.json +5 -5
- package/codeyam-cli/src/webserver/server.js +1 -1
- package/codeyam-cli/src/webserver/server.js.map +1 -1
- package/codeyam-cli/templates/codeyam-setup-skill.md +5 -0
- package/package.json +7 -7
- package/packages/ai/index.js +0 -1
- package/packages/ai/index.js.map +1 -1
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +6 -15
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
- package/packages/ai/src/lib/astScopes/methodSemantics.js +134 -0
- package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
- package/packages/ai/src/lib/astScopes/paths.js +28 -3
- package/packages/ai/src/lib/astScopes/paths.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +99 -3
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/checkAllAttributes.js +1 -3
- package/packages/ai/src/lib/checkAllAttributes.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +308 -2
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +12 -6
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityDocumentation.js +19 -1
- package/packages/ai/src/lib/generateChangesEntityDocumentation.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityScenarioData.js +55 -156
- package/packages/ai/src/lib/generateChangesEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityScenarios.js +79 -262
- package/packages/ai/src/lib/generateChangesEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateEntityDocumentation.js +15 -1
- package/packages/ai/src/lib/generateEntityDocumentation.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarioData.js +52 -152
- package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarios.js +88 -258
- package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateStatementAnalysis.js +46 -71
- package/packages/ai/src/lib/generateStatementAnalysis.js.map +1 -1
- package/packages/ai/src/lib/getLLMCallStats.js +0 -14
- package/packages/ai/src/lib/getLLMCallStats.js.map +1 -1
- package/packages/ai/src/lib/modelInfo.js +15 -0
- package/packages/ai/src/lib/modelInfo.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityDocumentationGenerator.js +8 -33
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityDocumentationGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js +35 -41
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js +59 -72
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityDocumentationGenerator.js +8 -27
- package/packages/ai/src/lib/promptGenerators/generateEntityDocumentationGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +24 -27
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js +21 -22
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/types/index.js +2 -0
- package/packages/ai/src/lib/types/index.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +16 -7
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +28 -21
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js +18 -11
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js.map +1 -1
- package/packages/utils/index.js +1 -0
- package/packages/utils/index.js.map +1 -1
- package/packages/utils/src/lib/frameworks/getNextRoutePath.js +2 -1
- package/packages/utils/src/lib/frameworks/getNextRoutePath.js.map +1 -1
- package/packages/utils/src/lib/frameworks/nextRouteFileNameToRoute.js +2 -1
- package/packages/utils/src/lib/frameworks/nextRouteFileNameToRoute.js.map +1 -1
- package/packages/utils/src/lib/frameworks/sanitizeNextRouteSegments.js +32 -0
- package/packages/utils/src/lib/frameworks/sanitizeNextRouteSegments.js.map +1 -0
- package/analyzer-template/packages/ai/src/lib/generateEntityDataMap.ts +0 -375
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-rqv54FUY.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-DqXXjAJ7.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-DU_jxCPD.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-5DY-YIxu.js +0 -6
- package/codeyam-cli/src/webserver/build/client/assets/_index-DvSrcxsk.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-CsaMd9mb.js +0 -10
- package/codeyam-cli/src/webserver/build/client/assets/components-Dj-Ggnl2.js +0 -40
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BbR3FwNc.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-L7M9Vr5z.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-C9w-q7P3.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-CdGoUs8A.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/file-text-B6Er7j5k.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-KcDVw1FY.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/git-B9uZ8eSJ.js +0 -12
- package/codeyam-cli/src/webserver/build/client/assets/globals-B0f88RTV.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-fca08d7e.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-Cf8VBqIb.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/settings-NU_ZquhK.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-CNaMJ-nR.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useToast-BRShB17p.js +0 -1
- package/codeyam-cli/src/webserver/build/client/cy-logo-cli.svg +0 -13
- package/codeyam-cli/src/webserver/build/client/favicon.svg +0 -13
- package/codeyam-cli/src/webserver/build/server/assets/index-DHr4rT4u.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-Bi1mj14J.js +0 -166
- package/codeyam-cli/src/webserver/public/cy-logo-cli.svg +0 -13
- package/codeyam-cli/src/webserver/public/favicon.svg +0 -13
- package/packages/ai/src/lib/generateEntityDataMap.js +0 -335
- package/packages/ai/src/lib/generateEntityDataMap.js.map +0 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityDataMapGenerator.js +0 -17
- package/packages/ai/src/lib/promptGenerators/generateEntityDataMapGenerator.js.map +0 -1
|
@@ -34,10 +34,12 @@ const ROOT_SCOPE_NAME = 'root';
|
|
|
34
34
|
export let maxEquivalencyChainDepth = 0;
|
|
35
35
|
export let addToSchemaCallCount = 0;
|
|
36
36
|
export let followEquivalenciesCallCount = 0;
|
|
37
|
+
export let addEquivalencyCallCount = 0;
|
|
37
38
|
export function resetScopeDataStructureMetrics() {
|
|
38
39
|
maxEquivalencyChainDepth = 0;
|
|
39
40
|
addToSchemaCallCount = 0;
|
|
40
41
|
followEquivalenciesCallCount = 0;
|
|
42
|
+
addEquivalencyCallCount = 0;
|
|
41
43
|
}
|
|
42
44
|
export class ScopeDataStructure {
|
|
43
45
|
constructor(managers, scopeName = ROOT_SCOPE_NAME, scopeText, scopeAnalysis) {
|
|
@@ -58,6 +60,10 @@ export class ScopeDataStructure {
|
|
|
58
60
|
// Inverted index: maps uniqueId -> EquivalencyDatabaseEntry for O(1) lookup
|
|
59
61
|
this.intermediatesOrderIndex = new Map();
|
|
60
62
|
this.globalVisited = new Set();
|
|
63
|
+
// Separate visited set for addComplexSourcePathVariables - uses scope::path only (not value)
|
|
64
|
+
// This allows addComplexSourcePathVariables to run for each unique scope+path combo,
|
|
65
|
+
// while the main globalVisited uses scope+path+value for fine-grained deduplication
|
|
66
|
+
this.complexSourceVisited = new Set();
|
|
61
67
|
this.equivalencyManagers.push(...managers);
|
|
62
68
|
this.scopeTree.name = scopeName;
|
|
63
69
|
this.addScopeAnalysis(scopeName, scopeText, scopeAnalysis);
|
|
@@ -179,6 +185,16 @@ export class ScopeDataStructure {
|
|
|
179
185
|
}
|
|
180
186
|
addToSchema({ path, value, scopeNode, equivalencyValueChain = [], traceId, }) {
|
|
181
187
|
addToSchemaCallCount++;
|
|
188
|
+
// DEBUG: Detect infinite loops
|
|
189
|
+
if (addToSchemaCallCount > 500000) {
|
|
190
|
+
console.error('INFINITE LOOP DETECTED in addToSchema', {
|
|
191
|
+
callCount: addToSchemaCallCount,
|
|
192
|
+
path,
|
|
193
|
+
value,
|
|
194
|
+
scopeNodeName: scopeNode?.name,
|
|
195
|
+
});
|
|
196
|
+
throw new Error(`Infinite loop detected: addToSchema called ${addToSchemaCallCount} times`);
|
|
197
|
+
}
|
|
182
198
|
// Track max chain depth
|
|
183
199
|
if (equivalencyValueChain.length > maxEquivalencyChainDepth) {
|
|
184
200
|
maxEquivalencyChainDepth = equivalencyValueChain.length;
|
|
@@ -265,6 +281,7 @@ export class ScopeDataStructure {
|
|
|
265
281
|
// throw new Error('STOP ON ADD');
|
|
266
282
|
// }
|
|
267
283
|
const equivalenciesDatabaseEntry = this.getEquivalenciesDatabaseEntry(scopeNode.name, path);
|
|
284
|
+
// Call addComplexSourcePathVariables like the original code (before visited check)
|
|
268
285
|
this.addComplexSourcePathVariables(equivalenciesDatabaseEntry, scopeNode, path, equivalencyValueChain, traceId);
|
|
269
286
|
const uniqueIdentifier = `${scopeNode.name}::${path}::${value}`;
|
|
270
287
|
if (this.globalVisited.has(uniqueIdentifier)) {
|
|
@@ -414,6 +431,19 @@ export class ScopeDataStructure {
|
|
|
414
431
|
}
|
|
415
432
|
addEquivalency(path, equivalentPath, equivalentScopeName, scopeNode, equivalencyReason, equivalencyValueChain, traceId) {
|
|
416
433
|
var _a;
|
|
434
|
+
// DEBUG: Detect infinite loops
|
|
435
|
+
addEquivalencyCallCount++;
|
|
436
|
+
if (addEquivalencyCallCount > 50000) {
|
|
437
|
+
console.error('INFINITE LOOP DETECTED in addEquivalency', {
|
|
438
|
+
callCount: addEquivalencyCallCount,
|
|
439
|
+
path,
|
|
440
|
+
equivalentPath,
|
|
441
|
+
equivalentScopeName,
|
|
442
|
+
scopeNodeName: scopeNode.name,
|
|
443
|
+
equivalencyReason,
|
|
444
|
+
});
|
|
445
|
+
throw new Error(`Infinite loop detected: addEquivalency called ${addEquivalencyCallCount} times`);
|
|
446
|
+
}
|
|
417
447
|
// Temporary debugging to track down unnecessary equivalencies
|
|
418
448
|
if (![
|
|
419
449
|
'original equivalency',
|
|
@@ -441,6 +471,8 @@ export class ScopeDataStructure {
|
|
|
441
471
|
'implicit parent equivalency - rerouted via useCallback', // 1 failure
|
|
442
472
|
'Spread operator equivalency key update: implicit parent equivalency', // 1 failure
|
|
443
473
|
'Array.from() equivalency',
|
|
474
|
+
'propagated sub-property equivalency',
|
|
475
|
+
'propagated function call return sub-property equivalency',
|
|
444
476
|
].includes(equivalencyReason)) {
|
|
445
477
|
if ([
|
|
446
478
|
'signature of functionCall',
|
|
@@ -471,8 +503,41 @@ export class ScopeDataStructure {
|
|
|
471
503
|
}
|
|
472
504
|
(_a = scopeNode.equivalencies)[path] || (_a[path] = []);
|
|
473
505
|
const existing = scopeNode.equivalencies[path];
|
|
474
|
-
|
|
475
|
-
v.scopeNodeName === equivalentScopeName)
|
|
506
|
+
const existingEquivalency = existing.find((v) => v.schemaPath === equivalentPath &&
|
|
507
|
+
v.scopeNodeName === equivalentScopeName);
|
|
508
|
+
if (existingEquivalency) {
|
|
509
|
+
// During Phase 2 (onlyEquivalencies=false), we need to still process the equivalency
|
|
510
|
+
// to build the chain and add to the database, even if the equivalency already exists
|
|
511
|
+
if (!this.onlyEquivalencies) {
|
|
512
|
+
const equivalentScopeNode = this.getScopeOrFunctionCallInfo(equivalentScopeName);
|
|
513
|
+
if (equivalentScopeNode) {
|
|
514
|
+
// Extract function call name from path if it looks like a function call path
|
|
515
|
+
// e.g., "ChildComponent().signature[0].dataItem" -> "ChildComponent"
|
|
516
|
+
const pathMatch = path.match(/^([^().]+)\(\)/);
|
|
517
|
+
const previousPathScopeNodeName = pathMatch
|
|
518
|
+
? pathMatch[1]
|
|
519
|
+
: scopeNode.name;
|
|
520
|
+
this.addToSchema({
|
|
521
|
+
path: equivalentPath,
|
|
522
|
+
value: 'unknown',
|
|
523
|
+
scopeNode: equivalentScopeNode,
|
|
524
|
+
equivalencyValueChain: [
|
|
525
|
+
...(equivalencyValueChain ?? []),
|
|
526
|
+
{
|
|
527
|
+
id: existingEquivalency.id,
|
|
528
|
+
source: 'duplicate equivalency - Phase 2',
|
|
529
|
+
reason: equivalencyReason,
|
|
530
|
+
previousPath: {
|
|
531
|
+
scopeNodeName: previousPathScopeNodeName,
|
|
532
|
+
schemaPath: path,
|
|
533
|
+
value: scopeNode.schema[path],
|
|
534
|
+
},
|
|
535
|
+
},
|
|
536
|
+
],
|
|
537
|
+
traceId,
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
}
|
|
476
541
|
return;
|
|
477
542
|
}
|
|
478
543
|
const id = ++this.lastEquivalencyId;
|
|
@@ -834,6 +899,52 @@ export class ScopeDataStructure {
|
|
|
834
899
|
path = cleanPath(path.replace(/::cyDuplicateKey\d+::/g, ''), allPaths);
|
|
835
900
|
equivalentValue = cleanPath(equivalentValue.replace(/::cyDuplicateKey\d+::/g, ''), allPaths);
|
|
836
901
|
this.addEquivalency(path, equivalentValue, scopeNode.name, scopeNode, 'original equivalency');
|
|
902
|
+
// Propagate sub-property equivalencies when the equivalentValue is a simple variable
|
|
903
|
+
// that has sub-properties defined in the isolatedEquivalentVariables.
|
|
904
|
+
// This handles cases like: dataItem={{ structure: completeDataStructure }}
|
|
905
|
+
// where completeDataStructure has sub-properties like completeDataStructure['Function Arguments']
|
|
906
|
+
// We need to propagate these to create: dataItem.structure['Function Arguments'] equivalencies
|
|
907
|
+
const isSimpleVariable = !equivalentValue.startsWith('signature[') &&
|
|
908
|
+
!equivalentValue.includes('functionCallReturnValue') &&
|
|
909
|
+
!equivalentValue.includes('.') &&
|
|
910
|
+
!equivalentValue.includes('[');
|
|
911
|
+
if (isSimpleVariable) {
|
|
912
|
+
// Look in current scope and all parent scopes for sub-properties
|
|
913
|
+
const scopesToCheck = [scopeNode.name, ...scopeNode.tree];
|
|
914
|
+
for (const scopeName of scopesToCheck) {
|
|
915
|
+
const checkScope = this.scopeNodes[scopeName];
|
|
916
|
+
if (!checkScope?.analysis?.isolatedEquivalentVariables)
|
|
917
|
+
continue;
|
|
918
|
+
for (const [subPath, subValue] of Object.entries(checkScope.analysis.isolatedEquivalentVariables)) {
|
|
919
|
+
// Check if this is a sub-property of the equivalentValue variable
|
|
920
|
+
// e.g., completeDataStructure['Function Arguments'] or completeDataStructure.foo
|
|
921
|
+
const matchesDot = subPath.startsWith(equivalentValue + '.');
|
|
922
|
+
const matchesBracket = subPath.startsWith(equivalentValue + '[');
|
|
923
|
+
if (matchesDot || matchesBracket) {
|
|
924
|
+
const subPropertyPath = subPath.substring(equivalentValue.length);
|
|
925
|
+
const newPath = cleanPath(path + subPropertyPath, allPaths);
|
|
926
|
+
const newEquivalentValue = cleanPath(subValue.replace(/::cyDuplicateKey\d+::/g, ''), allPaths);
|
|
927
|
+
if (newEquivalentValue &&
|
|
928
|
+
this.isValidPath(newEquivalentValue)) {
|
|
929
|
+
this.addEquivalency(newPath, newEquivalentValue, checkScope.name, // Use the scope where the sub-property was found
|
|
930
|
+
scopeNode, 'propagated sub-property equivalency');
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
// Also check if equivalentValue itself maps to a functionCallReturnValue
|
|
934
|
+
// e.g., result = useMemo(...).functionCallReturnValue
|
|
935
|
+
if (subPath === equivalentValue &&
|
|
936
|
+
typeof subValue === 'string' &&
|
|
937
|
+
subValue.endsWith('.functionCallReturnValue')) {
|
|
938
|
+
this.propagateFunctionCallReturnSubProperties(path, subValue, scopeNode, allPaths);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
// Handle function call return values by propagating returnValue.* sub-properties
|
|
944
|
+
// from the callback scope to the usage path
|
|
945
|
+
if (equivalentValue.endsWith('.functionCallReturnValue')) {
|
|
946
|
+
this.propagateFunctionCallReturnSubProperties(path, equivalentValue, scopeNode, allPaths);
|
|
947
|
+
}
|
|
837
948
|
}
|
|
838
949
|
}
|
|
839
950
|
for (const key of Array.from(allPaths)) {
|
|
@@ -867,6 +978,182 @@ export class ScopeDataStructure {
|
|
|
867
978
|
}
|
|
868
979
|
this.validateSchema(scopeNode, false, false);
|
|
869
980
|
}
|
|
981
|
+
/**
|
|
982
|
+
* Propagates returnValue.* sub-properties from a callback scope to the usage path.
|
|
983
|
+
*
|
|
984
|
+
* When we have an equivalency like:
|
|
985
|
+
* DataItemEditor().signature[0].structure -> getData().functionCallReturnValue
|
|
986
|
+
*
|
|
987
|
+
* And the callback scope for getData has:
|
|
988
|
+
* returnValue.args -> dataStructure.arguments
|
|
989
|
+
*
|
|
990
|
+
* This method creates the transitive equivalency:
|
|
991
|
+
* DataItemEditor().signature[0].structure.args -> signature[0].dataStructure.arguments
|
|
992
|
+
*
|
|
993
|
+
* It also resolves variable references through parent scopes (e.g., dataStructure -> signature[0].dataStructure)
|
|
994
|
+
* and ensures the database entry is updated with the usage path.
|
|
995
|
+
*/
|
|
996
|
+
propagateFunctionCallReturnSubProperties(path, equivalentValue, scopeNode, allPaths) {
|
|
997
|
+
// Try to find the callback scope name from different patterns:
|
|
998
|
+
// 1. "getData().functionCallReturnValue" → look up getData variable to find scope
|
|
999
|
+
// 2. "useMemo(cyScope1(), [...]).functionCallReturnValue" → extract cyScope1 directly
|
|
1000
|
+
let callbackScopeName;
|
|
1001
|
+
// Pattern 1: Simple function call like getData().functionCallReturnValue
|
|
1002
|
+
const simpleFunctionMatch = equivalentValue.match(/^(\w+)\(\)\.functionCallReturnValue$/);
|
|
1003
|
+
if (simpleFunctionMatch) {
|
|
1004
|
+
const functionName = simpleFunctionMatch[1];
|
|
1005
|
+
// Find the function reference in current or parent scopes
|
|
1006
|
+
const scopesToCheck = [scopeNode.name, ...scopeNode.tree];
|
|
1007
|
+
for (const scopeName of scopesToCheck) {
|
|
1008
|
+
const checkScope = this.scopeNodes[scopeName];
|
|
1009
|
+
if (!checkScope?.analysis?.isolatedEquivalentVariables)
|
|
1010
|
+
continue;
|
|
1011
|
+
const functionRef = checkScope.analysis.isolatedEquivalentVariables[functionName];
|
|
1012
|
+
if (typeof functionRef === 'string' && functionRef.endsWith('F')) {
|
|
1013
|
+
callbackScopeName = functionRef.slice(0, -1);
|
|
1014
|
+
break;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
// Pattern 2: useMemo/useCallback with callback scope
|
|
1019
|
+
// e.g., "useMemo(cyScope1(), [deps]).functionCallReturnValue"
|
|
1020
|
+
if (!callbackScopeName) {
|
|
1021
|
+
const useMemoMatch = equivalentValue.match(/^useMemo\((\w+)\(\),\s*\[.*\]\)\.functionCallReturnValue$/);
|
|
1022
|
+
if (useMemoMatch) {
|
|
1023
|
+
callbackScopeName = useMemoMatch[1];
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
if (!callbackScopeName)
|
|
1027
|
+
return;
|
|
1028
|
+
const callbackScope = this.scopeNodes[callbackScopeName];
|
|
1029
|
+
if (!callbackScope)
|
|
1030
|
+
return;
|
|
1031
|
+
// Look for returnValue.* sub-properties in the callback scope
|
|
1032
|
+
if (!callbackScope.analysis?.isolatedEquivalentVariables)
|
|
1033
|
+
return;
|
|
1034
|
+
const isolatedVars = callbackScope.analysis.isolatedEquivalentVariables;
|
|
1035
|
+
// First, check if returnValue is an alias to another variable (e.g., returnValue = intermediate)
|
|
1036
|
+
// If so, we need to look for that variable's sub-properties too
|
|
1037
|
+
const returnValueAlias = typeof isolatedVars.returnValue === 'string' &&
|
|
1038
|
+
!isolatedVars.returnValue.includes('.')
|
|
1039
|
+
? isolatedVars.returnValue
|
|
1040
|
+
: undefined;
|
|
1041
|
+
// Pattern 3: Object.keys(X).reduce() - the reduce result has the same sub-properties as X
|
|
1042
|
+
// When returnValue = "Object.keys(source).reduce(...).functionCallReturnValue", look for source.* sub-properties
|
|
1043
|
+
let reduceSourceVar;
|
|
1044
|
+
if (typeof isolatedVars.returnValue === 'string') {
|
|
1045
|
+
const reduceMatch = isolatedVars.returnValue.match(/^Object\.keys\((\w+)\)\.reduce\(.*\)\.functionCallReturnValue$/);
|
|
1046
|
+
if (reduceMatch) {
|
|
1047
|
+
reduceSourceVar = reduceMatch[1];
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
for (const [subPath, subValue] of Object.entries(isolatedVars)) {
|
|
1051
|
+
// Check for direct returnValue.* sub-properties
|
|
1052
|
+
const isReturnValueSub = subPath.startsWith('returnValue.') ||
|
|
1053
|
+
subPath.startsWith('returnValue[');
|
|
1054
|
+
// Also check for alias.* sub-properties (e.g., intermediate.args when returnValue = intermediate)
|
|
1055
|
+
const isAliasSub = returnValueAlias &&
|
|
1056
|
+
(subPath.startsWith(returnValueAlias + '.') ||
|
|
1057
|
+
subPath.startsWith(returnValueAlias + '['));
|
|
1058
|
+
// Also check for reduce source.* sub-properties (e.g., source['Function Arguments'] when returnValue = Object.keys(source).reduce())
|
|
1059
|
+
const isReduceSourceSub = reduceSourceVar &&
|
|
1060
|
+
(subPath.startsWith(reduceSourceVar + '.') ||
|
|
1061
|
+
subPath.startsWith(reduceSourceVar + '['));
|
|
1062
|
+
if (typeof subValue !== 'string' ||
|
|
1063
|
+
(!isReturnValueSub && !isAliasSub && !isReduceSourceSub))
|
|
1064
|
+
continue;
|
|
1065
|
+
// Convert alias/reduceSource paths to returnValue paths
|
|
1066
|
+
let effectiveSubPath = subPath;
|
|
1067
|
+
if (isAliasSub && !isReturnValueSub) {
|
|
1068
|
+
// Replace the alias prefix with returnValue
|
|
1069
|
+
effectiveSubPath =
|
|
1070
|
+
'returnValue' + subPath.substring(returnValueAlias.length);
|
|
1071
|
+
}
|
|
1072
|
+
else if (isReduceSourceSub && !isReturnValueSub && !isAliasSub) {
|
|
1073
|
+
// Replace the reduce source prefix with returnValue
|
|
1074
|
+
effectiveSubPath =
|
|
1075
|
+
'returnValue' + subPath.substring(reduceSourceVar.length);
|
|
1076
|
+
}
|
|
1077
|
+
const subPropertyPath = effectiveSubPath.substring('returnValue'.length);
|
|
1078
|
+
const newPath = cleanPath(path + subPropertyPath, allPaths);
|
|
1079
|
+
let newEquivalentValue = cleanPath(subValue.replace(/::cyDuplicateKey\d+::/g, ''), allPaths);
|
|
1080
|
+
// Resolve variable references through parent scope equivalencies
|
|
1081
|
+
const resolved = this.resolveVariableThroughParentScopes(newEquivalentValue, callbackScope, allPaths);
|
|
1082
|
+
newEquivalentValue = resolved.resolvedPath;
|
|
1083
|
+
const equivalentScopeName = resolved.scopeName;
|
|
1084
|
+
if (!newEquivalentValue || !this.isValidPath(newEquivalentValue))
|
|
1085
|
+
continue;
|
|
1086
|
+
this.addEquivalency(newPath, newEquivalentValue, equivalentScopeName, scopeNode, 'propagated function call return sub-property equivalency');
|
|
1087
|
+
// Ensure the database entry has the usage path
|
|
1088
|
+
this.addUsageToEquivalencyDatabaseEntry(newPath, newEquivalentValue, equivalentScopeName, scopeNode.name);
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
/**
|
|
1092
|
+
* Resolves a variable path through parent scope equivalencies.
|
|
1093
|
+
*
|
|
1094
|
+
* For example, if the path is "dataStructure.arguments" and the parent scope has
|
|
1095
|
+
* dataStructure -> signature[0].dataStructure, this returns:
|
|
1096
|
+
* { resolvedPath: "signature[0].dataStructure.arguments", scopeName: "ParentScope" }
|
|
1097
|
+
*/
|
|
1098
|
+
resolveVariableThroughParentScopes(path, callbackScope, allPaths) {
|
|
1099
|
+
if (!path)
|
|
1100
|
+
return { resolvedPath: undefined, scopeName: callbackScope.name };
|
|
1101
|
+
// Extract the root variable name
|
|
1102
|
+
const dotIndex = path.indexOf('.');
|
|
1103
|
+
const bracketIndex = path.indexOf('[');
|
|
1104
|
+
let firstDelimiter = -1;
|
|
1105
|
+
if (dotIndex > -1 && bracketIndex > -1) {
|
|
1106
|
+
firstDelimiter = Math.min(dotIndex, bracketIndex);
|
|
1107
|
+
}
|
|
1108
|
+
else {
|
|
1109
|
+
firstDelimiter = dotIndex > -1 ? dotIndex : bracketIndex;
|
|
1110
|
+
}
|
|
1111
|
+
if (firstDelimiter === -1)
|
|
1112
|
+
return { resolvedPath: path, scopeName: callbackScope.name };
|
|
1113
|
+
const rootVar = path.substring(0, firstDelimiter);
|
|
1114
|
+
const restOfPath = path.substring(firstDelimiter);
|
|
1115
|
+
// Look in parent scopes for the root variable's equivalency
|
|
1116
|
+
for (const parentScopeName of callbackScope.tree || []) {
|
|
1117
|
+
const parentScope = this.scopeNodes[parentScopeName];
|
|
1118
|
+
if (!parentScope?.analysis?.isolatedEquivalentVariables)
|
|
1119
|
+
continue;
|
|
1120
|
+
const rootEquiv = parentScope.analysis.isolatedEquivalentVariables[rootVar];
|
|
1121
|
+
if (typeof rootEquiv === 'string') {
|
|
1122
|
+
return {
|
|
1123
|
+
resolvedPath: cleanPath(rootEquiv + restOfPath, allPaths),
|
|
1124
|
+
scopeName: parentScopeName,
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
return { resolvedPath: path, scopeName: callbackScope.name };
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Adds a usage path to the equivalency database entry that has the given source.
|
|
1132
|
+
*
|
|
1133
|
+
* The addEquivalency call creates the equivalency but doesn't always properly
|
|
1134
|
+
* link the usage in the database, so we need to do it explicitly.
|
|
1135
|
+
*/
|
|
1136
|
+
addUsageToEquivalencyDatabaseEntry(usagePath, sourcePath, sourceScopeName, fallbackScopeName) {
|
|
1137
|
+
const usageEntry = {
|
|
1138
|
+
scopeNodeName: usagePath.match(/^([^().]+)\(\)/)
|
|
1139
|
+
? (usagePath.match(/^([^().]+)\(\)/)?.[1] ?? fallbackScopeName)
|
|
1140
|
+
: fallbackScopeName,
|
|
1141
|
+
schemaPath: usagePath,
|
|
1142
|
+
};
|
|
1143
|
+
const sourceKey = `${sourceScopeName}::${sourcePath}`;
|
|
1144
|
+
for (const entry of this.equivalencyDatabase) {
|
|
1145
|
+
if (entry.intermediatesOrder[sourceKey] === 0 ||
|
|
1146
|
+
entry.sourceCandidates.some((sc) => sc.scopeNodeName === sourceScopeName &&
|
|
1147
|
+
sc.schemaPath === sourcePath)) {
|
|
1148
|
+
const usageExists = entry.usages.some((u) => u.scopeNodeName === usageEntry.scopeNodeName &&
|
|
1149
|
+
u.schemaPath === usageEntry.schemaPath);
|
|
1150
|
+
if (!usageExists) {
|
|
1151
|
+
entry.usages.push(usageEntry);
|
|
1152
|
+
}
|
|
1153
|
+
break;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
870
1157
|
checkForArrayItemPath(pathParts, scopeNode, equivalencyValueChain) {
|
|
871
1158
|
const arrayItemPath = joinParenthesesAndArrays([...pathParts, '[]']);
|
|
872
1159
|
if (scopeNode.equivalencies[arrayItemPath]) {
|
|
@@ -1054,6 +1341,13 @@ export class ScopeDataStructure {
|
|
|
1054
1341
|
return;
|
|
1055
1342
|
}
|
|
1056
1343
|
const usageScopeNode = this.getScopeOrFunctionCallInfo(usageEquivalency.scopeNodeName);
|
|
1344
|
+
// Guard against infinite recursion by tracking which paths we've already
|
|
1345
|
+
// added from addComplexSourcePathVariables
|
|
1346
|
+
const complexPathKey = `${usageScopeNode.name}::${newUsageEquivalentPath}`;
|
|
1347
|
+
if (this.complexSourceVisited.has(complexPathKey)) {
|
|
1348
|
+
continue;
|
|
1349
|
+
}
|
|
1350
|
+
this.complexSourceVisited.add(complexPathKey);
|
|
1057
1351
|
this.addToSchema({
|
|
1058
1352
|
path: newUsageEquivalentPath,
|
|
1059
1353
|
value: 'unknown',
|
|
@@ -1162,6 +1456,7 @@ export class ScopeDataStructure {
|
|
|
1162
1456
|
}
|
|
1163
1457
|
for (let i = 0; i < cleanEquivalencyValueChain.length; ++i) {
|
|
1164
1458
|
const pathInfo = cleanEquivalencyValueChain[i].currentPath;
|
|
1459
|
+
const previousPath = cleanEquivalencyValueChain[i].previousPath;
|
|
1165
1460
|
const schemaPathParts = this.splitPath(pathInfo.schemaPath);
|
|
1166
1461
|
const isSignaturePath = schemaPathParts.findIndex((p) => p.startsWith('signature[')) > 0;
|
|
1167
1462
|
if (schemaPathParts[0].startsWith('returnValue') ||
|
|
@@ -1171,6 +1466,17 @@ export class ScopeDataStructure {
|
|
|
1171
1466
|
) {
|
|
1172
1467
|
databaseEntry.usages.push(pathInfo);
|
|
1173
1468
|
}
|
|
1469
|
+
// Also add previousPath as a usage if it matches the criteria
|
|
1470
|
+
// This handles propagated sub-property equivalencies where the JSX prop path
|
|
1471
|
+
// is in previousPath and should be tracked as a usage
|
|
1472
|
+
if (previousPath) {
|
|
1473
|
+
const prevSchemaPathParts = this.splitPath(previousPath.schemaPath);
|
|
1474
|
+
const isPrevSignaturePath = prevSchemaPathParts.findIndex((p) => p.startsWith('signature[')) > 0;
|
|
1475
|
+
if (prevSchemaPathParts[0].startsWith('returnValue') ||
|
|
1476
|
+
isPrevSignaturePath) {
|
|
1477
|
+
databaseEntry.usages.push(previousPath);
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1174
1480
|
const pathId = this.uniqueId(pathInfo);
|
|
1175
1481
|
let intermediateIndex = cleanEquivalencyValueChain.length - i - 1;
|
|
1176
1482
|
const existingIntermediateIndex = databaseEntry.intermediatesOrder[pathId];
|