mirror of
https://github.com/hanzoai/babel.git
synced 2026-09-24 16:56:45 +00:00
fix(code-frame): use 0-based columns to match Babel AST locations (#17316) `codeFrameColumns` treated the `column` property as 1-based, but Babel AST locations use 0-based columns. This caused the caret/underline to be off by one character when passing AST `.loc` objects directly. - Removed the `- 1` offset in marker spacing calculation - Removed the `+ 1` in multiline start marker count - Changed default column sentinel from `0` to `null` so that `column: 0` is treated as a valid position - Updated falsiness checks (`!startColumn`) to null checks - Removed `+ 1` workarounds in babel-core and babel-traverse callers This is a breaking change for external consumers of `@babel/code-frame` who passed 1-based columns manually.
46 lines
1.5 KiB
JavaScript
46 lines
1.5 KiB
JavaScript
import { codeFrameColumns } from "@babel/code-frame";
|
|
import { runInThisContext } from "node:vm";
|
|
|
|
export default function toContextualSyntaxError(
|
|
error,
|
|
source,
|
|
filename,
|
|
options,
|
|
) {
|
|
if (!(error instanceof SyntaxError)) return error;
|
|
|
|
const { startLine = 1, startColumn = 0 } = options || {};
|
|
const line = error.loc.line - startLine + 1;
|
|
const column = line === 1 ? error.loc.column - startColumn : error.loc.column;
|
|
const frame = codeFrameColumns(
|
|
source,
|
|
{ start: { line, column } },
|
|
{ highlightCode: true },
|
|
);
|
|
|
|
// We make this a lazy property since we don't want pay the price of creating
|
|
// this new error unless we are going to display it.
|
|
Object.defineProperty(error, "context", {
|
|
get() {
|
|
const message = JSON.stringify(`${error.message}\n${frame}`);
|
|
const originalStackTraceLimit = Error.stackTraceLimit;
|
|
|
|
// Limit this stack trace to 1. Everything after that is just stuff from
|
|
// the test.
|
|
Error.stackTraceLimit = 1;
|
|
|
|
// The only way to manipulate the file in which a SyntaxError reports it
|
|
// is coming from is to roundtrip through vm.runInThisContext. If v8
|
|
// supported Firefox's non-standard Error.fileName property, that could be
|
|
// used instead, but unfortunately it does not.
|
|
const context = runInThisContext(`SyntaxError(${message})`, { filename });
|
|
|
|
Error.stackTraceLimit = originalStackTraceLimit;
|
|
|
|
return Object.assign(context, { cause: this });
|
|
},
|
|
});
|
|
|
|
return error;
|
|
}
|