mirror of
https://github.com/morluto/rea
synced 2026-10-26 22:28:27 -04:00
fix(javascript): omit self-referential static references with disclosure (#1157)
* fix(javascript): omit self-referential static references with disclosure
A bundled module that requires its own key (`r(50)` inside webpack
module 50) resolved, through the static-reference composer, to its own
module node. The resulting self-referential imports edge failed result
validation and lost the entire analysis ("Result schema rejected 1
issue ... (custom)"). This is the same invariant as #1146; #1152 fixed
the bundler async-chunk composer, and this is the remaining adjacent
composer.
Skip a reference whose resolved target is its own source, count it, and
disclose the omission the way #1152 discloses async-chunk references.
Sibling requires are kept.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(javascript): share the self-reference omission disclosure
The self-import (#1130), async-chunk (#1152) and static-reference
disclosures repeated one sentence template in three composers, and the
new test repeated the analyze-and-check sequence of its neighbour. That
put jscpd at its 2.5% threshold. Share the template through
selfReferenceOmissions with identical wording, and share one test helper
for the graph-wide self-reference invariants.
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:
@@ -10,6 +10,7 @@ import {
|
||||
linkElectronRoleToAsset,
|
||||
moduleLookupKey,
|
||||
resolveArtifactPath,
|
||||
selfReferenceOmissions,
|
||||
sourceNodeFor,
|
||||
type JavaScriptArtifactGraphContext,
|
||||
type JavaScriptArtifactGraphCoverage,
|
||||
@@ -42,14 +43,15 @@ interface ResolvedReference {
|
||||
/** Project imports, workers, roles, endpoints, storage, and source-map links. */
|
||||
export const addJavaScriptStaticFindings = (
|
||||
context: JavaScriptArtifactGraphContext,
|
||||
): void => {
|
||||
): readonly string[] => {
|
||||
const omissions = { selfReferences: 0 };
|
||||
for (const analyzed of context.analysis.files) {
|
||||
const { file, javascript } = analyzed;
|
||||
const asset = context.assetNodes.get(file.path);
|
||||
if (javascript === null || asset === undefined) continue;
|
||||
const coverage = javascriptAnalysisCoverage(javascript);
|
||||
for (const value of javascript.references)
|
||||
addReference(context, { file, asset, value, coverage });
|
||||
addReference(context, { file, asset, value, coverage }, omissions);
|
||||
for (const value of javascript.endpoints)
|
||||
addEndpoint(context, { file, asset, value, coverage });
|
||||
for (const value of javascript.storage)
|
||||
@@ -59,11 +61,17 @@ export const addJavaScriptStaticFindings = (
|
||||
for (const value of javascript.source_map_urls)
|
||||
addSourceMapEdge(context, { file, asset, value, coverage });
|
||||
}
|
||||
return selfReferenceOmissions(
|
||||
omissions.selfReferences,
|
||||
["static reference", "static references"],
|
||||
"the referencing module",
|
||||
);
|
||||
};
|
||||
|
||||
const addReference = (
|
||||
context: JavaScriptArtifactGraphContext,
|
||||
input: FindingInput<StaticReference>,
|
||||
omissions: { selfReferences: number },
|
||||
): void => {
|
||||
const source =
|
||||
sourceNodeFor(context, input.file.path, input.value.module_key) ??
|
||||
@@ -119,6 +127,13 @@ const addReference = (
|
||||
});
|
||||
return;
|
||||
}
|
||||
// A reference that resolves to its own source, such as a bundled module
|
||||
// requiring its own key, cannot become an edge: the application graph
|
||||
// forbids self-referential edges and one would fail the whole analysis.
|
||||
if (resolved?.node.node_id === source.node_id) {
|
||||
omissions.selfReferences += 1;
|
||||
return;
|
||||
}
|
||||
const target =
|
||||
resolved?.node ??
|
||||
unresolvedReferenceNode(context, input.file, input.value, input.coverage);
|
||||
|
||||
Reference in New Issue
Block a user