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
40 changes: 25 additions & 15 deletions lib/webidl2.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
let line = 1;
tokens = tokens.slice();
const names = new Map();
let current = null;

const FLOAT = "float";
const INT = "integer";
Expand All @@ -69,7 +70,17 @@
tok += tokens[numTokens].value;
numTokens++;
}
throw new WebIDLParseError(str, line, tok, tokens.slice(0, maxTokens));

let message;
if (current) {
message = `Got an error during or right after parsing \`${current.partial ? "partial " : ""}${current.type} ${current.name}\`: ${str}`
}
else {
// throwing before any valid definition
message = `Got an error before parsing any named definition: ${str}`;
}

throw new WebIDLParseError(message, line, tok, tokens.slice(0, maxTokens));
};

function sanitize_name(name, type) {
Expand Down Expand Up @@ -484,12 +495,11 @@
all_ws();
const tok = consume(ID, "interface");
if (tok) {
ret = interface_rest();
ret.type = "callback interface";
ret = interface_rest(false, store, "callback interface");
return ret;
}
const name = consume(ID) || error("No name for callback");
ret = { type: "callback", name: sanitize_name(name.value, "callback") };
ret = current = { type: "callback", name: sanitize_name(name.value, "callback") };
all_ws();
consume(OTHER, "=") || error("No assignment in callback");
all_ws();
Expand Down Expand Up @@ -675,14 +685,14 @@
return ret;
};

function interface_rest(isPartial, store) {
function interface_rest(isPartial, store, typeName = "interface") {
all_ws();
const name = consume(ID) || error("No name for interface");
const mems = [];
const ret = {
type: "interface",
const ret = current = {
type: typeName,
name: isPartial ? name.value : sanitize_name(name.value, "interface"),
partial: false,
partial: isPartial,
members: mems
};
if (!isPartial) ret.inheritance = inheritance() || null;
Expand Down Expand Up @@ -721,10 +731,10 @@
all_ws();
const name = consume(ID) || error("No name for interface mixin");
const mems = [];
const ret = {
const ret = current = {
type: "interface mixin",
name: isPartial ? name.value : sanitize_name(name.value, "interface mixin"),
partial: false,
partial: isPartial,
members: mems
};
all_ws();
Expand Down Expand Up @@ -767,7 +777,7 @@
all_ws();
const name = consume(ID) || error("No name for namespace");
const mems = [];
const ret = {
const ret = current = {
type: "namespace",
name: isPartial ? name.value : sanitize_name(name.value, "namespace"),
partial: isPartial,
Expand Down Expand Up @@ -836,7 +846,6 @@
interface_(true, store) ||
namespace(true, store) ||
error("Partial doesn't apply to anything");
thing.partial = true;
return thing;
};

Expand All @@ -846,10 +855,10 @@
all_ws();
const name = consume(ID) || error("No name for dictionary");
const mems = [];
const ret = {
const ret = current = {
type: "dictionary",
name: isPartial ? name.value : sanitize_name(name.value, "dictionary"),
partial: false,
partial: isPartial,
members: mems
};
if (!isPartial) ret.inheritance = inheritance() || null;
Expand Down Expand Up @@ -892,7 +901,7 @@
all_ws();
const name = consume(ID) || error("No name for enum");
const vals = [];
const ret = {
const ret = current = {
type: "enum",
name: sanitize_name(name.value, "enum"),
values: vals
Expand Down Expand Up @@ -932,6 +941,7 @@
all_ws();
const name = consume(ID) || error("No name in typedef");
ret.name = sanitize_name(name.value, "typedef");
current = ret;
all_ws();
consume(OTHER, ";") || error("Unterminated typedef");
return ret;
Expand Down
7 changes: 7 additions & 0 deletions test/invalid/idl/no-semicolon-callback.widl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
callback interface NoSemicolon {
attribute boolean noSemiColon;
}

enum YouNeedOne {
"really"
}
7 changes: 7 additions & 0 deletions test/invalid/idl/no-semicolon.widl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
partial interface NoSemicolon {
attribute boolean noSemiColon;
}

enum YouNeedOne {
"really"
}
4 changes: 2 additions & 2 deletions test/invalid/json/array.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "No name in attribute",
"message": "Got an error during or right after parsing `interface LotteryResults`: No name in attribute",
"line": 5
}
}
2 changes: 1 addition & 1 deletion test/invalid/json/caller.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Invalid operation",
"message": "Got an error during or right after parsing `interface NumberQuadrupler`: Invalid operation",
"line": 6
}
2 changes: 1 addition & 1 deletion test/invalid/json/dict-required-default.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Required member must not have a default"
"message": "Got an error during or right after parsing `dictionary Dict`: Required member must not have a default"
, "line": 4
}
4 changes: 2 additions & 2 deletions test/invalid/json/duplicate.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "The name \"Test\" of type \"typedef\" is already seen",
"message": "Got an error during or right after parsing `typedef Test`: The name \"Test\" of type \"typedef\" is already seen",
"line": 3
}
}
2 changes: 1 addition & 1 deletion test/invalid/json/enum.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Unexpected value in enum"
"message": "Got an error during or right after parsing `enum foo`: Unexpected value in enum"
, "line": 1
}
2 changes: 1 addition & 1 deletion test/invalid/json/exception.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Unrecognised tokens",
"message": "Got an error before parsing any named definition: Unrecognised tokens",
"line": 4
}
2 changes: 1 addition & 1 deletion test/invalid/json/iterator.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Invalid operation",
"message": "Got an error during or right after parsing `interface SessionManager`: Invalid operation",
"line": 5
}
4 changes: 2 additions & 2 deletions test/invalid/json/maplike-1type.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Missing second type argument in maplike declaration",
"message": "Got an error during or right after parsing `interface MapLikeOneType`: Missing second type argument in maplike declaration",
"line": 2
}
}
2 changes: 1 addition & 1 deletion test/invalid/json/module.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Unrecognised tokens"
"message": "Got an error before parsing any named definition: Unrecognised tokens"
, "line": 2
}
4 changes: 4 additions & 0 deletions test/invalid/json/no-semicolon-callback.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"message": "Got an error during or right after parsing `callback interface NoSemicolon`: Missing semicolon after interface",
"line": 5
}
4 changes: 4 additions & 0 deletions test/invalid/json/no-semicolon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"message": "Got an error during or right after parsing `partial interface NoSemicolon`: Missing semicolon after interface",
"line": 5
}
2 changes: 1 addition & 1 deletion test/invalid/json/nonnullableany.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Type any cannot be made nullable"
"message": "Got an error during or right after parsing `interface NonNullable`: Type any cannot be made nullable"
, "line": 2
}
2 changes: 1 addition & 1 deletion test/invalid/json/nonnullableobjects.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Can't nullable more than once"
"message": "Got an error during or right after parsing `interface NonNullable`: Can't nullable more than once"
, "line": 4
}
2 changes: 1 addition & 1 deletion test/invalid/json/promise-with-extended-attribute.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Promise type cannot have extended attribute",
"message": "Got an error during or right after parsing `interface Foo`: Promise type cannot have extended attribute",
"line": 2
}
2 changes: 1 addition & 1 deletion test/invalid/json/raises.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Unterminated attribute"
"message": "Got an error during or right after parsing `interface Person`: Unterminated attribute"
, "line": 5
}
4 changes: 2 additions & 2 deletions test/invalid/json/readonly-iterable.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Invalid operation",
"message": "Got an error during or right after parsing `interface ReadonlyIterable`: Invalid operation",
"line": 2
}
}
2 changes: 1 addition & 1 deletion test/invalid/json/record-key-with-extended-attribute.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Record key cannot have extended attribute",
"message": "Got an error during or right after parsing `interface Foo`: Record key cannot have extended attribute",
"line": 2
}
2 changes: 1 addition & 1 deletion test/invalid/json/record-key.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Record key must be DOMString, USVString, or ByteString",
"message": "Got an error during or right after parsing `interface Foo`: Record key must be DOMString, USVString, or ByteString",
"line": 2
}
2 changes: 1 addition & 1 deletion test/invalid/json/scopedname.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "No name in typedef"
"message": "Got an error before parsing any named definition: No name in typedef"
, "line": 2
}
2 changes: 1 addition & 1 deletion test/invalid/json/sequenceAsAttribute.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Attributes cannot accept sequence types"
"message": "Got an error during or right after parsing `interface sequenceAsAttribute`: Attributes cannot accept sequence types"
, "line": 2
}
4 changes: 2 additions & 2 deletions test/invalid/json/setlike-2types.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Unterminated setlike declaration",
"message": "Got an error during or right after parsing `interface SetLikeTwoTypes`: Unterminated setlike declaration",
"line": 2
}
}
2 changes: 1 addition & 1 deletion test/invalid/json/setter-creator.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Invalid operation",
"message": "Got an error during or right after parsing `interface OrderedMap`: Invalid operation",
"line": 3
}
2 changes: 1 addition & 1 deletion test/invalid/json/special-omittable.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Invalid operation"
"message": "Got an error during or right after parsing `interface Dictionary`: Invalid operation"
, "line": 6
}
2 changes: 1 addition & 1 deletion test/invalid/json/stringconstants.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "No value for const"
"message": "Got an error during or right after parsing `interface Util`: No value for const"
, "line": 2
}
4 changes: 2 additions & 2 deletions test/invalid/json/typedef-nested.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"message": "Invalid operation"
"message": "Got an error during or right after parsing `interface Widget`: Invalid operation"
, "line": 14
}
}