Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a8efb8226 |
No files matched your search
@@ -143,25 +143,27 @@ export const analyzeAndAdoptJavaScriptArtifactFiles = async (
|
|||||||
const selectedFileCount =
|
const selectedFileCount =
|
||||||
fileSet.files.length - (fileSet.source_selection?.unselected_files ?? 0);
|
fileSet.files.length - (fileSet.source_selection?.unselected_files ?? 0);
|
||||||
let selectedFileIndex = 0;
|
let selectedFileIndex = 0;
|
||||||
|
// Caller-excluded sources are never analyzed, so neither cancellation nor
|
||||||
|
// another interruption describes them.
|
||||||
|
const recordOutsideSelection = (file: JavaScriptArtifactFile): boolean => {
|
||||||
|
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",
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
for (const file of fileSet.files) {
|
for (const file of fileSet.files) {
|
||||||
try {
|
try {
|
||||||
await setImmediate();
|
await setImmediate();
|
||||||
if (signal?.aborted === true)
|
if (signal?.aborted === true)
|
||||||
throw new AnalysisCancelledError("analyze_javascript_application");
|
throw new AnalysisCancelledError("analyze_javascript_application");
|
||||||
if (
|
if (recordOutsideSelection(file)) continue;
|
||||||
!file.text.included &&
|
|
||||||
file.text.reason === "outside-analysis-scope"
|
|
||||||
) {
|
|
||||||
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",
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
await beforeFile(file, selectedFileIndex++, selectedFileCount);
|
await beforeFile(file, selectedFileIndex++, selectedFileCount);
|
||||||
if (file.kind !== "javascript" || !file.text.included) {
|
if (file.kind !== "javascript" || !file.text.included) {
|
||||||
const steps = analyzeArtifactFileSteps(file, {
|
const steps = analyzeArtifactFileSteps(file, {
|
||||||
@@ -252,7 +254,7 @@ export const analyzeAndAdoptJavaScriptArtifactFiles = async (
|
|||||||
: cause instanceof AnalysisError
|
: cause instanceof AnalysisError
|
||||||
? cause
|
? cause
|
||||||
: null;
|
: null;
|
||||||
if (interruption !== null) {
|
if (interruption !== null && !recordOutsideSelection(file)) {
|
||||||
state.files.push({
|
state.files.push({
|
||||||
file,
|
file,
|
||||||
javascript: null,
|
javascript: null,
|
||||||
@@ -286,21 +288,8 @@ export const analyzeAndAdoptJavaScriptArtifactFiles = async (
|
|||||||
: null,
|
: null,
|
||||||
};
|
};
|
||||||
for (const file of fileSet.files) {
|
for (const file of fileSet.files) {
|
||||||
if (analyzedPaths.has(file.path)) continue;
|
if (analyzedPaths.has(file.path) || recordOutsideSelection(file))
|
||||||
if (
|
|
||||||
!file.text.included &&
|
|
||||||
file.text.reason === "outside-analysis-scope"
|
|
||||||
) {
|
|
||||||
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",
|
|
||||||
);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
state.files.push({
|
state.files.push({
|
||||||
file,
|
file,
|
||||||
javascript: null,
|
javascript: null,
|
||||||
|
|||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
import { expect, it } from "vitest";
|
||||||
|
|
||||||
|
import { analyzeAndAdoptJavaScriptArtifactFiles } from "../../../../src/application/javascript/JavaScriptArtifactAnalysis.js";
|
||||||
|
import { createJavaScriptSemanticGraphProjection } from "../../../../src/application/javascript/JavaScriptSemanticGraphBuilder.js";
|
||||||
|
import { readJavaScriptArtifactFiles } from "../../../../src/artifacts/javascript/JavaScriptArtifactFiles.js";
|
||||||
|
import { createJavaScriptArtifactReader } from "../../../../src/artifacts/javascript/JavaScriptArtifactReader.js";
|
||||||
|
import { createJavaScriptSourceAnalysis } from "../../../../src/artifacts/javascript/JavaScriptSourceAnalysis.js";
|
||||||
|
import { JAVASCRIPT_ANALYSIS_RESOURCE_DEFAULTS } from "../../../../src/domain/javascript/javascriptAnalysisResourceControls.js";
|
||||||
|
import {
|
||||||
|
scanCanonicalArtifactInventory,
|
||||||
|
withArtifactResourceScope,
|
||||||
|
} from "../../../fixtures/artifactInventory.js";
|
||||||
|
import { writeJavaScriptSourceSelectionFixture } from "../../../fixtures/javascriptSourceSelection.js";
|
||||||
|
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
|
||||||
|
|
||||||
|
it("keeps unselected sources outside the selection when cancellation follows the last selected source", async () => {
|
||||||
|
const root = await createTestTempDirectory("rea-js-selected-late-cancel-");
|
||||||
|
await writeJavaScriptSourceSelectionFixture(root);
|
||||||
|
const snapshot = await scanCanonicalArtifactInventory(root, {});
|
||||||
|
const reader = createJavaScriptArtifactReader(root, "directory");
|
||||||
|
const worker = createJavaScriptSourceAnalysis(
|
||||||
|
JAVASCRIPT_ANALYSIS_RESOURCE_DEFAULTS,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
const files = await withArtifactResourceScope((scope) =>
|
||||||
|
readJavaScriptArtifactFiles(reader, snapshot, scope, undefined, [
|
||||||
|
"main.mjs",
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
const controller = new AbortController();
|
||||||
|
// Cancel after the only selected source completes, before the loop
|
||||||
|
// reaches the first unselected source.
|
||||||
|
const { analysis, interruption } =
|
||||||
|
await analyzeAndAdoptJavaScriptArtifactFiles(
|
||||||
|
files,
|
||||||
|
{
|
||||||
|
analyze: async (file, budget, signal) => {
|
||||||
|
const result = await worker.analyze(file, budget, signal);
|
||||||
|
controller.abort();
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
createJavaScriptSemanticGraphProjection(),
|
||||||
|
async () => {},
|
||||||
|
controller.signal,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(interruption?._tag).toBe("AnalysisCancelledError");
|
||||||
|
const unselected = analysis.files.filter(
|
||||||
|
({ file }) =>
|
||||||
|
!file.text.included && file.text.reason === "outside-analysis-scope",
|
||||||
|
);
|
||||||
|
expect(unselected).toHaveLength(5);
|
||||||
|
expect(
|
||||||
|
unselected.filter((entry) => entry.analysis_failure !== undefined),
|
||||||
|
).toEqual([]);
|
||||||
|
} finally {
|
||||||
|
await worker.close();
|
||||||
|
await reader.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in new issue
Block a user