acorn
Advanced tools
Comparing version 0.11.0 to 0.12.0
@@ -48,3 +48,2 @@ // Acorn: Loose parser | ||
input = String(inpt); | ||
if (/^#!.*/.test(input)) input = "//" + input.slice(2); | ||
fetchToken = acorn.tokenize(input, opts); | ||
@@ -63,10 +62,10 @@ options = fetchToken.options; | ||
function next(forceRegexp) { | ||
function next() { | ||
lastEnd = token.end; | ||
if (options.locations) | ||
lastEndLoc = token.endLoc; | ||
if (forceRegexp) | ||
ahead.length = 0; | ||
lastEndLoc = token.loc && token.loc.end; | ||
token = ahead.shift() || readToken(forceRegexp); | ||
token = ahead.shift() || readToken(); | ||
if (options.onToken) | ||
options.onToken(token); | ||
@@ -82,7 +81,7 @@ if (token.start >= nextLineStart) { | ||
function readToken(forceRegexp) { | ||
function readToken() { | ||
for (;;) { | ||
try { | ||
var tok = fetchToken(forceRegexp); | ||
if (tok.type === tt.dot && input.substr(tok.end, 1) === '.') { | ||
var tok = fetchToken(); | ||
if (tok.type === tt.dot && input.substr(tok.end, 1) === '.' && options.ecmaVersion >= 6) { | ||
tok = fetchToken(); | ||
@@ -108,4 +107,6 @@ tok.start--; | ||
replace = {start: e.pos, end: pos, | ||
type: input.charAt(e.pos) == "`" ? tt.template : tt.templateContinued, | ||
value: input.slice(e.pos + 1, pos)}; | ||
type: tt.template, | ||
value: input.slice(e.pos, pos)}; | ||
} else if (/comment/.test(msg)) { | ||
replace = fetchToken.current(); | ||
} else { | ||
@@ -133,4 +134,4 @@ replace = false; | ||
if (options.locations) { | ||
replace.startLoc = acorn.getLineInfo(input, replace.start); | ||
replace.endLoc = acorn.getLineInfo(input, replace.end); | ||
replace.loc = new SourceLocation(acorn.getLineInfo(input, replace.start)); | ||
replace.loc.end = acorn.getLineInfo(input, replace.end); | ||
} | ||
@@ -217,3 +218,3 @@ return replace; | ||
function SourceLocation(start) { | ||
this.start = start || token.startLoc || {line: 1, column: 0}; | ||
this.start = start || token.loc.start || {line: 1, column: 0}; | ||
this.end = null; | ||
@@ -235,3 +236,3 @@ if (sourceFile !== null) this.source = sourceFile; | ||
function storeCurrentPos() { | ||
return options.locations ? [token.start, token.startLoc] : token.start; | ||
return options.locations ? [token.start, token.loc.start] : token.start; | ||
} | ||
@@ -244,2 +245,3 @@ | ||
node.loc = new SourceLocation(pos[1]); | ||
pos = pos[0]; | ||
} else { | ||
@@ -251,3 +253,3 @@ node = new Node(pos); | ||
if (options.ranges) | ||
node.range = [pos[0], 0]; | ||
node.range = [pos, 0]; | ||
return node; | ||
@@ -266,10 +268,2 @@ } | ||
function finishNodeAt(node, type, pos) { | ||
if (options.locations) { node.loc.end = pos[1]; pos = pos[0]; } | ||
node.type = type; | ||
node.end = pos; | ||
if (options.ranges) node.range[1] = pos; | ||
return node; | ||
} | ||
function dummyIdent() { | ||
@@ -291,5 +285,14 @@ var dummy = startNode(); | ||
function isContextual(name) { | ||
return token.type === tt.name && token.value === name; | ||
} | ||
function eatContextual(name) { | ||
return token.value === name && eat(tt.name); | ||
} | ||
function canInsertSemicolon() { | ||
return (token.type === tt.eof || token.type === tt.braceR || newline.test(input.slice(lastEnd, token.start))); | ||
} | ||
function semicolon() { | ||
@@ -318,3 +321,4 @@ return eat(tt.semi); | ||
case "ArrayPattern": | ||
case "SpreadElement": | ||
case "RestElement": | ||
case "AssignmentPattern": | ||
return expr; | ||
@@ -332,3 +336,3 @@ | ||
lastEnd = token.end; | ||
lastEndLoc = token.endLoc; | ||
lastEndLoc = token.loc && token.loc.end; | ||
return finishNode(node, "Program"); | ||
@@ -338,5 +342,2 @@ } | ||
function parseStatement() { | ||
if (token.type === tt.slash || token.type === tt.assign && token.value === "/=") | ||
next(true); | ||
var starttype = token.type, node = startNode(); | ||
@@ -375,3 +376,3 @@ | ||
var init = parseVar(true); | ||
if (init.declarations.length === 1 && (token.type === tt._in || token.type === tt.name && token.value === "of")) { | ||
if (init.declarations.length === 1 && (token.type === tt._in || isContextual("of"))) { | ||
return parseForIn(node, init); | ||
@@ -381,5 +382,5 @@ } | ||
} | ||
var init = parseExpression(false, true); | ||
if (token.type === tt._in || token.type === tt.name && token.value === "of") { | ||
return parseForIn(node, checkLVal(init)); | ||
var init = parseExpression(true); | ||
if (token.type === tt._in || isContextual("of")) { | ||
return parseForIn(node, toAssignable(init)); | ||
} | ||
@@ -451,3 +452,3 @@ return parseFor(node, init); | ||
expect(tt.parenL); | ||
clause.param = parseIdent(); | ||
clause.param = toAssignable(parseExprAtom()); | ||
expect(tt.parenR); | ||
@@ -556,3 +557,3 @@ clause.guard = null; | ||
decl.id = options.ecmaVersion >= 6 ? toAssignable(parseExprAtom()) : parseIdent(); | ||
decl.init = eat(tt.eq) ? parseExpression(true, noIn) : null; | ||
decl.init = eat(tt.eq) ? parseMaybeAssign(noIn) : null; | ||
node.declarations.push(finishNode(decl, "VariableDeclarator")); | ||
@@ -569,6 +570,6 @@ } while (eat(tt.comma)); | ||
function parseExpression(noComma, noIn) { | ||
function parseExpression(noIn) { | ||
var start = storeCurrentPos(); | ||
var expr = parseMaybeAssign(noIn); | ||
if (!noComma && token.type === tt.comma) { | ||
if (token.type === tt.comma) { | ||
var node = startNodeAt(start); | ||
@@ -611,4 +612,4 @@ node.expressions = [expr]; | ||
node.test = expr; | ||
node.consequent = parseExpression(true); | ||
node.alternate = expect(tt.colon) ? parseExpression(true, noIn) : dummyIdent(); | ||
node.consequent = parseMaybeAssign(); | ||
node.alternate = expect(tt.colon) ? parseMaybeAssign(noIn) : dummyIdent(); | ||
return finishNode(node, "ConditionalExpression"); | ||
@@ -649,10 +650,3 @@ } | ||
if (token.type.prefix) { | ||
var node = startNode(), update = token.type.isUpdate, nodeType; | ||
if (token.type === tt.ellipsis) { | ||
nodeType = "SpreadElement"; | ||
} else { | ||
nodeType = update ? "UpdateExpression" : "UnaryExpression"; | ||
node.operator = token.value; | ||
node.prefix = true; | ||
} | ||
var node = startNode(), update = token.type.isUpdate; | ||
node.operator = token.value; | ||
@@ -663,3 +657,8 @@ node.prefix = true; | ||
if (update) node.argument = checkLVal(node.argument); | ||
return finishNode(node, nodeType); | ||
return finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); | ||
} else if (token.type === tt.ellipsis) { | ||
var node = startNode(); | ||
next(); | ||
node.argument = parseMaybeUnary(noIn); | ||
return finishNode(node, "SpreadElement"); | ||
} | ||
@@ -718,3 +717,3 @@ var start = storeCurrentPos(); | ||
base = finishNode(node, "CallExpression"); | ||
} else if (token.type == tt.template) { | ||
} else if (token.type == tt.backQuote) { | ||
var node = startNodeAt(start); | ||
@@ -808,7 +807,7 @@ node.tag = base; | ||
node.delegate = eat(tt.star); | ||
node.argument = parseExpression(true); | ||
node.argument = parseMaybeAssign(); | ||
} | ||
return finishNode(node, "YieldExpression"); | ||
case tt.template: | ||
case tt.backQuote: | ||
return parseTemplate(); | ||
@@ -836,9 +835,10 @@ | ||
function parseTemplateElement() { | ||
var elem = startNodeAt(options.locations ? [token.start + 1, token.startLoc.offset(1)] : token.start + 1); | ||
elem.value = token.value; | ||
elem.tail = input.charCodeAt(token.end - 1) !== 123; // '{' | ||
var endOff = elem.tail ? 1 : 2; | ||
var endPos = options.locations ? [token.end - endOff, token.endLoc.offset(-endOff)] : token.end - endOff; | ||
var elem = startNode(); | ||
elem.value = { | ||
raw: input.slice(token.start, token.end), | ||
cooked: token.value | ||
}; | ||
next(); | ||
return finishNodeAt(elem, "TemplateElement", endPos); | ||
elem.tail = token.type === tt.backQuote; | ||
return finishNode(elem, "TemplateElement"); | ||
} | ||
@@ -848,2 +848,3 @@ | ||
var node = startNode(); | ||
next(); | ||
node.expressions = []; | ||
@@ -853,17 +854,14 @@ var curElt = parseTemplateElement(); | ||
while (!curElt.tail) { | ||
var next = parseExpression(); | ||
if (isDummy(next)) { | ||
node.quasis[node.quasis.length - 1].tail = true; | ||
break; | ||
} | ||
node.expressions.push(next); | ||
if (token.type === tt.templateContinued) { | ||
node.quasis.push(curElt = parseTemplateElement()); | ||
next(); | ||
node.expressions.push(parseExpression()); | ||
if (expect(tt.braceR)) { | ||
curElt = parseTemplateElement(); | ||
} else { | ||
curElt = startNode(); | ||
curElt.value = {cooked: "", raw: ""}; | ||
curElt.value = {cooked: '', raw: ''}; | ||
curElt.tail = true; | ||
node.quasis.push(curElt); | ||
} | ||
node.quasis.push(curElt); | ||
} | ||
expect(tt.backQuote); | ||
return finishNode(node, "TemplateLiteral"); | ||
@@ -878,2 +876,3 @@ } | ||
else if (isStatement) node.id = dummyIdent(); | ||
else node.id = null; | ||
node.superClass = eat(tt._extends) ? parseExpression() : null; | ||
@@ -890,7 +889,9 @@ node.body = startNode(); | ||
while (!closes(tt.braceR, indent, line)) { | ||
var prop = startNode(), isGenerator; | ||
if (isClass && semicolon()) continue; | ||
var prop = startNode(), isGenerator, start; | ||
if (options.ecmaVersion >= 6) { | ||
if (isClass) { | ||
if (prop['static'] = (token.type === tt.name && token.value === "static")) next(); | ||
prop['static'] = false; | ||
} else { | ||
start = storeCurrentPos(); | ||
prop.method = false; | ||
@@ -902,6 +903,16 @@ prop.shorthand = false; | ||
parsePropertyName(prop); | ||
if (isDummy(prop.key)) { if (isDummy(parseExpression(true))) next(); eat(tt.comma); continue; } | ||
if (isDummy(prop.key)) { if (isDummy(parseMaybeAssign())) next(); eat(tt.comma); continue; } | ||
if (isClass) { | ||
if (prop.key.type === "Identifier" && !prop.computed && prop.key.name === "static" && | ||
(token.type != tt.parenL && token.type != tt.braceL)) { | ||
prop['static'] = true; | ||
isGenerator = eat(tt.star); | ||
parsePropertyName(prop); | ||
} else { | ||
prop['static'] = false; | ||
} | ||
} | ||
if (!isClass && eat(tt.colon)) { | ||
prop.kind = "init"; | ||
prop.value = parseExpression(true); | ||
prop.value = parseMaybeAssign(); | ||
} else if (options.ecmaVersion >= 6 && (token.type === tt.parenL || token.type === tt.braceL)) { | ||
@@ -916,3 +927,4 @@ if (isClass) { | ||
} else if (options.ecmaVersion >= 5 && prop.key.type === "Identifier" && | ||
(prop.key.name === "get" || prop.key.name === "set")) { | ||
!prop.computed && (prop.key.name === "get" || prop.key.name === "set") && | ||
(token.type != tt.comma && token.type != tt.braceR)) { | ||
prop.kind = prop.key.name; | ||
@@ -926,3 +938,15 @@ parsePropertyName(prop); | ||
prop.kind = "init"; | ||
prop.value = options.ecmaVersion >= 6 ? prop.key : dummyIdent(); | ||
if (options.ecmaVersion >= 6) { | ||
if (eat(tt.eq)) { | ||
var assign = startNodeAt(start); | ||
assign.operator = "="; | ||
assign.left = prop.key; | ||
assign.right = parseMaybeAssign(); | ||
prop.value = finishNode(assign, "AssignmentExpression"); | ||
} else { | ||
prop.value = prop.key; | ||
} | ||
} else { | ||
prop.value = dummyIdent(); | ||
} | ||
prop.shorthand = true; | ||
@@ -933,3 +957,2 @@ } | ||
node.body.body.push(finishNode(prop, "MethodDefinition")); | ||
semicolon(); | ||
} else { | ||
@@ -945,3 +968,3 @@ node.properties.push(finishNode(prop, "Property")); | ||
lastEnd = token.start; | ||
if (options.locations) lastEndLoc = token.startLoc; | ||
if (options.locations) lastEndLoc = token.loc.start; | ||
} | ||
@@ -979,3 +1002,2 @@ if (isClass) { | ||
node.name = token.type === tt.name ? token.value : token.type.keyword; | ||
fetchToken.noRegexp(); | ||
next(); | ||
@@ -989,4 +1011,2 @@ return finishNode(node, "Identifier"); | ||
if (options.ecmaVersion >= 6) { | ||
node.defaults = []; | ||
node.rest = null; | ||
node.generator = false; | ||
@@ -1007,3 +1027,3 @@ node.expression = false; | ||
for (var i = 0; i < props.length; i++) { | ||
props[i].value = toAssignable(props[i].value); | ||
toAssignable(props[i].value); | ||
} | ||
@@ -1014,11 +1034,13 @@ break; | ||
node.type = "ArrayPattern"; | ||
var elms = node.elements; | ||
for (var i = 0; i < elms.length; i++) { | ||
elms[i] = toAssignable(elms[i]); | ||
} | ||
toAssignableList(node.elements); | ||
break; | ||
case "SpreadElement": | ||
node.type = "RestElement"; | ||
node.argument = toAssignable(node.argument); | ||
break; | ||
case "AssignmentExpression": | ||
node.type = "AssignmentPattern"; | ||
break; | ||
} | ||
@@ -1029,29 +1051,13 @@ } | ||
function parseFunctionParams(node, params) { | ||
var defaults = [], hasDefaults = false; | ||
if (!params) { | ||
pushCx(); | ||
params = parseExprList(tt.parenR); | ||
function toAssignableList(exprList) { | ||
for (var i = 0; i < exprList.length; i++) { | ||
toAssignable(exprList[i]); | ||
} | ||
for (var i = 0; i < params.length; i++) { | ||
var param = params[i], defValue = null; | ||
if (param.type === "AssignmentExpression") { | ||
defValue = param.right; | ||
param = param.left; | ||
} | ||
param = toAssignable(param); | ||
if (param.type === "SpreadElement") { | ||
param = param.argument; | ||
if (i === params.length - 1) { | ||
node.rest = param; | ||
continue; | ||
} | ||
} | ||
node.params.push(param); | ||
defaults.push(defValue); | ||
if (defValue) hasDefaults = true; | ||
} | ||
return exprList; | ||
} | ||
if (hasDefaults) node.defaults = defaults; | ||
function parseFunctionParams(params) { | ||
pushCx(); | ||
params = parseExprList(tt.parenR); | ||
return toAssignableList(params); | ||
} | ||
@@ -1066,3 +1072,3 @@ | ||
else if (isStatement) node.id = dummyIdent(); | ||
parseFunctionParams(node); | ||
node.params = parseFunctionParams(); | ||
node.body = parseBlock(); | ||
@@ -1075,6 +1081,6 @@ return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); | ||
initFunction(node); | ||
parseFunctionParams(node); | ||
node.params = parseFunctionParams(); | ||
node.generator = isGenerator || false; | ||
node.expression = options.ecmaVersion >= 6 && token.type !== tt.braceL; | ||
node.body = node.expression ? parseExpression(true) : parseBlock(); | ||
node.body = node.expression ? parseMaybeAssign() : parseBlock(); | ||
return finishNode(node, "FunctionExpression"); | ||
@@ -1085,5 +1091,5 @@ } | ||
initFunction(node); | ||
parseFunctionParams(node, params); | ||
node.params = toAssignableList(params); | ||
node.expression = token.type !== tt.braceL; | ||
node.body = node.expression ? parseExpression(true) : parseBlock(); | ||
node.body = node.expression ? parseMaybeAssign() : parseBlock(); | ||
return finishNode(node, "ArrowFunctionExpression"); | ||
@@ -1098,3 +1104,10 @@ } | ||
if (node['default']) { | ||
node.declaration = parseExpression(); | ||
var expr = parseMaybeAssign(); | ||
if (expr.id) { | ||
switch (expr.type) { | ||
case "FunctionExpression": expr.type = "FunctionDeclaration"; break; | ||
case "ClassExpression": expr.type = "ClassDeclaration"; break; | ||
} | ||
} | ||
node.declaration = expr; | ||
semicolon(); | ||
@@ -1141,6 +1154,3 @@ } else if (token.type.keyword) { | ||
next(); | ||
if (token.type === tt.name && token.value === "as") { | ||
next(); | ||
elt.name = parseIdent(); | ||
} | ||
if (eatContextual("as")) elt.name = parseIdent(); | ||
elts.push(finishNode(elt, prefix + "BatchSpecifier")); | ||
@@ -1154,18 +1164,9 @@ } else { | ||
var elt = startNode(); | ||
if (token.type === tt.star) { | ||
next(); | ||
if (token.type === tt.name && token.value === "as") { | ||
next(); | ||
elt.name = parseIdent(); | ||
} | ||
if (eat(tt.star)) { | ||
if (eatContextual("as")) elt.name = parseIdent(); | ||
finishNode(elt, prefix + "BatchSpecifier"); | ||
} else { | ||
if (token.type === tt.name && token.value === "from") break; | ||
if (isContextual("from")) break; | ||
elt.id = parseIdent(); | ||
if (token.type === tt.name && token.value === "as") { | ||
next(); | ||
elt.name = parseIdent(); | ||
} else { | ||
elt.name = null; | ||
} | ||
elt.name = eatContextual("as") ? parseIdent() : null; | ||
finishNode(elt, prefix + "Specifier"); | ||
@@ -1179,8 +1180,3 @@ } | ||
} | ||
if (token.type === tt.name && token.value === "from") { | ||
next(); | ||
node.source = parseExprAtom(); | ||
} else { | ||
node.source = null; | ||
} | ||
node.source = eatContextual("from") ? parseExprAtom() : null; | ||
} | ||
@@ -1196,3 +1192,3 @@ | ||
} | ||
var elt = parseExpression(true); | ||
var elt = parseMaybeAssign(); | ||
if (isDummy(elt)) { | ||
@@ -1211,3 +1207,3 @@ if (closes(close, indent, line)) break; | ||
lastEnd = token.start; | ||
if (options.locations) lastEndLoc = token.startLoc; | ||
if (options.locations) lastEndLoc = token.loc.start; | ||
} | ||
@@ -1214,0 +1210,0 @@ return elts; |
@@ -6,3 +6,3 @@ { | ||
"main": "acorn.js", | ||
"version": "0.11.0", | ||
"version": "0.12.0", | ||
"engines": {"node": ">=0.4.0"}, | ||
@@ -18,3 +18,3 @@ "maintainers": [{"name": "Marijn Haverbeke", | ||
"test": "node test/run.js", | ||
"prepublish": "bin/without_eval > acorn_csp.js" | ||
"prepublish": "node bin/without_eval > acorn_csp.js" | ||
}, | ||
@@ -21,0 +21,0 @@ "bin": {"acorn": "./bin/acorn"}, |
# Acorn | ||
[![Build Status](https://travis-ci.org/marijnh/acorn.svg?branch=master)](https://travis-ci.org/marijnh/acorn) | ||
[![NPM version](https://img.shields.io/npm/v/acorn.svg)](https://www.npmjs.org/package/acorn) | ||
[Author funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png)](https://marijnhaverbeke.nl/fund/) | ||
@@ -75,2 +77,6 @@ A tiny, fast JavaScript parser, written completely in JavaScript. | ||
- **allowHashBang**: When this is enabled (off by default), if the | ||
code starts with the characters `#!` (as in a shellscript), the | ||
first line will be treated as a comment. | ||
- **locations**: When `true`, each node has a `loc` object attached | ||
@@ -162,2 +168,13 @@ with `start` and `end` subobjects, each of which contains the | ||
In ES6 environment, returned result can be used as any other protocol-compliant iterable: | ||
```javascript | ||
for (let token of acorn.tokenize(str)) { | ||
// iterate over the tokens | ||
} | ||
// transform code to array of tokens: | ||
var tokens = [...acorn.tokenize(str)]; | ||
``` | ||
**tokTypes** holds an object mapping names to the token type objects | ||
@@ -220,3 +237,3 @@ that end up in the `type` properties of tokens. | ||
sense of the input. Depends on `acorn.js`, because it uses the same | ||
tokenizer. The loose parser does not support ECMAScript 6 syntax yet. | ||
tokenizer. | ||
@@ -223,0 +240,0 @@ ### util/walk.js ### |
@@ -175,3 +175,3 @@ // AST walker module for Mozilla Parser API compatible trees | ||
base.EmptyStatement = ignore; | ||
base.ExpressionStatement = function(node, st, c) { | ||
base.ExpressionStatement = base.ParenthesizedExpression = function(node, st, c) { | ||
c(node.expression, st, "Expression"); | ||
@@ -204,3 +204,3 @@ }; | ||
}; | ||
base.ThrowStatement = base.SpreadElement = function(node, st, c) { | ||
base.ThrowStatement = base.SpreadElement = base.RestElement = function(node, st, c) { | ||
c(node.argument, st, "Expression"); | ||
@@ -254,3 +254,3 @@ }; | ||
base.ThisExpression = ignore; | ||
base.ArrayExpression = function(node, st, c) { | ||
base.ArrayExpression = base.ArrayPattern = function(node, st, c) { | ||
for (var i = 0; i < node.elements.length; ++i) { | ||
@@ -261,3 +261,3 @@ var elt = node.elements[i]; | ||
}; | ||
base.ObjectExpression = function(node, st, c) { | ||
base.ObjectExpression = base.ObjectPattern = function(node, st, c) { | ||
for (var i = 0; i < node.properties.length; ++i) | ||
@@ -274,3 +274,3 @@ c(node.properties[i], st); | ||
}; | ||
base.BinaryExpression = base.AssignmentExpression = base.LogicalExpression = function(node, st, c) { | ||
base.BinaryExpression = base.AssignmentExpression = base.AssignmentPattern = base.LogicalExpression = function(node, st, c) { | ||
c(node.left, st, "Expression"); | ||
@@ -293,3 +293,11 @@ c(node.right, st, "Expression"); | ||
}; | ||
base.Identifier = base.Literal = base.ExportDeclaration = base.ImportDeclaration = ignore; | ||
base.ExportDeclaration = function (node, st, c) { | ||
c(node.declaration, st); | ||
}; | ||
base.ImportDeclaration = function (node, st, c) { | ||
node.specifiers.forEach(function (specifier) { | ||
c(specifier, st); | ||
}); | ||
}; | ||
base.ImportSpecifier = base.ImportBatchSpecifier = base.Identifier = base.Literal = ignore; | ||
@@ -296,0 +304,0 @@ base.TaggedTemplateExpression = function(node, st, c) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses eval() which is a dangerous function. This prevents the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
314
283554
18
6605