Comparing version 11.0.0 to 12.0.0
@@ -18,46 +18,37 @@ "use strict"; | ||
function attemptTokenMatch(str, type, lastIndex, tokens) { | ||
const re = tokenRe[type]; | ||
re.lastIndex = lastIndex; | ||
const result = re.exec(str); | ||
if (result) { | ||
tokens.push({ type, value: result[0] }); | ||
return re.lastIndex; | ||
} | ||
return -1; | ||
} | ||
function tokenise(str) { | ||
const tokens = []; | ||
let lastIndex = 0; | ||
let trivia = ""; | ||
while (lastIndex < str.length) { | ||
const nextChar = str.charAt(lastIndex); | ||
let result = -1; | ||
if (/[-0-9.]/.test(nextChar)) { | ||
result = attemptTokenMatch(str, "float", lastIndex, tokens); | ||
if (/[\t\n\r ]/.test(nextChar)) { | ||
result = attemptTokenMatch("whitespace", { noFlushTrivia: true }); | ||
} else if (nextChar === '/') { | ||
result = attemptTokenMatch("comment", { noFlushTrivia: true }); | ||
} | ||
if (result !== -1) { | ||
trivia += tokens.pop().value; | ||
} else if (/[-0-9.]/.test(nextChar)) { | ||
result = attemptTokenMatch("float"); | ||
if (result === -1) { | ||
result = attemptTokenMatch(str, "integer", lastIndex, tokens); | ||
result = attemptTokenMatch("integer"); | ||
} | ||
if (result === -1) { | ||
// '-' and '.' can also match "other". | ||
result = attemptTokenMatch(str, "other", lastIndex, tokens); | ||
result = attemptTokenMatch("other"); | ||
} | ||
} else if (/[A-Z_a-z]/.test(nextChar)) { | ||
result = attemptTokenMatch(str, "identifier", lastIndex, tokens); | ||
result = attemptTokenMatch("identifier"); | ||
} else if (nextChar === '"') { | ||
result = attemptTokenMatch(str, "string", lastIndex, tokens); | ||
result = attemptTokenMatch("string"); | ||
if (result === -1) { | ||
// '"' can also match "other". | ||
result = attemptTokenMatch(str, "other", lastIndex, tokens); | ||
result = attemptTokenMatch("other"); | ||
} | ||
} else if (/[\t\n\r ]/.test(nextChar)) { | ||
result = attemptTokenMatch(str, "whitespace", lastIndex, tokens); | ||
} else if (nextChar === '/') { | ||
result = attemptTokenMatch(str, "comment", lastIndex, tokens); | ||
if (result === -1) { | ||
// '/' can also match "other". | ||
result = attemptTokenMatch(str, "other", lastIndex, tokens); | ||
} | ||
} else { | ||
result = attemptTokenMatch(str, "other", lastIndex, tokens); | ||
result = attemptTokenMatch("other"); | ||
} | ||
@@ -70,2 +61,16 @@ if (result === -1) { | ||
return tokens; | ||
function attemptTokenMatch(type, {noFlushTrivia} = {}) { | ||
const re = tokenRe[type]; | ||
re.lastIndex = lastIndex; | ||
const result = re.exec(str); | ||
if (result) { | ||
tokens.push({ type, value: result[0], trivia }); | ||
if (!noFlushTrivia) { | ||
trivia = ""; | ||
} | ||
return re.lastIndex; | ||
} | ||
return -1; | ||
} | ||
} | ||
@@ -86,3 +91,3 @@ | ||
function parse(tokens, opt) { | ||
function parse(tokens) { | ||
let line = 1; | ||
@@ -125,2 +130,4 @@ tokens = tokens.slice(); | ||
} | ||
// Count newlines preceding the actual errorneous token | ||
line += count(tokens[0].trivia, "\n"); | ||
@@ -153,2 +160,3 @@ let message; | ||
last_token = tokens.shift(); | ||
line += count(last_token.trivia, "\n"); | ||
if (type === ID && last_token.value.startsWith('_')) | ||
@@ -160,2 +168,11 @@ last_token.value = last_token.value.substring(1); | ||
function unconsume(...toks) { | ||
// TODO: use const when Servo updates its JS engine | ||
// https://github.com/servo/servo/issues/20231 | ||
for (let tok of toks) { | ||
line -= count(tok.trivia, "\n"); | ||
} | ||
tokens.unshift(...toks); | ||
} | ||
function count(str, char) { | ||
@@ -169,37 +186,8 @@ let total = 0; | ||
function ws() { | ||
if (!tokens.length) return; | ||
if (tokens[0].type === "whitespace" || tokens[0].type === "comment") { | ||
const t = tokens.shift(); | ||
line += count(t.value, '\n'); | ||
return t; | ||
} | ||
} | ||
const all_ws_re = { | ||
"ws": /([\t\n\r ]+)/y, | ||
"line-comment": /\/\/(.*)\r?\n?/y, | ||
"multiline-comment": /\/\*((?:[^*]|\*[^/])*)\*\//y | ||
}; | ||
function all_ws() { | ||
const t = { type: "whitespace", value: "" }; | ||
while (true) { | ||
const w = ws(); | ||
if (!w) break; | ||
t.value += w.value; | ||
} | ||
if (t.value.length > 0) { | ||
return t; | ||
} | ||
} | ||
function integer_type() { | ||
let ret = ""; | ||
all_ws(); | ||
if (consume(ID, "unsigned")) ret = "unsigned "; | ||
all_ws(); | ||
if (consume(ID, "short")) return ret + "short"; | ||
if (consume(ID, "long")) { | ||
ret += "long"; | ||
all_ws(); | ||
if (consume(ID, "long")) return ret + " long"; | ||
@@ -213,5 +201,3 @@ return ret; | ||
let ret = ""; | ||
all_ws(); | ||
if (consume(ID, "unrestricted")) ret = "unrestricted "; | ||
all_ws(); | ||
if (consume(ID, "float")) return ret + "float"; | ||
@@ -225,3 +211,2 @@ if (consume(ID, "double")) return ret + "double"; | ||
if (num_type) return num_type; | ||
all_ws(); | ||
if (consume(ID, "boolean")) return "boolean"; | ||
@@ -243,3 +228,3 @@ if (consume(ID, "byte")) return "byte"; | ||
if (consume(ID, "Infinity")) return { type: "Infinity", negative: true }; | ||
else tokens.unshift(tok); | ||
else unconsume(tok); | ||
} | ||
@@ -250,3 +235,2 @@ } | ||
while (true) { | ||
all_ws(); | ||
if (consume(OTHER, "?")) { | ||
@@ -268,3 +252,2 @@ if (obj.nullable) error("Can't nullable more than once"); | ||
value = name.value; | ||
all_ws(); | ||
// Generic types | ||
@@ -279,5 +262,3 @@ if (consume(OTHER, "<")) { | ||
do { | ||
all_ws(); | ||
types.push(type_with_extended_attributes(typeName) || error("Error parsing generic type " + value)); | ||
all_ws(); | ||
} | ||
@@ -297,3 +278,2 @@ while (consume(OTHER, ",")); | ||
ret.idlType = types.length === 1 ? types[0] : types; | ||
all_ws(); | ||
if (!consume(OTHER, ">")) error("Unterminated generic type " + value); | ||
@@ -314,3 +294,2 @@ type_suffix(ret); | ||
function union_type(typeName) { | ||
all_ws(); | ||
if (!consume(OTHER, "(")) return; | ||
@@ -321,3 +300,2 @@ const ret = Object.assign({ type: typeName || null }, EMPTY_IDLTYPE, { union: true, idlType: [] }); | ||
while (true) { | ||
all_ws(); | ||
if (!consume(ID, "or")) break; | ||
@@ -346,11 +324,9 @@ const typ = type_with_extended_attributes() || error("No type after 'or' in union type"); | ||
ret.extAttrs = extended_attrs(); | ||
all_ws(); | ||
const opt_token = consume(ID, "optional"); | ||
if (opt_token) { | ||
ret.optional = true; | ||
all_ws(); | ||
} | ||
ret.idlType = type_with_extended_attributes("argument-type"); | ||
if (!ret.idlType) { | ||
if (opt_token) tokens.unshift(opt_token); | ||
if (opt_token) unconsume(opt_token); | ||
return; | ||
@@ -360,3 +336,2 @@ } | ||
if (!ret.optional) { | ||
all_ws(); | ||
if (tokens.length >= 3 && | ||
@@ -373,7 +348,6 @@ tokens[0].type === "other" && tokens[0].value === "." && | ||
} | ||
all_ws(); | ||
const name = consume(ID); | ||
if (!name) { | ||
if (opt_token) tokens.unshift(opt_token); | ||
tokens.unshift(type_token); | ||
if (opt_token) unconsume(opt_token); | ||
unconsume(type_token); | ||
return; | ||
@@ -383,3 +357,2 @@ } | ||
if (ret.optional) { | ||
all_ws(); | ||
const dflt = default_(); | ||
@@ -399,3 +372,2 @@ if (typeof dflt !== "undefined") { | ||
while (true) { | ||
all_ws(); | ||
if (!consume(OTHER, ",")) return ret; | ||
@@ -408,3 +380,2 @@ const nxt = argument() || error("Trailing comma in arguments list"); | ||
function simple_extended_attr() { | ||
all_ws(); | ||
const name = consume(ID); | ||
@@ -418,6 +389,4 @@ if (!name) return; | ||
}; | ||
all_ws(); | ||
const eq = consume(OTHER, "="); | ||
if (eq) { | ||
all_ws(); | ||
ret.rhs = consume(ID) || | ||
@@ -427,4 +396,7 @@ consume(FLOAT) || | ||
consume(STR); | ||
if (ret.rhs) { | ||
// No trivia exposure yet | ||
ret.rhs.trivia = undefined; | ||
} | ||
} | ||
all_ws(); | ||
if (consume(OTHER, "(")) { | ||
@@ -442,3 +414,2 @@ if (eq && !ret.rhs) { | ||
} | ||
all_ws(); | ||
consume(OTHER, ")") || error("Unexpected token in extended attribute argument list"); | ||
@@ -454,10 +425,7 @@ } | ||
const eas = []; | ||
all_ws(); | ||
if (!consume(OTHER, "[")) return eas; | ||
eas[0] = simple_extended_attr() || error("Extended attribute with not content"); | ||
all_ws(); | ||
while (consume(OTHER, ",")) { | ||
eas.push(simple_extended_attr() || error("Trailing comma in extended attribute")); | ||
} | ||
all_ws(); | ||
consume(OTHER, "]") || error("No end of extended attribute"); | ||
@@ -468,5 +436,3 @@ return eas; | ||
function default_() { | ||
all_ws(); | ||
if (consume(OTHER, "=")) { | ||
all_ws(); | ||
const def = const_value(); | ||
@@ -481,2 +447,4 @@ if (def) { | ||
str.value = str.value.slice(1, -1); | ||
// No trivia exposure yet | ||
str.trivia = undefined; | ||
return str; | ||
@@ -488,6 +456,4 @@ } | ||
function const_() { | ||
all_ws(); | ||
if (!consume(ID, "const")) return; | ||
const ret = { type: "const", nullable: false }; | ||
all_ws(); | ||
let typ = primitive_type(); | ||
@@ -499,16 +465,11 @@ if (!typ) { | ||
ret.idlType = Object.assign({ type: "const-type" }, EMPTY_IDLTYPE, { idlType: typ }); | ||
all_ws(); | ||
if (consume(OTHER, "?")) { | ||
ret.nullable = true; | ||
all_ws(); | ||
} | ||
const name = consume(ID) || error("No name for const"); | ||
ret.name = name.value; | ||
all_ws(); | ||
consume(OTHER, "=") || error("No value assignment for const"); | ||
all_ws(); | ||
const cnt = const_value(); | ||
if (cnt) ret.value = cnt; | ||
else error("No value for const"); | ||
all_ws(); | ||
consume(OTHER, ";") || error("Unterminated const"); | ||
@@ -519,5 +480,3 @@ return ret; | ||
function inheritance() { | ||
all_ws(); | ||
if (consume(OTHER, ":")) { | ||
all_ws(); | ||
const inh = consume(ID) || error("No type in inheritance"); | ||
@@ -529,12 +488,8 @@ return inh.value; | ||
function operation_rest(ret) { | ||
all_ws(); | ||
if (!ret) ret = {}; | ||
const name = consume(ID); | ||
ret.name = name ? name.value : null; | ||
all_ws(); | ||
consume(OTHER, "(") || error("Invalid operation"); | ||
ret.arguments = argument_list(); | ||
all_ws(); | ||
consume(OTHER, ")") || error("Unterminated operation"); | ||
all_ws(); | ||
consume(OTHER, ";") || error("Unterminated operation"); | ||
@@ -545,6 +500,4 @@ return ret; | ||
function callback() { | ||
all_ws(); | ||
let ret; | ||
if (!consume(ID, "callback")) return; | ||
all_ws(); | ||
const tok = consume(ID, "interface"); | ||
@@ -557,12 +510,7 @@ if (tok) { | ||
ret = current = { type: "callback", name: sanitize_name(name.value, "callback") }; | ||
all_ws(); | ||
consume(OTHER, "=") || error("No assignment in callback"); | ||
all_ws(); | ||
ret.idlType = return_type(); | ||
all_ws(); | ||
consume(OTHER, "(") || error("No arguments in callback"); | ||
ret.arguments = argument_list(); | ||
all_ws(); | ||
consume(OTHER, ")") || error("Unterminated callback"); | ||
all_ws(); | ||
consume(OTHER, ";") || error("Unterminated callback"); | ||
@@ -573,3 +521,2 @@ return ret; | ||
function attribute() { | ||
all_ws(); | ||
const grabbed = []; | ||
@@ -583,4 +530,2 @@ const ret = { | ||
}; | ||
const w = all_ws(); | ||
if (w) grabbed.push(w); | ||
if (consume(ID, "inherit")) { | ||
@@ -590,4 +535,2 @@ if (ret.static || ret.stringifier) error("Cannot have a static or stringifier inherit"); | ||
grabbed.push(last_token); | ||
const w = all_ws(); | ||
if (w) grabbed.push(w); | ||
} | ||
@@ -597,8 +540,6 @@ if (consume(ID, "readonly")) { | ||
grabbed.push(last_token); | ||
const w = all_ws(); | ||
if (w) grabbed.push(w); | ||
} | ||
const rest = attribute_rest(ret); | ||
if (!rest) { | ||
tokens = grabbed.concat(tokens); | ||
unconsume(...grabbed); | ||
} | ||
@@ -612,10 +553,7 @@ return rest; | ||
} | ||
all_ws(); | ||
ret.idlType = type_with_extended_attributes("attribute-type") || error("No type in attribute"); | ||
if (ret.idlType.sequence) error("Attributes cannot accept sequence types"); | ||
if (ret.idlType.generic === "record") error("Attributes cannot accept record types"); | ||
all_ws(); | ||
const name = consume(ID) || error("No name in attribute"); | ||
ret.name = name.value; | ||
all_ws(); | ||
consume(OTHER, ";") || error("Unterminated attribute"); | ||
@@ -636,6 +574,4 @@ return ret; | ||
function operation() { | ||
all_ws(); | ||
const ret = Object.assign({}, EMPTY_OPERATION); | ||
while (true) { | ||
all_ws(); | ||
if (consume(ID, "getter")) ret.getter = true; | ||
@@ -647,3 +583,2 @@ else if (consume(ID, "setter")) ret.setter = true; | ||
if (ret.getter || ret.setter || ret.deleter) { | ||
all_ws(); | ||
ret.idlType = return_type(); | ||
@@ -654,3 +589,2 @@ operation_rest(ret); | ||
ret.idlType = return_type(); | ||
all_ws(); | ||
operation_rest(ret); | ||
@@ -661,5 +595,3 @@ return ret; | ||
function static_member() { | ||
all_ws(); | ||
if (!consume(ID, "static")) return; | ||
all_ws(); | ||
return noninherited_attribute("static") || | ||
@@ -671,5 +603,3 @@ regular_operation("static") || | ||
function stringifier() { | ||
all_ws(); | ||
if (!consume(ID, "stringifier")) return; | ||
all_ws(); | ||
if (consume(OTHER, ";")) { | ||
@@ -691,5 +621,3 @@ return Object.assign({}, EMPTY_OPERATION, { stringifier: true }); | ||
while (true) { | ||
all_ws(); | ||
if (consume(OTHER, ",")) { | ||
all_ws(); | ||
const name = consume(ID) || error("Trailing comma in identifiers list"); | ||
@@ -717,3 +645,2 @@ arr.push(name.value); | ||
function iterable() { | ||
all_ws(); | ||
const grabbed = []; | ||
@@ -724,4 +651,2 @@ const ret = { type: null, idlType: null, readonly: false }; | ||
grabbed.push(last_token); | ||
var w = all_ws(); | ||
if (w) grabbed.push(w); | ||
} | ||
@@ -732,3 +657,3 @@ const consumeItType = ret.readonly ? readonly_iterable_type : iterable_type; | ||
if (!ittype) { | ||
tokens = grabbed.concat(tokens); | ||
unconsume(...grabbed); | ||
return; | ||
@@ -742,11 +667,7 @@ } | ||
delete ret.readonly; | ||
all_ws(); | ||
if (consume(OTHER, "<")) { | ||
ret.idlType = [type_with_extended_attributes()] || error(`Error parsing ${ittype} declaration`); | ||
all_ws(); | ||
if (secondTypeAllowed) { | ||
if (consume(OTHER, ",")) { | ||
all_ws(); | ||
ret.idlType.push(type_with_extended_attributes()); | ||
all_ws(); | ||
} | ||
@@ -757,3 +678,2 @@ else if (secondTypeRequired) | ||
if (!consume(OTHER, ">")) error(`Unterminated ${ittype} declaration`); | ||
all_ws(); | ||
if (!consume(OTHER, ";")) error(`Missing semicolon after ${ittype} declaration`); | ||
@@ -767,3 +687,2 @@ } else | ||
function interface_rest(isPartial, typeName = "interface") { | ||
all_ws(); | ||
const name = consume(ID) || error("No name for interface"); | ||
@@ -778,8 +697,5 @@ const mems = []; | ||
if (!isPartial) ret.inheritance = inheritance() || null; | ||
all_ws(); | ||
consume(OTHER, "{") || error("Bodyless interface"); | ||
while (true) { | ||
all_ws(); | ||
if (consume(OTHER, "}")) { | ||
all_ws(); | ||
consume(OTHER, ";") || error("Missing semicolon after interface"); | ||
@@ -789,3 +705,2 @@ return ret; | ||
const ea = extended_attrs(); | ||
all_ws(); | ||
const cnt = const_(); | ||
@@ -797,4 +712,3 @@ if (cnt) { | ||
} | ||
const mem = (opt.allowNestedTypedefs && typedef()) || | ||
static_member() || | ||
const mem = static_member() || | ||
stringifier() || | ||
@@ -811,5 +725,3 @@ iterable() || | ||
function mixin_rest(isPartial) { | ||
all_ws(); | ||
if (!consume(ID, "mixin")) return; | ||
all_ws(); | ||
const name = consume(ID) || error("No name for interface mixin"); | ||
@@ -823,8 +735,5 @@ const mems = []; | ||
}; | ||
all_ws(); | ||
consume(OTHER, "{") || error("Bodyless interface mixin"); | ||
while (true) { | ||
all_ws(); | ||
if (consume(OTHER, "}")) { | ||
all_ws(); | ||
consume(OTHER, ";") || error("Missing semicolon after interface mixin"); | ||
@@ -834,3 +743,2 @@ return ret; | ||
const ea = extended_attrs(); | ||
all_ws(); | ||
const cnt = const_(); | ||
@@ -852,3 +760,2 @@ if (cnt) { | ||
function interface_(isPartial) { | ||
all_ws(); | ||
if (!consume(ID, "interface")) return; | ||
@@ -861,5 +768,3 @@ return mixin_rest(isPartial) || | ||
function namespace(isPartial) { | ||
all_ws(); | ||
if (!consume(ID, "namespace")) return; | ||
all_ws(); | ||
const name = consume(ID) || error("No name for namespace"); | ||
@@ -873,8 +778,5 @@ const mems = []; | ||
}; | ||
all_ws(); | ||
consume(OTHER, "{") || error("Bodyless namespace"); | ||
while (true) { | ||
all_ws(); | ||
if (consume(OTHER, "}")) { | ||
all_ws(); | ||
consume(OTHER, ";") || error("Missing semicolon after namespace"); | ||
@@ -884,3 +786,2 @@ return ret; | ||
const ea = extended_attrs(); | ||
all_ws(); | ||
const mem = noninherited_attribute() || | ||
@@ -895,3 +796,2 @@ regular_operation() || | ||
function noninherited_attribute(prefix) { | ||
const w = all_ws(); | ||
const grabbed = []; | ||
@@ -908,12 +808,9 @@ const ret = { | ||
} | ||
if (w) grabbed.push(w); | ||
if (consume(ID, "readonly")) { | ||
ret.readonly = true; | ||
grabbed.push(last_token); | ||
const w = all_ws(); | ||
if (w) grabbed.push(w); | ||
} | ||
const rest = attribute_rest(ret); | ||
if (!rest) { | ||
tokens = grabbed.concat(tokens); | ||
unconsume(...grabbed); | ||
} | ||
@@ -924,3 +821,2 @@ return rest; | ||
function regular_operation(prefix) { | ||
all_ws(); | ||
const ret = Object.assign({}, EMPTY_OPERATION); | ||
@@ -935,3 +831,2 @@ if (prefix) { | ||
function partial() { | ||
all_ws(); | ||
if (!consume(ID, "partial")) return; | ||
@@ -946,5 +841,3 @@ const thing = dictionary(true) || | ||
function dictionary(isPartial) { | ||
all_ws(); | ||
if (!consume(ID, "dictionary")) return; | ||
all_ws(); | ||
const name = consume(ID) || error("No name for dictionary"); | ||
@@ -959,8 +852,5 @@ const mems = []; | ||
if (!isPartial) ret.inheritance = inheritance() || null; | ||
all_ws(); | ||
consume(OTHER, "{") || error("Bodyless dictionary"); | ||
while (true) { | ||
all_ws(); | ||
if (consume(OTHER, "}")) { | ||
all_ws(); | ||
consume(OTHER, ";") || error("Missing semicolon after dictionary"); | ||
@@ -970,6 +860,4 @@ return ret; | ||
const ea = extended_attrs(); | ||
all_ws(); | ||
const required = consume(ID, "required"); | ||
const typ = type_with_extended_attributes("dictionary-type") || error("No type for dictionary member"); | ||
all_ws(); | ||
const name = consume(ID) || error("No name for dictionary member"); | ||
@@ -989,3 +877,2 @@ const dflt = default_(); | ||
ret.members.push(member); | ||
all_ws(); | ||
consume(OTHER, ";") || error("Unterminated dictionary member"); | ||
@@ -996,5 +883,3 @@ } | ||
function enum_() { | ||
all_ws(); | ||
if (!consume(ID, "enum")) return; | ||
all_ws(); | ||
const name = consume(ID) || error("No name for enum"); | ||
@@ -1007,10 +892,7 @@ const vals = []; | ||
}; | ||
all_ws(); | ||
consume(OTHER, "{") || error("No curly for enum"); | ||
let value_expected = true; | ||
while (true) { | ||
all_ws(); | ||
if (consume(OTHER, "}")) { | ||
if (!ret.values.length) error("No value in enum"); | ||
all_ws(); | ||
consume(OTHER, ";") || error("No semicolon after enum"); | ||
@@ -1024,6 +906,6 @@ return ret; | ||
val.value = val.value.slice(1, -1); | ||
// No trivia exposure yet | ||
val.trivia = undefined; | ||
ret.values.push(val); | ||
all_ws(); | ||
if (consume(OTHER, ",")) { | ||
all_ws(); | ||
value_expected = true; | ||
@@ -1037,3 +919,2 @@ } else { | ||
function typedef() { | ||
all_ws(); | ||
if (!consume(ID, "typedef")) return; | ||
@@ -1043,9 +924,6 @@ const ret = { | ||
}; | ||
all_ws(); | ||
ret.idlType = type_with_extended_attributes("typedef-type") || error("No type in typedef"); | ||
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"); | ||
@@ -1056,6 +934,4 @@ return ret; | ||
function implements_() { | ||
all_ws(); | ||
const target = consume(ID); | ||
if (!target) return; | ||
const w = all_ws(); | ||
if (consume(ID, "implements")) { | ||
@@ -1066,6 +942,4 @@ const ret = { | ||
}; | ||
all_ws(); | ||
const imp = consume(ID) || error("Incomplete implements statement"); | ||
ret["implements"] = imp.value; | ||
all_ws(); | ||
consume(OTHER, ";") || error("No terminating ; for implements statement"); | ||
@@ -1075,5 +949,3 @@ return ret; | ||
// rollback | ||
if (w) | ||
tokens.unshift(w); | ||
tokens.unshift(target); | ||
unconsume(target); | ||
} | ||
@@ -1083,6 +955,4 @@ } | ||
function includes() { | ||
all_ws(); | ||
const target = consume(ID); | ||
if (!target) return; | ||
const w = all_ws(); | ||
if (consume(ID, "includes")) { | ||
@@ -1093,6 +963,4 @@ const ret = { | ||
}; | ||
all_ws(); | ||
const imp = consume(ID) || error("Incomplete includes statement"); | ||
ret["includes"] = imp.value; | ||
all_ws(); | ||
consume(OTHER, ";") || error("No terminating ; for includes statement"); | ||
@@ -1102,5 +970,3 @@ return ret; | ||
// rollback | ||
if (w) | ||
tokens.unshift(w); | ||
tokens.unshift(target); | ||
unconsume(target); | ||
} | ||
@@ -1142,6 +1008,5 @@ } | ||
const obj = { | ||
parse(str, opt) { | ||
if (!opt) opt = {}; | ||
parse(str) { | ||
const tokens = tokenise(str); | ||
return parse(tokens, opt); | ||
return parse(tokens); | ||
} | ||
@@ -1148,0 +1013,0 @@ }; |
{ | ||
"name": "webidl2", | ||
"description": "A WebIDL Parser", | ||
"version": "11.0.0", | ||
"version": "12.0.0", | ||
"contributors": [ | ||
@@ -6,0 +6,0 @@ "Robin Berjon <robin@berjon.com> (https://berjon.com)", |
@@ -48,19 +48,2 @@ | ||
### Advanced Parsing | ||
`parse()` can optionally accept a second parameter, an options object, which can be used to | ||
modify parsing behavior. | ||
The following options are recognized: | ||
```JS | ||
{ | ||
allowNestedTypedefs: false | ||
} | ||
``` | ||
And their meanings are as follows: | ||
* `allowNestedTypedefs`: Boolean indicating whether the parser should accept `typedef`s as valid members of `interface`s. | ||
This is non-standard syntax and therefore the default is `false`. | ||
### Errors | ||
@@ -617,10 +600,2 @@ | ||
In order to run the tests you need to ensure that the widlproc submodule inside `test` is | ||
initialized and up to date: | ||
```Bash | ||
git submodule init | ||
git submodule update | ||
``` | ||
### Running | ||
@@ -627,0 +602,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 2 instances in 1 package
1
100
511880
182
7724
632