Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 36 additions & 10 deletions lib/webidl2.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
// remaining trivia as eof
tokens.push({
type: "eof",
value: "",
trivia
});

Expand Down Expand Up @@ -210,24 +211,49 @@

function error(str) {
const maxTokens = 5;
const tok = tokens
.slice(consume_position, consume_position + maxTokens)
.map(t => t.trivia + t.value).join("");
// Count newlines preceding the actual erroneous token
if (tokens[consume_position] && !probe("eof")) {
line += count(tokens[consume_position].trivia, "\n");
}

let message;
if (current) {
message = `Got an error during or right after parsing \`${current.partial ? "partial " : ""}${current.type} ${current.name}\`: ${str}`;
const precedingLine = lastLine(
tokensToText(sliceTokens(-maxTokens), { precedes: true })
);

const procedingTokens = sliceTokens(maxTokens);
const procedingText = tokensToText(procedingTokens);
const procedingLine = procedingText.split("\n")[0];

const spaced = " ".repeat(precedingLine.length) + "^ " + str;
const context = precedingLine + procedingLine + "\n" + spaced;

const since = current ? `, since \`${current.partial ? "partial " : ""}${current.type} ${current.name}\`` : "";
const message = `Syntax error at line ${line}${since}:\n${context}`;

throw new WebIDLParseError(message, line, procedingText, procedingTokens);

function sliceTokens(count) {
return count > 0 ?
tokens.slice(consume_position, consume_position + count) :
tokens.slice(Math.max(consume_position + count, 0), consume_position);
}
else {
// throwing before any valid definition
message = `Got an error before parsing any named definition: ${str}`;

function tokensToText(inputs, { precedes } = {}) {
const text = inputs.map(t => t.trivia + t.value).join("");
const nextToken = tokens[consume_position];
if (nextToken.type === "eof") {
return text;
}
if (precedes) {
return text + nextToken.trivia;
}
return text.slice(nextToken.trivia.length);
}

throw new WebIDLParseError(message, line, tok, tokens.slice(0, maxTokens));
function lastLine(text) {
const splitted = text.split("\n");
return splitted[splitted.length - 1];
}
}

function sanitize_name(name, type) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"mocha": "5.2.0"
},
"scripts": {
"lint": "eslint lib/*.js test/*.js",
"lint": "eslint lib/*.js test/*.js test/util/*.js",
"test": "npm run lint && mocha",
"acquire": "node test/util/acquire.js"
},
Expand Down
8 changes: 3 additions & 5 deletions test/invalid.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ const { collect } = require("./util/collect");
const expect = require("expect");

describe("Parses all of the invalid IDLs to check that they blow up correctly", () => {
for (const test of collect("invalid", { expectError: true })) {
for (const test of collect("invalid", { expectError: true, raw: true })) {
it(`should produce the right error for ${test.path}`, () => {
const err = test.readJSON();
expect(test.error).toBeTruthy();
expect(test.error.message).toEqual(err.message);
expect(test.error.line).toEqual(err.line);
const err = test.readText();
expect(test.error.message + "\n").toEqual(err);
});
}
});
3 changes: 3 additions & 0 deletions test/invalid/baseline/array.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 5, since `interface LotteryResults`:
readonly attribute unsigned short[][] numbers
^ No name in attribute
3 changes: 3 additions & 0 deletions test/invalid/baseline/caller.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 6, since `interface NumberQuadrupler`:
legacycaller float compute(float x
^ Invalid operation
3 changes: 3 additions & 0 deletions test/invalid/baseline/dict-required-default.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 4, since `dictionary Dict`:
required long member = 0;
^ Required member must not have a default
3 changes: 3 additions & 0 deletions test/invalid/baseline/duplicate-escaped.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface Iroha`:
interface _Iroha {};
^ The name "Iroha" of type "interface" was already seen
3 changes: 3 additions & 0 deletions test/invalid/baseline/duplicate.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 3, since `typedef Test`:
interface Test {
^ The name "Test" of type "typedef" was already seen
3 changes: 3 additions & 0 deletions test/invalid/baseline/enum-bodyless.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 1, since `enum X`:
enum X
^ Bodyless enum
3 changes: 3 additions & 0 deletions test/invalid/baseline/enum-empty.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 1, since `enum Empty`:
enum Empty {};
^ No value in enum
3 changes: 3 additions & 0 deletions test/invalid/baseline/enum-wo-comma.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 1, since `enum NoComma`:
enum NoComma { value1 "value2" };
^ No comma between enum values
3 changes: 3 additions & 0 deletions test/invalid/baseline/enum.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 1, since `enum foo`:
enum foo { 1, 2, 3
^ Unexpected value in enum
3 changes: 3 additions & 0 deletions test/invalid/baseline/exception.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 4:
exception SomeException {
^ Unrecognised tokens
3 changes: 3 additions & 0 deletions test/invalid/baseline/extattr-empty-ids.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 1:
[Exposed=()]
^ Expected identifiers but none found
3 changes: 3 additions & 0 deletions test/invalid/baseline/id-underscored-number.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 1:
interface _0 {};
^ No name for interface
3 changes: 3 additions & 0 deletions test/invalid/baseline/implements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 14, since `interface EventTarget`:
Node implements EventTarget;
^ Unrecognised tokens
3 changes: 3 additions & 0 deletions test/invalid/baseline/implements_and_includes_ws.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 4:
foobar;
^ Unrecognised tokens
3 changes: 3 additions & 0 deletions test/invalid/baseline/iterable-empty.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface X`:
iterable<>;
^ Error parsing iterable declaration
3 changes: 3 additions & 0 deletions test/invalid/baseline/iterator.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 5, since `interface SessionManager`:
Session iterator;
^ Invalid operation
3 changes: 3 additions & 0 deletions test/invalid/baseline/legacyiterable.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface LegacyIterable`:
legacyiterable<long>;
^ Missing return type
3 changes: 3 additions & 0 deletions test/invalid/baseline/maplike-1type.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface MapLikeOneType`:
maplike<long>;
^ Missing second type argument in maplike declaration
3 changes: 3 additions & 0 deletions test/invalid/baseline/module.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2:
module gfx {
^ Unrecognised tokens
3 changes: 3 additions & 0 deletions test/invalid/baseline/namespace-readwrite.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `namespace CSS`:
attribute object readwrite;
^ Attributes must be readonly in this context
3 changes: 3 additions & 0 deletions test/invalid/baseline/no-semicolon-callback.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 5, since `callback interface NoSemicolon`:
enum YouNeedOne {
^ Missing semicolon after interface
3 changes: 3 additions & 0 deletions test/invalid/baseline/no-semicolon.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 5, since `partial interface NoSemicolon`:
enum YouNeedOne {
^ Missing semicolon after interface
3 changes: 3 additions & 0 deletions test/invalid/baseline/nonnullableany.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface NonNullable`:
attribute any? foo;
^ Type any cannot be made nullable
3 changes: 3 additions & 0 deletions test/invalid/baseline/nonnullableobjects.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 4, since `interface NonNullable`:
attribute Foo??
^ Can't nullable more than once
3 changes: 3 additions & 0 deletions test/invalid/baseline/operation-too-special.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface Ako`:
getter setter void maki()
^ Missing return type
3 changes: 3 additions & 0 deletions test/invalid/baseline/promise-nullable.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface X`:
attribute Promise<void>?
^ Promise type cannot be nullable
3 changes: 3 additions & 0 deletions test/invalid/baseline/promise-with-extended-attribute.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface Foo`:
Promise<[XAttr] DOMString>
^ Promise type cannot have extended attribute
3 changes: 3 additions & 0 deletions test/invalid/baseline/raises.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 5, since `interface Person`:
attribute DOMString name setraises (InvalidName);
^ Unterminated attribute
3 changes: 3 additions & 0 deletions test/invalid/baseline/readonly-iterable.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface ReadonlyIterable`:
readonly iterable<long>
^ Missing return type
3 changes: 3 additions & 0 deletions test/invalid/baseline/record-key-with-extended-attribute.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface Foo`:
void foo(record<[XAttr] DOMString,
^ Record key cannot have extended attribute
3 changes: 3 additions & 0 deletions test/invalid/baseline/record-key.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface Foo`:
void foo(record<octet, any> param
^ Record key must be a string type
3 changes: 3 additions & 0 deletions test/invalid/baseline/record-single.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface Foo`:
foo(record<DOMString> param);
^ Missing comma after record key type
3 changes: 3 additions & 0 deletions test/invalid/baseline/scopedname.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2:
typedef gfx::geom::
^ No name in typedef
3 changes: 3 additions & 0 deletions test/invalid/baseline/sequenceAsAttribute.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface sequenceAsAttribute`:
attribute sequence<short> invalid;
^ Attributes cannot accept sequence types
3 changes: 3 additions & 0 deletions test/invalid/baseline/setlike-2types.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface SetLikeTwoTypes`:
setlike<long, long>;
^ Unterminated setlike declaration
3 changes: 3 additions & 0 deletions test/invalid/baseline/setter-creator.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 3, since `interface OrderedMap`:
setter creator void set(DOMString name
^ Invalid operation
3 changes: 3 additions & 0 deletions test/invalid/baseline/spaced-negative-infinity.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface X`:
const float infinity = - Infinity;
^ No value for const
3 changes: 3 additions & 0 deletions test/invalid/baseline/spaced-variadic.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface X`:
void operation(object . . . args
^ Unterminated operation
3 changes: 3 additions & 0 deletions test/invalid/baseline/special-omittable.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 6, since `interface Dictionary`:
omittable getter float getProperty(DOMString
^ Invalid operation
3 changes: 3 additions & 0 deletions test/invalid/baseline/stray-slash.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2:
/ This is not.
^ Unrecognised tokens
3 changes: 3 additions & 0 deletions test/invalid/baseline/stringconstants.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface Util`:
const DOMString hello = "world";
^ No type for const
3 changes: 3 additions & 0 deletions test/invalid/baseline/typedef-nested.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 14, since `interface Widget`:
typedef sequence<Point>
^ Missing return type
3 changes: 3 additions & 0 deletions test/invalid/baseline/union-dangling-or.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 1:
(One or Two or) UnionOr;
^ No type after open parenthesis or 'or' in union type
3 changes: 3 additions & 0 deletions test/invalid/baseline/union-one.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 1:
typedef (OnlyOne) UnionOne;
^ At least two types are expected in a union type but found less
3 changes: 3 additions & 0 deletions test/invalid/baseline/union-zero.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 1:
typedef () UnionZero;
^ No type after open parenthesis or 'or' in union type
3 changes: 3 additions & 0 deletions test/invalid/baseline/unknown-generic.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Syntax error at line 2, since `interface FetchEvent`:
ResponsePromise<any> default(
^ Unsupported generic type ResponsePromise
4 changes: 0 additions & 4 deletions test/invalid/json/array.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/caller.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/dict-required-default.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/duplicate-escaped.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/duplicate.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/enum-bodyless.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/enum-empty.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/enum-wo-comma.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/enum.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/exception.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/extattr-empty-ids.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/id-underscored-number.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/implements.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/implements_and_includes_ws.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/iterable-empty.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/iterator.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/legacyiterable.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/maplike-1type.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/module.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/namespace-readwrite.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/no-semicolon-callback.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/no-semicolon.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/nonnullableany.json

This file was deleted.

4 changes: 0 additions & 4 deletions test/invalid/json/nonnullableobjects.json

This file was deleted.

Loading