Skip to content

Commit 80cb7a9

Browse files
authored
Revert "[compiler] Fix VariableDeclarator source location (#35129)" (#35346)
This broke main.
1 parent 894bc73 commit 80cb7a9

File tree

174 files changed

+398
-459
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+398
-459
lines changed

compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4026,7 +4026,6 @@ function lowerAssignment(
40264026
pattern: {
40274027
kind: 'ArrayPattern',
40284028
items,
4029-
loc: lvalue.node.loc ?? GeneratedSource,
40304029
},
40314030
},
40324031
value,
@@ -4204,7 +4203,6 @@ function lowerAssignment(
42044203
pattern: {
42054204
kind: 'ObjectPattern',
42064205
properties,
4207-
loc: lvalue.node.loc ?? GeneratedSource,
42084206
},
42094207
},
42104208
value,

compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -694,13 +694,11 @@ export type SpreadPattern = {
694694
export type ArrayPattern = {
695695
kind: 'ArrayPattern';
696696
items: Array<Place | SpreadPattern | Hole>;
697-
loc: SourceLocation;
698697
};
699698

700699
export type ObjectPattern = {
701700
kind: 'ObjectPattern';
702701
properties: Array<ObjectProperty | SpreadPattern>;
703-
loc: SourceLocation;
704702
};
705703

706704
export type ObjectPropertyKey =

compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,6 @@ function emitDestructureProps(
515515
pattern: {
516516
kind: 'ObjectPattern',
517517
properties,
518-
loc: GeneratedSource,
519518
},
520519
kind: InstructionKind.Let,
521520
},

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts

Lines changed: 8 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ function codegenReactiveScope(
702702
outputComments.push(name.name);
703703
if (!cx.hasDeclared(identifier)) {
704704
statements.push(
705-
t.variableDeclaration('let', [createVariableDeclarator(name, null)]),
705+
t.variableDeclaration('let', [t.variableDeclarator(name)]),
706706
);
707707
}
708708
cacheLoads.push({name, index, value: wrapCacheDep(cx, name)});
@@ -1387,7 +1387,7 @@ function codegenInstructionNullable(
13871387
suggestions: null,
13881388
});
13891389
return createVariableDeclaration(instr.loc, 'const', [
1390-
createVariableDeclarator(codegenLValue(cx, lvalue), value),
1390+
t.variableDeclarator(codegenLValue(cx, lvalue), value),
13911391
]);
13921392
}
13931393
case InstructionKind.Function: {
@@ -1451,7 +1451,7 @@ function codegenInstructionNullable(
14511451
suggestions: null,
14521452
});
14531453
return createVariableDeclaration(instr.loc, 'let', [
1454-
createVariableDeclarator(codegenLValue(cx, lvalue), value),
1454+
t.variableDeclarator(codegenLValue(cx, lvalue), value),
14551455
]);
14561456
}
14571457
case InstructionKind.Reassign: {
@@ -1691,9 +1691,6 @@ function withLoc<T extends (...args: Array<any>) => t.Node>(
16911691
};
16921692
}
16931693

1694-
const createIdentifier = withLoc(t.identifier);
1695-
const createArrayPattern = withLoc(t.arrayPattern);
1696-
const createObjectPattern = withLoc(t.objectPattern);
16971694
const createBinaryExpression = withLoc(t.binaryExpression);
16981695
const createExpressionStatement = withLoc(t.expressionStatement);
16991696
const _createLabelledStatement = withLoc(t.labeledStatement);
@@ -1725,31 +1722,6 @@ const createTryStatement = withLoc(t.tryStatement);
17251722
const createBreakStatement = withLoc(t.breakStatement);
17261723
const createContinueStatement = withLoc(t.continueStatement);
17271724

1728-
function createVariableDeclarator(
1729-
id: t.LVal,
1730-
init?: t.Expression | null,
1731-
): t.VariableDeclarator {
1732-
const node = t.variableDeclarator(id, init);
1733-
1734-
/*
1735-
* The variable declarator location is not preserved in HIR, however, we can use the
1736-
* start location of the id and the end location of the init to recreate the
1737-
* exact original variable declarator location.
1738-
*
1739-
* Or if init is null, we likely have a declaration without an initializer, so we can use the id.loc.end as the end location.
1740-
*/
1741-
if (id.loc && (init === null || init?.loc)) {
1742-
node.loc = {
1743-
start: id.loc.start,
1744-
end: init?.loc?.end ?? id.loc.end,
1745-
filename: id.loc.filename,
1746-
identifierName: undefined,
1747-
};
1748-
}
1749-
1750-
return node;
1751-
}
1752-
17531725
function createHookGuard(
17541726
guard: ExternalFunction,
17551727
context: ProgramContext,
@@ -1857,7 +1829,7 @@ function codegenInstruction(
18571829
);
18581830
} else {
18591831
return createVariableDeclaration(instr.loc, 'const', [
1860-
createVariableDeclarator(
1832+
t.variableDeclarator(
18611833
convertIdentifier(instr.lvalue.identifier),
18621834
expressionValue,
18631835
),
@@ -2784,7 +2756,7 @@ function codegenArrayPattern(
27842756
): t.ArrayPattern {
27852757
const hasHoles = !pattern.items.every(e => e.kind !== 'Hole');
27862758
if (hasHoles) {
2787-
const result = createArrayPattern(pattern.loc, []);
2759+
const result = t.arrayPattern([]);
27882760
/*
27892761
* Older versions of babel have a validation bug fixed by
27902762
* https://github.com/babel/babel/pull/10917
@@ -2805,8 +2777,7 @@ function codegenArrayPattern(
28052777
}
28062778
return result;
28072779
} else {
2808-
return createArrayPattern(
2809-
pattern.loc,
2780+
return t.arrayPattern(
28102781
pattern.items.map(item => {
28112782
if (item.kind === 'Hole') {
28122783
return null;
@@ -2826,8 +2797,7 @@ function codegenLValue(
28262797
return codegenArrayPattern(cx, pattern);
28272798
}
28282799
case 'ObjectPattern': {
2829-
return createObjectPattern(
2830-
pattern.loc,
2800+
return t.objectPattern(
28312801
pattern.properties.map(property => {
28322802
if (property.kind === 'ObjectProperty') {
28332803
const key = codegenObjectPropertyKey(cx, property.key);
@@ -2946,7 +2916,7 @@ function convertIdentifier(identifier: Identifier): t.Identifier {
29462916
suggestions: null,
29472917
},
29482918
);
2949-
return createIdentifier(identifier.loc, identifier.name.value);
2919+
return t.identifier(identifier.name.value);
29502920
}
29512921

29522922
function compareScopeDependency(

compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateSourceLocations.ts

Lines changed: 26 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,7 @@ import {Result} from '../Utils/Result';
2727

2828
/**
2929
* Some common node types that are important for coverage tracking.
30-
* Based on istanbul-lib-instrument + some other common nodes we expect to be present in the generated AST.
31-
*
32-
* Note: For VariableDeclaration, VariableDeclarator, and Identifier, we enforce stricter validation
33-
* that requires both the source location AND node type to match in the generated AST. This ensures
34-
* that variable declarations maintain their structural integrity through compilation.
30+
* Based on istanbul-lib-instrument
3531
*/
3632
const IMPORTANT_INSTRUMENTED_TYPES = new Set([
3733
'ArrowFunctionExpression',
@@ -58,14 +54,6 @@ const IMPORTANT_INSTRUMENTED_TYPES = new Set([
5854
'LabeledStatement',
5955
'ConditionalExpression',
6056
'LogicalExpression',
61-
62-
/**
63-
* Note: these aren't important for coverage tracking,
64-
* but we still want to track them to ensure we aren't regressing them when
65-
* we fix the source location tracking for other nodes.
66-
*/
67-
'VariableDeclaration',
68-
'Identifier',
6957
]);
7058

7159
/**
@@ -126,13 +114,10 @@ export function validateSourceLocations(
126114
): Result<void, CompilerError> {
127115
const errors = new CompilerError();
128116

129-
/*
130-
* Step 1: Collect important locations from the original source
131-
* Note: Multiple node types can share the same location (e.g. VariableDeclarator and Identifier)
132-
*/
117+
// Step 1: Collect important locations from the original source
133118
const importantOriginalLocations = new Map<
134119
string,
135-
{loc: t.SourceLocation; nodeTypes: Set<string>}
120+
{loc: t.SourceLocation; nodeType: string}
136121
>();
137122

138123
func.traverse({
@@ -152,31 +137,20 @@ export function validateSourceLocations(
152137
// Collect the location if it exists
153138
if (node.loc) {
154139
const key = locationKey(node.loc);
155-
const existing = importantOriginalLocations.get(key);
156-
if (existing) {
157-
existing.nodeTypes.add(node.type);
158-
} else {
159-
importantOriginalLocations.set(key, {
160-
loc: node.loc,
161-
nodeTypes: new Set([node.type]),
162-
});
163-
}
140+
importantOriginalLocations.set(key, {
141+
loc: node.loc,
142+
nodeType: node.type,
143+
});
164144
}
165145
},
166146
});
167147

168-
// Step 2: Collect all locations from the generated AST with their node types
169-
const generatedLocations = new Map<string, Set<string>>();
148+
// Step 2: Collect all locations from the generated AST
149+
const generatedLocations = new Set<string>();
170150

171151
function collectGeneratedLocations(node: t.Node): void {
172152
if (node.loc) {
173-
const key = locationKey(node.loc);
174-
const nodeTypes = generatedLocations.get(key);
175-
if (nodeTypes) {
176-
nodeTypes.add(node.type);
177-
} else {
178-
generatedLocations.set(key, new Set([node.type]));
179-
}
153+
generatedLocations.add(locationKey(node.loc));
180154
}
181155

182156
// Use Babel's VISITOR_KEYS to traverse only actual node properties
@@ -209,86 +183,22 @@ export function validateSourceLocations(
209183
collectGeneratedLocations(outlined.fn.body);
210184
}
211185

212-
/*
213-
* Step 3: Validate that all important locations are preserved
214-
* For certain node types, also validate that the node type matches
215-
*/
216-
const strictNodeTypes = new Set([
217-
'VariableDeclaration',
218-
'VariableDeclarator',
219-
'Identifier',
220-
]);
221-
222-
const reportMissingLocation = (
223-
loc: t.SourceLocation,
224-
nodeType: string,
225-
): void => {
226-
errors.pushDiagnostic(
227-
CompilerDiagnostic.create({
228-
category: ErrorCategory.Todo,
229-
reason: 'Important source location missing in generated code',
230-
description:
231-
`Source location for ${nodeType} is missing in the generated output. This can cause coverage instrumentation ` +
232-
`to fail to track this code properly, resulting in inaccurate coverage reports.`,
233-
}).withDetails({
234-
kind: 'error',
235-
loc,
236-
message: null,
237-
}),
238-
);
239-
};
240-
241-
const reportWrongNodeType = (
242-
loc: t.SourceLocation,
243-
expectedType: string,
244-
actualTypes: Set<string>,
245-
): void => {
246-
errors.pushDiagnostic(
247-
CompilerDiagnostic.create({
248-
category: ErrorCategory.Todo,
249-
reason:
250-
'Important source location has wrong node type in generated code',
251-
description:
252-
`Source location for ${expectedType} exists in the generated output but with wrong node type(s): ${Array.from(actualTypes).join(', ')}. ` +
253-
`This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.`,
254-
}).withDetails({
255-
kind: 'error',
256-
loc,
257-
message: null,
258-
}),
259-
);
260-
};
261-
262-
for (const [key, {loc, nodeTypes}] of importantOriginalLocations) {
263-
const generatedNodeTypes = generatedLocations.get(key);
264-
265-
if (!generatedNodeTypes) {
266-
// Location is completely missing
267-
reportMissingLocation(loc, Array.from(nodeTypes).join(', '));
268-
} else {
269-
// Location exists, check each node type
270-
for (const nodeType of nodeTypes) {
271-
if (
272-
strictNodeTypes.has(nodeType) &&
273-
!generatedNodeTypes.has(nodeType)
274-
) {
275-
/*
276-
* For strict node types, the specific node type must be present
277-
* Check if any generated node type is also an important original node type
278-
*/
279-
const hasValidNodeType = Array.from(generatedNodeTypes).some(
280-
genType => nodeTypes.has(genType),
281-
);
282-
283-
if (hasValidNodeType) {
284-
// At least one generated node type is valid (also in original), so this is just missing
285-
reportMissingLocation(loc, nodeType);
286-
} else {
287-
// None of the generated node types are in original - this is wrong node type
288-
reportWrongNodeType(loc, nodeType, generatedNodeTypes);
289-
}
290-
}
291-
}
186+
// Step 3: Validate that all important locations are preserved
187+
for (const [key, {loc, nodeType}] of importantOriginalLocations) {
188+
if (!generatedLocations.has(key)) {
189+
errors.pushDiagnostic(
190+
CompilerDiagnostic.create({
191+
category: ErrorCategory.Todo,
192+
reason: 'Important source location missing in generated code',
193+
description:
194+
`Source location for ${nodeType} is missing in the generated output. This can cause coverage instrumentation ` +
195+
`to fail to track this code properly, resulting in inaccurate coverage reports.`,
196+
}).withDetails({
197+
kind: 'error',
198+
loc,
199+
message: null,
200+
}),
201+
);
292202
}
293203
}
294204

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/alias-capture-in-method-receiver-and-mutate.expect.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ function Component() {
3535
let t0;
3636
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
3737
const a = makeObject_Primitives();
38+
3839
const x = [];
3940
x.push(a);
41+
4042
mutate(x);
4143
t0 = [x, a];
4244
$[0] = t0;

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/alias-capture-in-method-receiver.expect.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ function Component() {
3333
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
3434
const x = [];
3535
x.push(a);
36+
3637
t1 = [x, a];
3738
$[1] = t1;
3839
} else {

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-fn-expr.expect.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,14 @@ function Component(t0) {
8585
let t1;
8686
if ($[0] !== prop) {
8787
const obj = shallowCopy(prop);
88+
8889
const aliasedObj = identity(obj);
90+
8991
const getId = () => obj.id;
92+
9093
mutate(aliasedObj);
9194
setPropertyByKey(aliasedObj, "id", prop.id + 1);
95+
9296
t1 = <Stringify getId={getId} shouldInvokeFns={true} />;
9397
$[0] = prop;
9498
$[1] = t1;

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-truncated-dep.expect.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,12 @@ function Component(t0) {
181181
if ($[0] !== prop) {
182182
const obj = shallowCopy(prop);
183183
const aliasedObj = identity(obj);
184+
184185
const id = [obj.id];
186+
185187
mutate(aliasedObj);
186188
setPropertyByKey(aliasedObj, "id", prop.id + 1);
189+
187190
t1 = <Stringify id={id} />;
188191
$[0] = prop;
189192
$[1] = t1;

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/align-scopes-within-nested-valueblock-in-array.expect.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ function Foo(t0) {
5454
let t1;
5555
if ($[0] !== cond1 || $[1] !== cond2) {
5656
const arr = makeArray({ a: 2 }, 2, []);
57+
5758
t1 = cond1 ? (
5859
<>
5960
<div>{identity("foo")}</div>

0 commit comments

Comments
 (0)