Socket
Socket
Sign inDemoInstall

acorn-es7-plugin

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

acorn-es7-plugin - npm Package Compare versions

Comparing version 1.0.0 to 1.0.3

229

acorn-es7-plugin.js

@@ -1,100 +0,159 @@

module.exports = function(acorn) {
var tokens = {
async:new acorn.TokenType("async",{beforeExpr: true, prefix: true, startsExpr: true, keyword: "async"}),
await:new acorn.TokenType("await",{beforeExpr: true, prefix: true, startsExpr: true, keyword: "await"})
} ;
var NotAsync = {} ;
var asyncExit = /^async[\t ]+(return|throw)/ ;
var asyncFunction = /^async[\t ]+function/ ;
acorn.plugins.asyncawait = function(parser,options){
var es7check = function(){} ;
/* Create a new parser derived from the specified parser, so that in the
* event of an error we can back out and try again */
function subParse(parser, how, pos, extensions) {
var p = new parser.constructor(parser.options, parser.input, pos);
if (extensions)
for (var k in extensions)
p[k] = extensions[k] ;
parser.extend("initialContext",function(base){
return function(){
if (this.options.ecmaVersion < 7) {
es7check = function(node) {
parser.raise(node.start,"async/await keywords only available when ecmaVersion>=7") ;
} ;
}
return base.apply(this,arguments);
p.inFunction = parser.inFunction ;
p.inAsyncFunction = parser.inAsyncFunction ;
p.inGenerator = parser.inGenerator ;
p.inModule = parser.inModule ;
p.nextToken();
return p[how]();
}
function asyncAwaitPlugin (parser,options){
var es7check = function(){} ;
parser.extend("initialContext",function(base){
return function(){
if (this.options.ecmaVersion < 7) {
es7check = function(node) {
parser.raise(node.start,"async/await keywords only available when ecmaVersion>=7") ;
} ;
}
}) ;
return base.apply(this,arguments);
}
}) ;
parser.extend("finishNode",function(base){
return function(node,type){
ret = base.call(this,node,type);
if (typeof options==="object" && options.asyncExits
&& (type==='ReturnStatement' || type==='ThrowStatement')) {
if (node.argument && node.argument.operator==='async') {
node.argument = node.argument.argument ;
node.async = true ;
parser.extend("parseStatement",function(base){
return function (declaration, topLevel) {
if (this.type.label==='name') {
if (asyncFunction.test(this.input.slice(this.start))) {
var wasAsync = this.inAsyncFunction ;
try {
this.inAsyncFunction = true ;
this.next() ;
var r = this.parseStatement(declaration, topLevel) ;
r.async = true ;
return r ;
} finally {
this.inAsyncFunction = wasAsync ;
}
}
if (type==='UnaryExpression' && node.operator==='await') {
es7check(node) ;
node.type = 'AwaitExpression' ;
} else if ((typeof options==="object" && options.asyncExits) && asyncExit.test(this.input.slice(this.start))) {
// NON-STANDARD EXTENSION iff. options.asyncExits is set, the
// extensions 'async return <expr>?' and 'async throw <expr>?'
// are enabled. In each case they are the standard ESTree nodes
// with the flag 'async:true'
this.next() ;
var r = this.parseStatement(declaration, topLevel) ;
r.async = true ;
return r ;
}
if (type==='UnaryExpression' && node.operator==='async') {
es7check(node) ;
if (!node.argument.async && (node.argument.type==='FunctionDeclaration' ||
node.argument.type==='FunctionExpression' ||
node.argument.type==='ArrowFunctionExpression')) {
var fn = node.argument ;
delete node.argument ;
delete node.operator ;
delete node.prefix ;
node.async = true ;
Object.keys(fn).forEach(function(k){
if (k!=='start')
node[k] = fn[k] ;
}
return base.apply(this,arguments);
}
}) ;
parser.extend("parseExprAtom",function(base){
return function(refShorthandDefaultPos){
var start = this.start ;
var rhs,r = base.apply(this,arguments);
if (r.type==='Identifier') {
if (r.name==='async' && !/^async[\t ]*\n/.test(this.input.slice(start))) {
// Is this really an async function?
var isAsync = this.inAsyncFunction ;
try {
this.inAsyncFunction = true ;
var pp = this ;
var inBody = false ;
rhs = subParse(this,'parseExpression',this.start,{
parseFunctionBody:function(){
try {
var wasInBody = inBody ;
inBody = true ;
return pp.parseFunctionBody.apply(this,arguments) ;
} finally {
inBody = wasInBody ;
}
},
raise:function(){
try {
return pp.raise.apply(this,arguments) ;
} catch(ex) {
throw inBody?ex:NotAsync ;
}
}
}) ;
if (rhs.type==='SequenceExpression')
rhs = rhs.expressions[0] ;
if (rhs.type==='FunctionExpression' || rhs.type==='FunctionDeclaration' || rhs.type==='ArrowFunctionExpression') {
rhs.async = true ;
this.pos = rhs.end ;
this.next();
es7check(rhs) ;
return rhs ;
}
} catch (ex) {
if (ex!==NotAsync)
throw ex ;
}
finally {
this.inAsyncFunction = isAsync ;
}
}
if (type==='ExpressionStatement' && node.expression.type==='FunctionExpression' && node.expression.async) {
es7check(node) ;
var fn = node.expression ;
fn.type = 'FunctionDeclaration' ;
delete node.expression ;
Object.keys(fn).forEach(function(k){
if (k!=='start')
node[k] = fn[k] ;
}) ;
}
return ret ;
}
}) ;
parser.extend("finishToken",function(base){
return function(type,val){
type = type || (tokens.hasOwnProperty(val) && tokens[val]) ;
return base.call(this,type,val);
}
}) ;
parser.extend("isKeyword",function(base){
return function(str){
if (str==="async") {
this.potentialArrowAt = this.start+str.length+1 ;
return true ;
else if (r.name==='await') {
var n = this.startNode() ;
if (this.inAsyncFunction) {
rhs = this.parseExprSubscripts() ;
n.operator = 'await' ;
n.argument = rhs ;
n = this.finishNodeAt(n,'AwaitExpression', rhs.end, rhs.loc) ;
es7check(n) ;
return n ;
} else
// NON-STANDARD EXTENSION iff. options.awaitAnywhere is true,
// an 'AwaitExpression' is allowed anywhere the token 'await'
// could not be an identifier with the name 'await'.
if (typeof options==="object" && options.awaitAnywhere) {
var start = this.start ;
rhs = subParse(this,'parseExprSubscripts',this.start-4) ;
if (rhs.end<=start) {
rhs = subParse(this,'parseExprSubscripts',this.start) ;
n.operator = 'await' ;
n.argument = rhs ;
n = this.finishNodeAt(n,'AwaitExpression', rhs.end, rhs.loc) ;
this.pos = rhs.end ;
this.next();
es7check(n) ;
return n ;
}
}
}
return tokens.hasOwnProperty(str) || base.apply(this,arguments);
}
}) ;
return r ;
}
}) ;
parser.extend("isReservedWord",function(base){
return function(str){
return tokens.hasOwnProperty(str) || base.apply(this,arguments);
parser.extend("parsePropertyName",function(base){
return function (prop) {
var key = base.apply(this,arguments) ;
if (key.type === "Identifier" && key.name === "async") {
es7check(prop) ;
prop.async = true ;
key = base.apply(this,arguments) ;
}
}) ;
return key;
};
}) ;
}
parser.extend("parsePropertyName",function(base){
return function (prop) {
var key = base.apply(this,arguments) ;
if (key.type === "Identifier" && key.name === "async") {
es7check(prop) ;
prop.async = true ;
key = base.apply(this,arguments) ;
}
return key;
};
}) ;
}
module.exports = function(acorn) {
acorn.plugins.asyncawait = asyncAwaitPlugin ;
}
{
"name": "acorn-es7-plugin",
"version": "1.0.0",
"version": "1.0.3",
"description": "A plugin for the Acorn parser that understands the ES7 keywords async and await",

@@ -5,0 +5,0 @@ "main": "acorn-es7-plugin.js",

@@ -33,1 +33,12 @@ [![NPM](https://nodei.co/npm/acorn-es7-plugin.png?downloads=true&downloadRank=true)](https://nodei.co/npm/acorn-es7-plugin/)

console.log(JSON.stringify(ast,null,2)) ;
Options & Compliance
====================
The parser attempts to enforce strict contextualisation of `async` and `await`. Specifically, `async` is only a keyword if it precedes a function declaration, function expression or arrow function. `await` is only a keyword inside an `async` function. Outside of these contexts, both tokens are treated as identifiers (as they were in ES6 and earlier).
When using the plugin, you can supply an object in place of the 'true' flag with the following options.
| flag | meaning |
|------|---------|
| awaitAnywhere | If `await` is used outside of an async function and could not be an identifier, generate an AwaitExpression node. This typically means you can use `await` anywhere _except_ when its argument would require parentheses, as this parses to a call to 'await(....)'. |
| asyncExits | Allow the additional sequences `async return <optional-expression>` and `async throw <optional-expression>`. These sequences are used with [nodent](https://github.com/MatAtBread/nodent). In each case, as with async functions, a standard ReturnStatement (or ThrowStatement) node is generated, with an additional member 'async' set to true.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc