fix(javascript): keep exact empty require paths and request fields
Migrate the remaining `""`-sentinel consumers from #783 to the nullable `semanticStaticPropertyKey`: CommonJS module origins (`require("m")['']`), require destructuring (`const {'': a} = require("m")`), and request body fields (`{ '': value }`). Dynamic keys still produce no link or field. API selectors that compare against known names are unchanged. Fixes #783 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
f7954a8fd6
commit
ad1f6b508f
|
|
@ -55,3 +55,51 @@ it("retains exact empty method names and environment keys", () => {
|
|||
{ kind: "environment", key: null, resolution: "partial" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("retains exact empty require paths without dynamic-key links", () => {
|
||||
const ir = analyzeJavaScriptSemantics(`
|
||||
const { '': fromPattern } = require("./table.js");
|
||||
const fromMember = require("./table.js")[''];
|
||||
const { [key]: dynamicPattern } = require("./table.js");
|
||||
const dynamicMember = require("./table.js")[key];
|
||||
module.exports.root = require("./table.js")[''];
|
||||
`);
|
||||
expect(
|
||||
ir.moduleLinks.map(({ kind, importedName, localName, exportedName }) => ({
|
||||
kind,
|
||||
importedName,
|
||||
localName,
|
||||
exportedName,
|
||||
})),
|
||||
).toEqual([
|
||||
{
|
||||
kind: "require",
|
||||
importedName: "",
|
||||
localName: "fromPattern",
|
||||
exportedName: null,
|
||||
},
|
||||
{
|
||||
kind: "require",
|
||||
importedName: "",
|
||||
localName: "fromMember",
|
||||
exportedName: null,
|
||||
},
|
||||
{
|
||||
kind: "commonjs-export",
|
||||
importedName: "",
|
||||
localName: null,
|
||||
exportedName: "root",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("retains exact empty request field names without dynamic fields", () => {
|
||||
const ir = analyzeJavaScriptSemantics(`
|
||||
fetch("https://example.test", { '': value, [key]: 1, body: "x" });
|
||||
`);
|
||||
expect(
|
||||
ir.requestOperations.flatMap(({ fields }) =>
|
||||
fields.map(({ name }) => name),
|
||||
),
|
||||
).toEqual(["", "body"]);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -405,8 +405,8 @@ const requestFields = (
|
|||
if (!t.isObjectProperty(property)) return [];
|
||||
// `{[key]: 1}` sends no knowable field name; reporting `key` would invent
|
||||
// a request field that may not exist.
|
||||
const name = semanticStaticPropertyName(property.key, property.computed);
|
||||
if (name.length === 0) return [];
|
||||
const name = semanticStaticPropertyKey(property.key, property.computed);
|
||||
if (name === null) return [];
|
||||
return [
|
||||
{
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -25,10 +25,7 @@ import {
|
|||
range,
|
||||
stringValue,
|
||||
} from "./javascriptStaticAnalysisHelpers.js";
|
||||
import {
|
||||
semanticStaticPropertyKey,
|
||||
semanticStaticPropertyName,
|
||||
} from "./javascriptAstValues.js";
|
||||
import { semanticStaticPropertyKey } from "./javascriptAstValues.js";
|
||||
|
||||
interface CollectCallableInput {
|
||||
readonly node: t.Node;
|
||||
|
|
@ -181,8 +178,8 @@ const semanticModuleOrigin = (
|
|||
const nested = t.isNode(node.object)
|
||||
? semanticModuleOrigin(node.object, projection, state)
|
||||
: undefined;
|
||||
const member = semanticStaticPropertyName(node.property, node.computed);
|
||||
return nested === undefined || member === ""
|
||||
const member = semanticStaticPropertyKey(node.property, node.computed);
|
||||
return nested === undefined || member === null
|
||||
? undefined
|
||||
: { ...nested, importedPath: [...nested.importedPath, member] };
|
||||
}
|
||||
|
|
@ -341,8 +338,8 @@ const requirePatternBindings = (
|
|||
if (t.isObjectPattern(pattern))
|
||||
return pattern.properties.flatMap((property) => {
|
||||
if (t.isRestElement(property)) return [];
|
||||
const name = semanticStaticPropertyName(property.key, property.computed);
|
||||
return name === ""
|
||||
const name = semanticStaticPropertyKey(property.key, property.computed);
|
||||
return name === null
|
||||
? []
|
||||
: requirePatternBindings(property.value, [...path, name]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue