Skip to content

Commit

Permalink
Add opts.message option to code frames (babel#7243)
Browse files Browse the repository at this point in the history
* Add opts.message option to code frames

* Fix for missing loc.start in code-frame

* Add docs
  • Loading branch information
jamiebuilds authored and aminmarashi committed Mar 17, 2018
1 parent e845a4a commit c447a8e
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 1 deletion.
16 changes: 16 additions & 0 deletions packages/babel-code-frame/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ console.log(result);

Toggles syntax highlighting the code as JavaScript for terminals.


### `linesAbove`

`number`, defaults to `2`.
Expand All @@ -86,6 +87,21 @@ Adjust the number of lines to show below the error.

Enable this to forcibly syntax highlight the code as JavaScript (for non-terminals); overrides `highlightCode`.

### `message`

`string`, otherwise nothing

Pass in a string to be displayed inline (if possible) next to the highlighted
location in the code. If it can't be positioned inline, it will be placed above
the code frame.

```
1 | class Foo {
> 2 | constructor()
| ^ Missing {
3 | };
```

## Upgrading from prior versions

Prior to version 7, the only API exposed by this module was for a single line and optional column pointer. The old API will now log a deprecation warning.
Expand Down
13 changes: 12 additions & 1 deletion packages/babel-code-frame/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ function getDefs(chalk) {
invalid: chalk.white.bgRed.bold,
gutter: chalk.grey,
marker: chalk.red.bold,
message: chalk.red.bold,
};
}

Expand Down Expand Up @@ -200,16 +201,18 @@ export function codeFrameColumns(

const lines = rawLines.split(NEWLINE);
const { start, end, markerLines } = getMarkerLines(loc, lines, opts);
const hasColumns = loc.start && typeof loc.start.column === "number";

const numberMaxWidth = String(end).length;

const frame = lines
let frame = lines
.slice(start, end)
.map((line, index) => {
const number = start + 1 + index;
const paddedNumber = ` ${number}`.slice(-numberMaxWidth);
const gutter = ` ${paddedNumber} | `;
const hasMarker = markerLines[number];
const lastMarkerLine = !markerLines[number + 1];
if (hasMarker) {
let markerLine = "";
if (Array.isArray(hasMarker)) {
Expand All @@ -224,6 +227,10 @@ export function codeFrameColumns(
markerSpacing,
maybeHighlight(defs.marker, "^").repeat(numberOfMarkers),
].join("");

if (lastMarkerLine && opts.message) {
markerLine += " " + maybeHighlight(defs.message, opts.message);
}
}
return [
maybeHighlight(defs.marker, ">"),
Expand All @@ -237,6 +244,10 @@ export function codeFrameColumns(
})
.join("\n");

if (opts.message && !hasColumns) {
frame = `${" ".repeat(numberMaxWidth + 1)}${opts.message}\n${frame}`;
}

if (highlighted) {
return chalk.reset(frame);
} else {
Expand Down
97 changes: 97 additions & 0 deletions packages/babel-code-frame/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,4 +299,101 @@ describe("@babel/code-frame", function() {
].join("\n"),
);
});

it("opts.message", function() {
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
assert.equal(
codeFrameColumns(
rawLines,
{ start: { line: 2, column: 16 } },
{
message: "Missing {",
},
),
[
" 1 | class Foo {",
"> 2 | constructor()",
" | ^ Missing {",
" 3 | };",
].join("\n"),
);
});

it("opts.message without column", function() {
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
assert.equal(
codeFrameColumns(
rawLines,
{ start: { line: 2 } },
{
message: "Missing {",
},
),
[
" Missing {",
" 1 | class Foo {",
"> 2 | constructor()",
" 3 | };",
].join("\n"),
);
});

it("opts.message with multiple lines", function() {
const rawLines = [
"class Foo {",
" constructor() {",
" console.log(arguments);",
" }",
"};",
].join("\n");
assert.equal(
codeFrameColumns(
rawLines,
{
start: { line: 2, column: 17 },
end: { line: 4, column: 3 },
},
{
message: "something about the constructor body",
},
),
[
" 1 | class Foo {",
"> 2 | constructor() {",
" | ^",
"> 3 | console.log(arguments);",
" | ^^^^^^^^^^^^^^^^^^^^^^^^^^^",
"> 4 | }",
" | ^^^ something about the constructor body",
" 5 | };",
].join("\n"),
);
});

it("opts.message with multiple lines without columns", function() {
const rawLines = [
"class Foo {",
" constructor() {",
" console.log(arguments);",
" }",
"};",
].join("\n");
assert.equal(
codeFrameColumns(
rawLines,
{ start: { line: 2 }, end: { line: 4 } },
{
message: "something about the constructor body",
},
),
[
" something about the constructor body",
" 1 | class Foo {",
"> 2 | constructor() {",
"> 3 | console.log(arguments);",
"> 4 | }",
" 5 | };",
].join("\n"),
);
});
});

0 comments on commit c447a8e

Please sign in to comment.