mirror of
https://github.com/morluto/rea.git
synced 2026-10-28 10:25:42 +00:00
fix(javascript): preserve analysis applicability after interruption (#4207)
Preserve applicable artifact processing phases and entered/unvisited status after interruption. Centralize JavaScript semantic applicability for full and incremental builders; retain native byte identity, actual JavaScript unknowns and structured-file provenance. Fixes #3948. Part of #4027. Validation:78 distinct focused cases across10files, full static/docs, and real Joplin timeout/default public CLI/MCP controls passed. Source pins, every attempt/outlier and compact resource/token projections are retained. No target/native provider execution or speedup claim. Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
This commit is contained in:
1 parent
663d07f02c
commit
85eac7b92b
18 files changed
+3717
-93
No files matched your search
@@ -22,6 +22,8 @@ import type {
|
||||
} from "../../domain/javascript/javascriptArtifactFiles.js";
|
||||
import type {
|
||||
AnalyzedJavaScriptArtifactFile,
|
||||
JavaScriptArtifactAnalysisFailure,
|
||||
JavaScriptArtifactAnalysisScope,
|
||||
JavaScriptArtifactAnalysis,
|
||||
JavaScriptModuleArtifactAnalysis,
|
||||
JavaScriptModuleSemanticIr,
|
||||
@@ -32,6 +34,7 @@ import type {
|
||||
JavaScriptSourceMapObservation,
|
||||
JavaScriptSourceMapOriginal,
|
||||
} from "./JavaScriptArtifactAnalysisTypes.js";
|
||||
import { javascriptArtifactAnalysisScopes } from "./JavaScriptArtifactAnalysisTypes.js";
|
||||
import { analyzeJavaScriptJsonModule } from "./JavaScriptJsonModules.js";
|
||||
import { completeJavaScriptAnalysisSteps } from "./JavaScriptAnalysisControl.js";
|
||||
import { htmlArtifactReferences } from "../../domain/javascript/htmlArtifactReferences.js";
|
||||
@@ -141,6 +144,7 @@ export const analyzeAndAdoptJavaScriptArtifactFiles = async (
|
||||
fileSet.files.length - (fileSet.source_selection?.unselected_files ?? 0);
|
||||
let selectedFileIndex = 0;
|
||||
for (const file of fileSet.files) {
|
||||
let analysisStarted = false;
|
||||
try {
|
||||
await setImmediate();
|
||||
if (classifyOutsideAnalysisScope(file, state, projection)) {
|
||||
@@ -155,6 +159,7 @@ export const analyzeAndAdoptJavaScriptArtifactFiles = async (
|
||||
if (signal?.aborted === true)
|
||||
throw new AnalysisCancelledError("analyze_javascript_application");
|
||||
await beforeFile(file, selectedFileIndex++, selectedFileCount);
|
||||
analysisStarted = true;
|
||||
if (file.kind !== "javascript" || !file.text.included) {
|
||||
const steps = analyzeArtifactFileSteps(file, {
|
||||
state,
|
||||
@@ -182,10 +187,12 @@ export const analyzeAndAdoptJavaScriptArtifactFiles = async (
|
||||
: error instanceof AnalysisTimeoutError
|
||||
? { worker_timeout_ms: error.timeoutMs }
|
||||
: null;
|
||||
const failure =
|
||||
const failure: JavaScriptArtifactAnalysisFailure | undefined =
|
||||
error === null
|
||||
? undefined
|
||||
: {
|
||||
scope: javascriptArtifactAnalysisScopes.javascript,
|
||||
status: "interrupted",
|
||||
reason: `${file.path}: ${error.message}`,
|
||||
error: projectAnalysisError(error),
|
||||
limits,
|
||||
@@ -245,15 +252,22 @@ export const analyzeAndAdoptJavaScriptArtifactFiles = async (
|
||||
? cause
|
||||
: null;
|
||||
if (interruption !== null) {
|
||||
const scope = javascriptArtifactAnalysisScopes[file.kind];
|
||||
state.files.push({
|
||||
file,
|
||||
javascript: null,
|
||||
semantic: null,
|
||||
analysis_failure: {
|
||||
reason: `${file.path}: ${interruption.message}`,
|
||||
error: projectAnalysisError(interruption),
|
||||
limits: null,
|
||||
},
|
||||
...(scope === null
|
||||
? {}
|
||||
: {
|
||||
analysis_failure: {
|
||||
scope,
|
||||
status: analysisStarted ? "interrupted" : "not-started",
|
||||
reason: `${file.path}: ${interruption.message}`,
|
||||
error: projectAnalysisError(interruption),
|
||||
limits: null,
|
||||
},
|
||||
}),
|
||||
});
|
||||
projection.recordUnavailableFile(
|
||||
file,
|
||||
@@ -277,25 +291,36 @@ export const analyzeAndAdoptJavaScriptArtifactFiles = async (
|
||||
? { worker_timeout_ms: interruption.timeoutMs }
|
||||
: null,
|
||||
};
|
||||
// This interruption has one cause. Share its immutable failure per phase
|
||||
// rather than copying it for every unvisited source in a large bundle.
|
||||
const failures = new Map<
|
||||
JavaScriptArtifactAnalysisScope,
|
||||
JavaScriptArtifactAnalysisFailure
|
||||
>();
|
||||
for (const file of fileSet.files) {
|
||||
if (analyzedPaths.has(file.path)) continue;
|
||||
if (classifyOutsideAnalysisScope(file, state, projection)) continue;
|
||||
const scope = javascriptArtifactAnalysisScopes[file.kind];
|
||||
let unavailable = scope === null ? undefined : failures.get(scope);
|
||||
if (scope !== null && unavailable === undefined) {
|
||||
unavailable = { ...failure, scope, status: "not-started" };
|
||||
failures.set(scope, unavailable);
|
||||
}
|
||||
state.files.push({
|
||||
file,
|
||||
javascript: null,
|
||||
semantic: null,
|
||||
analysis_failure: failure,
|
||||
...(unavailable === undefined ? {} : { analysis_failure: unavailable }),
|
||||
});
|
||||
if (file.kind === "javascript")
|
||||
projection.recordUnavailableFile(
|
||||
file,
|
||||
failure.reason,
|
||||
failure.limits,
|
||||
interruption instanceof AnalysisResourceConstraintError ||
|
||||
interruption instanceof AnalysisTimeoutError
|
||||
? "resource-limit"
|
||||
: "incomplete-module",
|
||||
);
|
||||
projection.recordUnavailableFile(
|
||||
file,
|
||||
failure.reason,
|
||||
failure.limits,
|
||||
interruption instanceof AnalysisResourceConstraintError ||
|
||||
interruption instanceof AnalysisTimeoutError
|
||||
? "resource-limit"
|
||||
: "incomplete-module",
|
||||
);
|
||||
}
|
||||
}
|
||||
return { analysis: finalizeArtifactAnalysis(state), interruption };
|
||||
@@ -423,13 +448,12 @@ const classifyOutsideAnalysisScope = <
|
||||
if (file.text.included || file.text.reason !== "outside-analysis-scope")
|
||||
return false;
|
||||
state.files.push({ file, javascript: null, semantic: null });
|
||||
if (file.kind === "javascript")
|
||||
projection?.recordUnavailableFile(
|
||||
file,
|
||||
"Source was not analyzed because it is outside the caller-selected source_paths.",
|
||||
null,
|
||||
"incomplete-module",
|
||||
);
|
||||
projection?.recordUnavailableFile(
|
||||
file,
|
||||
"Source was not analyzed because it is outside the caller-selected source_paths.",
|
||||
null,
|
||||
"incomplete-module",
|
||||
);
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user