Compare commits

..

2 Commits

Author SHA1 Message Date
Joe Savona
eaf36e3188 Update on "[compiler] Null out source locations where not explicitly preserved"
Inspired by #32950. Specifically from https://github.com/facebook/react/issues/32950#issuecomment-2837887871, it sounds like Babel by default emits source map information for all nodes, even when they don't have a `loc` property set. Code coverage tools then pick up the synthesized source location information for this, leading to the issue described.

A few google searches didn't turn up any documented way to opt-out of generating source span information, but AI tools answer that explicitly setting `node.loc = null` omits the node from source maps. This PR is a quick hack to confirm that.

[ghstack-poisoned]
2025-04-30 09:58:11 +09:00
Joe Savona
9db3f8b484 Update on "[compiler] Null out source locations where not explicitly preserved"
Inspired by #32950. Specifically from https://github.com/facebook/react/issues/32950#issuecomment-2837887871, it sounds like Babel by default emits source map information for all nodes, even when they don't have a `loc` property set. Code coverage tools then pick up the synthesized source location information for this, leading to the issue described.

A few google searches didn't turn up any documented way to opt-out of generating source span information, but AI tools answer that explicitly setting `node.loc = null` omits the node from source maps. This PR is a quick hack to confirm that.

[ghstack-poisoned]
2025-04-30 09:54:19 +09:00
6 changed files with 78 additions and 1 deletions

View File

@@ -2680,7 +2680,12 @@ function setMissingLocationsToNull(ast: any): void {
return;
}
if (ast['loc'] == null) {
ast['loc'] = null;
ast['loc'] = {
start: {line: null, column: null, index: null},
end: {line: null, column: null, index: null},
filename: null,
identifierName: null,
};
}
for (const key in ast) {
if (!hasOwnProperty(ast, key)) {

View File

@@ -0,0 +1,51 @@
## Input
```javascript
// @sourceMaps
export const Button = () => {
return <button>Click me</button>;
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @sourceMaps
export const Button = () => {
const $ = _c(1);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <button>Click me</button>;
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
};
```
## Source Map
```
{
"version": 3,
"names": [
"Button",
"t0"
],
"sources": [
"sourcemaps-simple.ts"
],
"sourcesContent": [
"// @sourceMaps\nexport const Button = () => {\n return <button>Click me</button>;\n};\n"
],
"mappings": "kDAAA;AACA,OAAO,MAAMA,MAAM,GAAGA,CAAA,K;SACb,OAAyB,CAAjB,QAAQ,EAAhB,MAAyB,C,qCAAzBC,EAAyB,C,CACjC",
"ignoreList": []
}
```
### Eval output
(kind: exception) Fixture not implemented

View File

@@ -0,0 +1,4 @@
// @sourceMaps
export const Button = () => {
return <button>Click me</button>;
};

View File

@@ -306,6 +306,7 @@ export type TransformResult = {
original: string;
forget: string;
} | null;
sourceMap: BabelCore.BabelFileResult['map'];
};
export async function transformFixtureInput(
@@ -331,6 +332,9 @@ export async function transformFixtureInput(
// with `cwd`, which is different across machines
const virtualFilepath = '/' + filename;
// Check if we should emit source maps in the test fixture
const includeSourceMaps = firstLine.includes('@sourceMaps');
const presets =
language === 'typescript'
? TypescriptEvaluatorPresets
@@ -357,6 +361,7 @@ export async function transformFixtureInput(
'babel-plugin-idx',
],
sourceType: 'module',
sourceMaps: includeSourceMaps,
ast: includeEvaluator,
cloneInputAst: includeEvaluator,
configFile: false,
@@ -447,6 +452,7 @@ export async function transformFixtureInput(
forgetOutput,
logs: formattedLogs,
evaluatorCode,
sourceMap: includeSourceMaps ? forgetResult.map : null,
},
};
}

View File

@@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import {BabelFileResult} from '@babel/core';
import chalk from 'chalk';
import fs from 'fs';
import invariant from 'invariant';
@@ -24,6 +25,7 @@ export function writeOutputToString(
evaluatorOutput: string | null,
logs: string | null,
errorMessage: string | null,
sourceMap: BabelFileResult['map'] | null,
) {
// leading newline intentional
let result = `
@@ -42,6 +44,14 @@ ${wrapWithTripleBackticks(compilerOutput, 'javascript')}
result += '\n';
}
if (sourceMap != null) {
result += `
## Source Map
${wrapWithTripleBackticks(JSON.stringify(sourceMap, null, 2))}
`;
}
if (logs != null) {
result += `
## Logs

View File

@@ -245,6 +245,7 @@ export async function transformFixture(
sproutOutput,
compileResult?.logs ?? null,
error,
compileResult?.sourceMap ?? null,
);
return {