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.14 to 1.0.15

474

acorn-es7-plugin.js

@@ -8,11 +8,11 @@ var NotAsync = {} ;

function hasLineTerminatorBeforeNext(st, since) {
return st.lineStart >= since;
return st.lineStart >= since;
}
function test(regex,st,noComment) {
var src = st.input.slice(st.start) ;
if (noComment) {
src = src.replace(removeComments,"$1 $3") ;
var src = st.input.slice(st.start) ;
if (noComment) {
src = src.replace(removeComments,"$1 $3") ;
}
return regex.test(src);
return regex.test(src);
}

@@ -23,5 +23,5 @@

function state(p) {
if (('state' in p) && p.state.constructor && p.state.constructor.name==='State')
return p.state ; // Probably babylon
return p ; // Probably acorn
if (('state' in p) && p.state.constructor && p.state.constructor.name==='State')
return p.state ; // Probably babylon
return p ; // Probably acorn
}

@@ -32,239 +32,271 @@

function subParse(parser, pos, extensions) {
// NB: The Babylon constructor does NOT expect 'pos' as an argument, and so
// the input needs truncation at the start position, however at present
// this doesn't work nicely as all the node location/start/end values
// are therefore offset. Consequently, this plug-in is NOT currently working
// with the (undocumented) Babylon plug-in interface.
var p = new parser.constructor(parser.options, parser.input, pos);
if (extensions)
for (var k in extensions)
p[k] = extensions[k] ;
// NB: The Babylon constructor does NOT expect 'pos' as an argument, and so
// the input needs truncation at the start position, however at present
// this doesn't work nicely as all the node location/start/end values
// are therefore offset. Consequently, this plug-in is NOT currently working
// with the (undocumented) Babylon plug-in interface.
var p = new parser.constructor(parser.options, parser.input, pos);
if (extensions)
for (var k in extensions)
p[k] = extensions[k] ;
var src = state(parser) ;
var dest = state(p) ;
['inFunction','inAsyncFunction','inAsync','inGenerator','inModule'].forEach(function(k){
if (k in src)
dest[k] = src[k] ;
}) ;
p.nextToken();
return p;
var src = state(parser) ;
var dest = state(p) ;
['inFunction','inAsyncFunction','inAsync','inGenerator','inModule'].forEach(function(k){
if (k in src)
dest[k] = src[k] ;
}) ;
p.nextToken();
return p;
}
function asyncAwaitPlugin (parser,options){
var es7check = function(){} ;
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") ;
} ;
}
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") ;
} ;
}
this.reservedWords = new RegExp(this.reservedWords.toString().replace(/await|async/g,"").replace("|/","/").replace("/|","/").replace("||","|")) ;
this.reservedWordsStrict = new RegExp(this.reservedWordsStrict.toString().replace(/await|async/g,"").replace("|/","/").replace("/|","/").replace("||","|")) ;
this.reservedWordsStrictBind = new RegExp(this.reservedWordsStrictBind.toString().replace(/await|async/g,"").replace("|/","/").replace("/|","/").replace("||","|")) ;
this.inAsyncFunction = options.inAsyncFunction ;
if (options.awaitAnywhere && options.inAsyncFunction)
parser.raise(node.start,"The options awaitAnywhere and inAsyncFunction are mutually exclusive") ;
this.inAsyncFunction = options.inAsyncFunction ;
if (options.awaitAnywhere && options.inAsyncFunction)
parser.raise(node.start,"The options awaitAnywhere and inAsyncFunction are mutually exclusive") ;
return base.apply(this,arguments);
}
}) ;
return base.apply(this,arguments);
}
}) ;
parser.extend("shouldParseExportStatement",function(base){
return function(){
if (this.type.label==='name' && this.value==='async' && test(asyncFunction,state(this))) {
return true ;
}
return base.apply(this,arguments) ;
}
}) ;
parser.extend("shouldParseExportStatement",function(base){
return function(){
if (this.type.label==='name' && this.value==='async' && test(asyncFunction,state(this))) {
return true ;
}
return base.apply(this,arguments) ;
}
}) ;
parser.extend("parseStatement",function(base){
return function (declaration, topLevel) {
var st = state(this) ;
var start = st.start;
var startLoc = st.startLoc;
if (st.type.label==='name') {
if (test(asyncFunction,st,true)) {
var wasAsync = st.inAsyncFunction ;
try {
st.inAsyncFunction = true ;
this.next() ;
var r = this.parseStatement(declaration, topLevel) ;
r.async = true ;
r.start = start;
r.loc && (r.loc.start = startLoc);
return r ;
} finally {
st.inAsyncFunction = wasAsync ;
}
} else if ((typeof options==="object" && options.asyncExits) && test(asyncExit,st)) {
// 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 ;
r.start = start;
r.loc && (r.loc.start = startLoc);
return r ;
}
}
return base.apply(this,arguments);
}
}) ;
parser.extend("parseStatement",function(base){
return function (declaration, topLevel) {
var st = state(this) ;
var start = st.start;
var startLoc = st.startLoc;
if (st.type.label==='name') {
if (test(asyncFunction,st,true)) {
var wasAsync = st.inAsyncFunction ;
try {
st.inAsyncFunction = true ;
this.next() ;
var r = this.parseStatement(declaration, topLevel) ;
r.async = true ;
r.start = start;
r.loc && (r.loc.start = startLoc);
return r ;
} finally {
st.inAsyncFunction = wasAsync ;
}
} else if ((typeof options==="object" && options.asyncExits) && test(asyncExit,st)) {
// 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 ;
r.start = start;
r.loc && (r.loc.start = startLoc);
return r ;
}
}
return base.apply(this,arguments);
}
}) ;
parser.extend("parseIdent",function(base){
return function(liberal){
var id = base.apply(this,arguments);
var st = state(this) ;
if (st.inAsyncFunction && id.name==='await') {
if (arguments.length===0) {
this.raise(id.start,"'await' is reserved within async functions") ;
}
}
return id ;
}
}) ;
return function(liberal){
var id = base.apply(this,arguments);
var st = state(this) ;
if (st.inAsyncFunction && id.name==='await') {
if (arguments.length===0) {
this.raise(id.start,"'await' is reserved within async functions") ;
}
}
return id ;
}
}) ;
parser.extend("parseExprAtom",function(base){
return function(refShorthandDefaultPos){
var st = state(this) ;
var start = st.start ;
var startLoc = st.startLoc;
var rhs,r = base.apply(this,arguments);
if (r.type==='Identifier') {
if (r.name==='async' && !hasLineTerminatorBeforeNext(st, r.end)) {
// Is this really an async function?
var isAsync = st.inAsyncFunction ;
try {
st.inAsyncFunction = true ;
var pp = this ;
var inBody = false ;
parser.extend("parseExprAtom",function(base){
return function(refShorthandDefaultPos){
var st = state(this) ;
var start = st.start ;
var startLoc = st.startLoc;
var rhs,r = base.apply(this,arguments);
if (r.type==='Identifier') {
if (r.name==='async' && !hasLineTerminatorBeforeNext(st, r.end)) {
// Is this really an async function?
var isAsync = st.inAsyncFunction ;
try {
st.inAsyncFunction = true ;
var pp = this ;
var inBody = false ;
var parseHooks = {
parseFunctionBody:function(node,isArrowFunction){
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 ;
}
}
} ;
var parseHooks = {
parseFunctionBody:function(node,isArrowFunction){
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 ;
}
}
} ;
rhs = subParse(this,st.start,parseHooks).parseExpression() ;
if (rhs.type==='SequenceExpression')
rhs = rhs.expressions[0] ;
if (rhs.type==='FunctionExpression' || rhs.type==='FunctionDeclaration' || rhs.type==='ArrowFunctionExpression') {
rhs.async = true ;
rhs.start = start;
rhs.loc && (rhs.loc.start = startLoc);
st.pos = rhs.end;
this.next();
es7check(rhs) ;
return rhs ;
}
} catch (ex) {
if (ex!==NotAsync)
throw ex ;
}
finally {
st.inAsyncFunction = isAsync ;
}
}
else if (r.name==='await') {
var n = this.startNodeAt(r.start, r.loc && r.loc.start);
if (st.inAsyncFunction) {
rhs = this.parseExprSubscripts() ;
n.operator = 'await' ;
n.argument = rhs ;
n = this.finishNodeAt(n,'AwaitExpression', rhs.end, rhs.loc && rhs.loc.end) ;
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'.
rhs = subParse(this,st.start,parseHooks).parseExpression() ;
if (rhs.type==='SequenceExpression')
rhs = rhs.expressions[0] ;
if (rhs.type==='FunctionExpression' || rhs.type==='FunctionDeclaration' || rhs.type==='ArrowFunctionExpression') {
rhs.async = true ;
rhs.start = start;
rhs.loc && (rhs.loc.start = startLoc);
st.pos = rhs.end;
this.next();
es7check(rhs) ;
return rhs ;
}
} catch (ex) {
if (ex!==NotAsync)
throw ex ;
}
finally {
st.inAsyncFunction = isAsync ;
}
}
else if (r.name==='await') {
var n = this.startNodeAt(r.start, r.loc && r.loc.start);
if (st.inAsyncFunction) {
rhs = this.parseExprSubscripts() ;
n.operator = 'await' ;
n.argument = rhs ;
n = this.finishNodeAt(n,'AwaitExpression', rhs.end, rhs.loc && rhs.loc.end) ;
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'.
// Look-ahead to see if this is really a property or label called async or await
if (st.input.slice(r.end).match(atomOrPropertyOrLabel))
return r ; // This is a valid property name or label
// Look-ahead to see if this is really a property or label called async or await
if (st.input.slice(r.end).match(atomOrPropertyOrLabel))
return r ; // This is a valid property name or label
if (typeof options==="object" && options.awaitAnywhere) {
start = st.start ;
rhs = subParse(this,start-4).parseExprSubscripts() ;
if (rhs.end<=start) {
rhs = subParse(this,start).parseExprSubscripts() ;
n.operator = 'await' ;
n.argument = rhs ;
n = this.finishNodeAt(n,'AwaitExpression', rhs.end, rhs.loc && rhs.loc.end) ;
st.pos = rhs.end;
this.next();
es7check(n) ;
return n ;
}
}
}
}
return r ;
}
}) ;
if (typeof options==="object" && options.awaitAnywhere) {
start = st.start ;
rhs = subParse(this,start-4).parseExprSubscripts() ;
if (rhs.end<=start) {
rhs = subParse(this,start).parseExprSubscripts() ;
n.operator = 'await' ;
n.argument = rhs ;
n = this.finishNodeAt(n,'AwaitExpression', rhs.end, rhs.loc && rhs.loc.end) ;
st.pos = rhs.end;
this.next();
es7check(n) ;
return n ;
}
}
}
}
return r ;
}
}) ;
parser.extend('finishNodeAt',function(base){
return function(node,type,pos,loc) {
if (node.__asyncValue) {
delete node.__asyncValue ;
node.value.async = true ;
}
return base.apply(this,arguments) ;
}
}) ;
parser.extend('finishNodeAt',function(base){
return function(node,type,pos,loc) {
if (node.__asyncValue) {
delete node.__asyncValue ;
node.value.async = true ;
}
return base.apply(this,arguments) ;
}
}) ;
parser.extend('finishNode',function(base){
return function(node,type) {
if (node.__asyncValue) {
delete node.__asyncValue ;
node.value.async = true ;
}
return base.apply(this,arguments) ;
}
}) ;
parser.extend('finishNode',function(base){
return function(node,type) {
if (node.__asyncValue) {
delete node.__asyncValue ;
node.value.async = true ;
}
return base.apply(this,arguments) ;
}
}) ;
parser.extend("parsePropertyName",function(base){
return function (prop) {
var st = state(this) ;
var key = base.apply(this,arguments) ;
if (key.type === "Identifier" && key.name === "async" && !hasLineTerminatorBeforeNext(st, key.end)) {
// Look-ahead to see if this is really a property or label called async or await
if (!st.input.slice(key.end).match(atomOrPropertyOrLabel)){
es7check(prop) ;
key = base.apply(this,arguments) ;
if (key.type==='Identifier') {
if (key.name==='constructor')
this.raise(key.start,"'constructor()' cannot be be async") ;
else if (key.name==='set')
this.raise(key.start,"'set <member>(value)' cannot be be async") ;
}
prop.__asyncValue = true ;
}
}
return key;
};
}) ;
parser.extend("parsePropertyName",function(base){
return function (prop) {
var st = state(this) ;
var key = base.apply(this,arguments) ;
if (key.type === "Identifier" && key.name === "async" && !hasLineTerminatorBeforeNext(st, key.end)) {
// Look-ahead to see if this is really a property or label called async or await
if (!st.input.slice(key.end).match(atomOrPropertyOrLabel)){
es7check(prop) ;
key = base.apply(this,arguments) ;
if (key.type==='Identifier') {
if (key.name==='constructor')
this.raise(key.start,"'constructor()' cannot be be async") ;
else if (key.name==='set')
this.raise(key.start,"'set <member>(value)' cannot be be async") ;
}
prop.__asyncValue = true ;
}
}
return key;
};
}) ;
parser.extend("parseClassMethod",function(base){
return function (classBody, method, isGenerator) {
var st, wasAsync ;
if (method.__asyncValue) {
st = state(this) ;
wasAsync = st.inAsyncFunction ;
st.inAsyncFunction = true ;
}
var r = base.apply(this,arguments) ;
if (st) {
st.inAsyncFunction = wasAsync ;
}
return r ;
}
}) ;
parser.extend("parsePropertyValue",function(base){
return function (prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors) {
var st, wasAsync ;
if (prop.__asyncValue) {
st = state(this) ;
wasAsync = st.inAsyncFunction ;
st.inAsyncFunction = true ;
}
var r = base.apply(this,arguments) ;
if (st) {
st.inAsyncFunction = wasAsync ;
}
return r ;
}
}) ;
}
module.exports = function(acorn) {
acorn.plugins.asyncawait = asyncAwaitPlugin ;
return acorn
acorn.plugins.asyncawait = asyncAwaitPlugin ;
return acorn
}
{
"name": "acorn-es7-plugin",
"version": "1.0.14",
"version": "1.0.15",
"description": "A plugin for the Acorn parser that understands the ES7 keywords async and await",

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

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

=========
27-Jun-16: v1.0.15
- Fix issue parsing async methods in classes and object literals which (incorrectly) required the `awaitAnywhere` option ([see https://github.com/MatAtBread/acorn-es7-plugin/issues/12](https://github.com/MatAtBread/acorn-es7-plugin/issues/12))
03-May-16: v1.0.14

@@ -109,0 +114,0 @@

@@ -27,3 +27,3 @@ {

"devDependencies": {
"acorn": "^2.5.2",
"acorn": "^3.2.0",
"babel-core": "^6.0.20",

@@ -30,0 +30,0 @@ "babel-preset-es2015": "^6.0.15",

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