fix(javascript): yield inside semantic analysis and large projection passes (#1542)
* fix(javascript): yield inside semantic analysis and large projection passes After #1525 the longest event-loop blocks were single stages on very large files: semantic analysis of Obsidian's 3.7 MB app.js ran 5.8 s in one piece, and its object projection 1.8 s. - analyzeParsedJavaScriptSemanticsSteps yields between the analysis phases and between the eight derived collectors; the synchronous function drains it, so results are unchanged. - Per-file analysis yields between open-receiver classification and static analysis and drives the semantic steps. - Semantic node creation, definitions and references, and the object and frontier passes yield every 64 items. Node creation keeps source order, which the per-file node budget depends on. On obsidian.asar the longest block falls from 5,355 ms to 907 ms with the same total time (40.6 s to 39.5 s). Graph IDs and complete result digests match main on five inputs. Remaining blocks up to about 0.9 s are single AST traversal passes inside the analyzers. Refs #1462 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(javascript): drop the unused synchronous derived-semantics wrapper Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b9c439831d
commit
ca7ef69c0c
7 files changed
+150
-62
No files matched your search
@@ -38,7 +38,7 @@ import {
|
||||
collectSemanticReturns,
|
||||
resolveSemanticModuleCallables,
|
||||
} from "./javascriptSemanticReturns.js";
|
||||
import { collectJavaScriptDerivedSemantics } from "./javascriptSemanticDerivedAnalysis.js";
|
||||
import { collectJavaScriptDerivedSemanticsSteps } from "./javascriptSemanticDerivedAnalysis.js";
|
||||
import { range } from "./javascriptStaticAnalysisHelpers.js";
|
||||
import { propertyName } from "./javascriptAstValues.js";
|
||||
import { semanticCoverage } from "./javascriptSemanticCoverage.js";
|
||||
@@ -107,18 +107,40 @@ export const analyzeParsedJavaScriptReferences = (
|
||||
export const analyzeParsedJavaScriptSemantics = (
|
||||
file: ParsedJavaScriptSource,
|
||||
): JavaScriptSemanticIr => {
|
||||
const steps = analyzeParsedJavaScriptSemanticsSteps(file);
|
||||
for (;;) {
|
||||
const step = steps.next();
|
||||
if (step.done === true) return step.value;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Recover semantics from a parsed artifact with a yield between analysis
|
||||
* phases, so a caller can serve control messages within one large file.
|
||||
* Each phase completes before the next starts; results equal the synchronous
|
||||
* form.
|
||||
*/
|
||||
export function* analyzeParsedJavaScriptSemanticsSteps(
|
||||
file: ParsedJavaScriptSource,
|
||||
): Generator<void, JavaScriptSemanticIr> {
|
||||
const state = createState(file.program);
|
||||
collectDefinitions(file.program, state);
|
||||
yield;
|
||||
collectSemanticMemberMutations(file.program, state);
|
||||
yield;
|
||||
traverseJavaScriptAst(file.program, {
|
||||
enter: (node) => collectSemanticModuleLink(node, state),
|
||||
});
|
||||
yield;
|
||||
const references = collectSemanticReferences(file.program, state);
|
||||
yield;
|
||||
const parserPartial = file.errors.length > 0;
|
||||
const bindings = immutableSemanticBindings(state);
|
||||
yield;
|
||||
const callables = collectSemanticReturns(file.program, state, parserPartial);
|
||||
yield;
|
||||
const moduleLinks = resolveSemanticModuleCallables(state, callables);
|
||||
const derived = collectJavaScriptDerivedSemantics(
|
||||
const derived = yield* collectJavaScriptDerivedSemanticsSteps(
|
||||
file.program,
|
||||
state,
|
||||
callables,
|
||||
@@ -154,7 +176,7 @@ export const analyzeParsedJavaScriptSemantics = (
|
||||
"Cross-function mutation and dynamic property resolution remain unknown.",
|
||||
],
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/** Receiver identity facts for the overloaded `.open` syntax only. */
|
||||
export type JavaScriptOpenReceiverFact =
|
||||
|
||||
Reference in new issue
Block a user