"use strict" ;
var _ interopRequire = function ( obj ) { return obj && obj . __ esModule ? obj [ "default" ] : obj ; } ;
var _ createClass = ( function ( ) { function defineProperties ( target , props ) { for ( var key in props ) { var prop = props [ key ] ; prop . configurable = true ; if ( prop . value ) prop . writable = true ; } Object . defineProperties ( target , props ) ; } return function ( Constructor , protoProps , staticProps ) { if ( protoProps ) defineProperties ( Constructor . prototype , protoProps ) ; if ( staticProps ) defineProperties ( Constructor , staticProps ) ; return Constructor ; } ; } ) ( ) ;
var _ get = function get ( object , property , receiver ) { var desc = Object . getOwnPropertyDescriptor ( object , property ) ; if ( desc === undefined ) { var parent = Object . getPrototypeOf ( object ) ; if ( parent === null ) { return undefined ; } else { return get ( parent , property , receiver ) ; } } else if ( "value" in desc && desc . writable ) { return desc . value ; } else { var getter = desc . get ; if ( getter === undefined ) { return undefined ; } return getter . call ( receiver ) ; } } ;
var _ inherits = function ( subClass , superClass ) { if ( typeof superClass !== "function" && superClass !== null ) { throw new TypeError ( "Super expression must either be null or a function, not " + typeof superClass ) ; } subClass . prototype = Object . create ( superClass && superClass . prototype , { constructor : { value : subClass , enumerable : false , writable : true , configurable : true } } ) ; if ( superClass ) subClass . __ proto__ = superClass ; } ;
var _ classCallCheck = function ( instance , Constructor ) { if ( ! ( instance instanceof Constructor ) ) { throw new TypeError ( "Cannot call a class as a function" ) ; } } ;
/ *
Copyright ( C ) 2015 Yusuke Suzuki < utatane . tea @ gmail . com >
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions are met :
* Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED . IN NO EVENT SHALL < COPYRIGHT HOLDER > BE LIABLE FOR ANY
DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
var Syntax = require ( "estraverse" ) . Syntax ;
var esrecurse = _ interopRequire ( require ( "esrecurse" ) ) ;
var Reference = _ interopRequire ( require ( "./reference" ) ) ;
var Variable = _ interopRequire ( require ( "./variable" ) ) ;
var _ definition = require ( "./definition" ) ;
var ParameterDefinition = _ definition . ParameterDefinition ;
var Definition = _ definition . Definition ;
var assert = _ interopRequire ( require ( "assert" ) ) ;
var PatternVisitor = ( function ( _ esrecurse$Visitor ) {
function PatternVisitor ( rootPattern , callback ) {
_ classCallCheck ( this , PatternVisitor ) ;
_ get ( Object . getPrototypeOf ( PatternVisitor . prototype ) , "constructor" , this ) . call ( this ) ;
this . rootPattern = rootPattern ;
this . callback = callback ;
this . assignments = [ ] ;
this . rightHandNodes = [ ] ;
this . restElements = [ ] ;
}
_ inherits ( PatternVisitor , _ esrecurse$Visitor ) ;
_ createClass ( PatternVisitor , {
Identifier : {
value : function Identifier ( pattern ) {
var lastRestElement = getLast ( this . restElements ) ;
this . callback ( pattern , {
topLevel : pattern === this . rootPattern ,
rest : lastRestElement != null && lastRestElement . argument === pattern ,
assignments : this . assignments
} ) ;
}
} ,
ObjectPattern : {
value : function ObjectPattern ( pattern ) {
var i , iz , property ;
for ( i = 0 , iz = pattern . properties . length ; i < iz ; ++ i ) {
property = pattern . properties [ i ] ;
// Computed property's key is a right hand node.
if ( property . computed ) {
this . rightHandNodes . push ( property . key ) ;
}
// If it's shorthand, its key is same as its value.
// If it's shorthand and has its default value, its key is same as its value.left (the value is AssignmentPattern).
// If it's not shorthand, the name of new variable is its value's.
this . visit ( property . value ) ;
}
}
} ,
ArrayPattern : {
value : function ArrayPattern ( pattern ) {
var i , iz , element ;
for ( i = 0 , iz = pattern . elements . length ; i < iz ; ++ i ) {
element = pattern . elements [ i ] ;
this . visit ( element ) ;
}
}
} ,
AssignmentPattern : {
value : function AssignmentPattern ( pattern ) {
this . assignments . push ( pattern ) ;
this . visit ( pattern . left ) ;
this . rightHandNodes . push ( pattern . right ) ;
this . assignments . pop ( ) ;
}
} ,
RestElement : {
value : function RestElement ( pattern ) {
this . restElements . push ( pattern ) ;
this . visit ( pattern . argument ) ;
this . restElements . pop ( ) ;
}
} ,
MemberExpression : {
value : function MemberExpression ( node ) {
// Computed property's key is a right hand node.
if ( node . computed ) {
this . rightHandNodes . push ( node . property ) ;
}
// the object is only read, write to its property.
this . rightHandNodes . push ( node . object ) ;
}
} ,
SpreadElement : {
//
// ForInStatement.left and AssignmentExpression.left are LeftHandSideExpression.
// By spec, LeftHandSideExpression is Pattern or MemberExpression.
// (see also: https://github.com/estree/estree/pull/20#issuecomment-74584758)
// But espree 2.0 and esprima 2.0 parse to ArrayExpression, ObjectExpression, etc...
//
value : function SpreadElement ( node ) {
this . visit ( node . argument ) ;
}
} ,
ArrayExpression : {
value : function ArrayExpression ( node ) {
node . elements . forEach ( this . visit , this ) ;
}
} ,
ObjectExpression : {
value : function ObjectExpression ( node ) {
var _ this = this ;
node . properties . forEach ( function ( property ) {
// Computed property's key is a right hand node.
if ( property . computed ) {
_ this . rightHandNodes . push ( property . key ) ;
}
_ this . visit ( property . value ) ;
} ) ;
}
} ,
AssignmentExpression : {
value : function AssignmentExpression ( node ) {
this . assignments . push ( node ) ;
this . visit ( node . left ) ;
this . rightHandNodes . push ( node . right ) ;
this . assignments . pop ( ) ;
}
} ,
CallExpression : {
value : function CallExpression ( node ) {
var _ this = this ;
// arguments are right hand nodes.
node . arguments . forEach ( function ( a ) {
_ this . rightHandNodes . push ( a ) ;
} ) ;
this . visit ( node . callee ) ;
}
}
} ) ;
return PatternVisitor ;
} ) ( esrecurse . Visitor ) ;
function getLast ( xs ) {
return xs [ xs . length - 1 ] || null ;
}
function traverseIdentifierInPattern ( rootPattern , referencer , callback ) {
// Call the callback at left hand identifier nodes, and Collect right hand nodes.
var visitor = new PatternVisitor ( rootPattern , callback ) ;
visitor . visit ( rootPattern ) ;
// Process the right hand nodes recursively.
if ( referencer != null ) {
visitor . rightHandNodes . forEach ( referencer . visit , referencer ) ;
}
}
function isPattern ( node ) {
var nodeType = node . type ;
return nodeType === Syntax . Identifier || nodeType === Syntax . ObjectPattern || nodeType === Syntax . ArrayPattern || nodeType === Syntax . SpreadElement || nodeType === Syntax . RestElement || nodeType === Syntax . AssignmentPattern ;
}
// Importing ImportDeclaration.
// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-moduledeclarationinstantiation
// https://github.com/estree/estree/blob/master/es6.md#importdeclaration
// FIXME: Now, we don't create module environment, because the context is
// implementation dependent.
var Importer = ( function ( _ esrecurse$Visitor2 ) {
function Importer ( declaration , referencer ) {
_ classCallCheck ( this , Importer ) ;
_ get ( Object . getPrototypeOf ( Importer . prototype ) , "constructor" , this ) . call ( this ) ;
this . declaration = declaration ;
this . referencer = referencer ;
}
_ inherits ( Importer , _ esrecurse$Visitor2 ) ;
_ createClass ( Importer , {
visitImport : {
value : function visitImport ( id , specifier ) {
var _ this = this ;
this . referencer . visitPattern ( id , function ( pattern ) {
_ this . referencer . currentScope ( ) . __ define ( pattern , new Definition ( Variable . ImportBinding , pattern , specifier , _ this . declaration , null , null ) ) ;
} ) ;
}
} ,
ImportNamespaceSpecifier : {
value : function ImportNamespaceSpecifier ( node ) {
var local = node . local || node . id ;
if ( local ) {
this . visitImport ( local , node ) ;
}
}
} ,
ImportDefaultSpecifier : {
value : function ImportDefaultSpecifier ( node ) {
var local = node . local || node . id ;
this . visitImport ( local , node ) ;
}
} ,
ImportSpecifier : {
value : function ImportSpecifier ( node ) {
var local = node . local || node . id ;
if ( node . name ) {
this . visitImport ( node . name , node ) ;
} else {
this . visitImport ( local , node ) ;
}
}
}
} ) ;
return Importer ;
} ) ( esrecurse . Visitor ) ;
// Referencing variables and creating bindings.
var Referencer = ( function ( _ esrecurse$Visitor3 ) {
function Referencer ( scopeManager ) {
_ classCallCheck ( this , Referencer ) ;
_ get ( Object . getPrototypeOf ( Referencer . prototype ) , "constructor" , this ) . call ( this ) ;
this . scopeManager = scopeManager ;
this . parent = null ;
this . isInnerMethodDefinition = false ;
}
_ inherits ( Referencer , _ esrecurse$Visitor3 ) ;
_ createClass ( Referencer , {
currentScope : {
value : function currentScope ( ) {
return this . scopeManager . __ currentScope ;
}
} ,
close : {
value : function close ( node ) {
while ( this . currentScope ( ) && node === this . currentScope ( ) . block ) {
this . scopeManager . __ currentScope = this . currentScope ( ) . __ close ( this . scopeManager ) ;
}
}
} ,
pushInnerMethodDefinition : {
value : function pushInnerMethodDefinition ( isInnerMethodDefinition ) {
var previous = this . isInnerMethodDefinition ;
this . isInnerMethodDefinition = isInnerMethodDefinition ;
return previous ;
}
} ,
popInnerMethodDefinition : {
value : function popInnerMethodDefinition ( isInnerMethodDefinition ) {
this . isInnerMethodDefinition = isInnerMethodDefinition ;
}
} ,
materializeTDZScope : {
value : function materializeTDZScope ( node , iterationNode ) {
// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-forin-div-ofexpressionevaluation-abstract-operation
// TDZ scope hides the declaration's names.
this . scopeManager . __ nestTDZScope ( node , iterationNode ) ;
this . visitVariableDeclaration ( this . currentScope ( ) , Variable . TDZ , iterationNode . left , 0 , true ) ;
}
} ,
materializeIterationScope : {
value : function materializeIterationScope ( node ) {
var _ this = this ;
// Generate iteration scope for upper ForIn/ForOf Statements.
var letOrConstDecl ;
this . scopeManager . __ nestForScope ( node ) ;
letOrConstDecl = node . left ;
this . visitVariableDeclaration ( this . currentScope ( ) , Variable . Variable , letOrConstDecl , 0 ) ;
this . visitPattern ( letOrConstDecl . declarations [ 0 ] . id , function ( pattern ) {
_ this . currentScope ( ) . __ referencing ( pattern , Reference . WRITE , node . right , null , true , true ) ;
} ) ;
}
} ,
referencingDefaultValue : {
value : function referencingDefaultValue ( pattern , assignments , maybeImplicitGlobal , init ) {
var scope = this . currentScope ( ) ;
assignments . forEach ( function ( assignment ) {
scope . __ referencing ( pattern , Reference . WRITE , assignment . right , maybeImplicitGlobal , pattern !== assignment . left , init ) ;
} ) ;
}
} ,
visitPattern : {
value : function visitPattern ( node , options , callback ) {
if ( typeof options === "function" ) {
callback = options ;
options = { processRightHandNodes : false } ;
}
traverseIdentifierInPattern ( node , options . processRightHandNodes ? this : null , callback ) ;
}
} ,
visitFunction : {
value : function visitFunction ( node ) {
var _ this = this ;
var i , iz ;
// FunctionDeclaration name is defined in upper scope
// NOTE: Not referring variableScope. It is intended.
// Since
// in ES5, FunctionDeclaration should be in FunctionBody.
// in ES6, FunctionDeclaration should be block scoped.
if ( node . type === Syntax . FunctionDeclaration ) {
// id is defined in upper scope
this . currentScope ( ) . __ define ( node . id , new Definition ( Variable . FunctionName , node . id , node , null , null , null ) ) ;
}
// FunctionExpression with name creates its special scope;
// FunctionExpressionNameScope.
if ( node . type === Syntax . FunctionExpression && node . id ) {
this . scopeManager . __ nestFunctionExpressionNameScope ( node ) ;
}
// Consider this function is in the MethodDefinition.
this . scopeManager . __ nestFunctionScope ( node , this . isInnerMethodDefinition ) ;
// Process parameter declarations.
for ( i = 0 , iz = node . params . length ; i < iz ; ++ i ) {
this . visitPattern ( node . params [ i ] , { processRightHandNodes : true } , function ( pattern , info ) {
_ this . currentScope ( ) . __ define ( pattern , new ParameterDefinition ( pattern , node , i , info . rest ) ) ;
_ this . referencingDefaultValue ( pattern , info . assignments , null , true ) ;
} ) ;
}
// if there's a rest argument, add that
if ( node . rest ) {
this . visitPattern ( {
type : "RestElement" ,
argument : node . rest
} , function ( pattern ) {
_ this . currentScope ( ) . __ define ( pattern , new ParameterDefinition ( pattern , node , node . params . length , true ) ) ;
} ) ;
}
// Skip BlockStatement to prevent creating BlockStatement scope.
if ( node . body . type === Syntax . BlockStatement ) {
this . visitChildren ( node . body ) ;
} else {
this . visit ( node . body ) ;
}
this . close ( node ) ;
}
} ,
visitClass : {
value : function visitClass ( node ) {
if ( node . type === Syntax . ClassDeclaration ) {
this . currentScope ( ) . __ define ( node . id , new Definition ( Variable . ClassName , node . id , node , null , null , null ) ) ;
}
// FIXME: Maybe consider TDZ.
this . visit ( node . superClass ) ;
this . scopeManager . __ nestClassScope ( node ) ;
if ( node . id ) {
this . currentScope ( ) . __ define ( node . id , new Definition ( Variable . ClassName , node . id , node ) ) ;
}
this . visit ( node . body ) ;
this . close ( node ) ;
}
} ,
visitProperty : {
value : function visitProperty ( node ) {
var previous , isMethodDefinition ;
if ( node . computed ) {
this . visit ( node . key ) ;
}
isMethodDefinition = node . type === Syntax . MethodDefinition || node . method ;
if ( isMethodDefinition ) {
previous = this . pushInnerMethodDefinition ( true ) ;
}
this . visit ( node . value ) ;
if ( isMethodDefinition ) {
this . popInnerMethodDefinition ( previous ) ;
}
}
} ,
visitForIn : {
value : function visitForIn ( node ) {
var _ this = this ;
if ( node . left . type === Syntax . VariableDeclaration && node . left . kind !== "var" ) {
this . materializeTDZScope ( node . right , node ) ;
this . visit ( node . right ) ;
this . close ( node . right ) ;
this . materializeIterationScope ( node ) ;
this . visit ( node . body ) ;
this . close ( node ) ;
} else {
if ( node . left . type === Syntax . VariableDeclaration ) {
this . visit ( node . left ) ;
this . visitPattern ( node . left . declarations [ 0 ] . id , function ( pattern ) {
_ this . currentScope ( ) . __ referencing ( pattern , Reference . WRITE , node . right , null , true , true ) ;
} ) ;
} else {
this . visitPattern ( node . left , { processRightHandNodes : true } , function ( pattern , info ) {
var maybeImplicitGlobal = null ;
if ( ! _ this . currentScope ( ) . isStrict ) {
maybeImplicitGlobal = {
pattern : pattern ,
node : node
} ;
}
_ this . referencingDefaultValue ( pattern , info . assignments , maybeImplicitGlobal , false ) ;
_ this . currentScope ( ) . __ referencing ( pattern , Reference . WRITE , node . right , maybeImplicitGlobal , true , false ) ;
} ) ;
}
this . visit ( node . right ) ;
this . visit ( node . body ) ;
}
}
} ,
visitVariableDeclaration : {
value : function visitVariableDeclaration ( variableTargetScope , type , node , index , fromTDZ ) {
var _ this = this ;
// If this was called to initialize a TDZ scope, this needs to make definitions, but doesn't make references.
var decl , init ;
decl = node . declarations [ index ] ;
init = decl . init ;
this . visitPattern ( decl . id , { processRightHandNodes : ! fromTDZ } , function ( pattern , info ) {
variableTargetScope . __ define ( pattern , new Definition ( type , pattern , decl , node , index , node . kind ) ) ;
if ( ! fromTDZ ) {
_ this . referencingDefaultValue ( pattern , info . assignments , null , true ) ;
}
if ( init ) {
_ this . currentScope ( ) . __ referencing ( pattern , Reference . WRITE , init , null , ! info . topLevel , true ) ;
}
} ) ;
}
} ,
AssignmentExpression : {
value : function AssignmentExpression ( node ) {
var _ this = this ;
if ( isPattern ( node . left ) ) {
if ( node . operator === "=" ) {
this . visitPattern ( node . left , { processRightHandNodes : true } , function ( pattern , info ) {
var maybeImplicitGlobal = null ;
if ( ! _ this . currentScope ( ) . isStrict ) {
maybeImplicitGlobal = {
pattern : pattern ,
node : node
} ;
}
_ this . referencingDefaultValue ( pattern , info . assignments , maybeImplicitGlobal , false ) ;
_ this . currentScope ( ) . __ referencing ( pattern , Reference . WRITE , node . right , maybeImplicitGlobal , ! info . topLevel , false ) ;
} ) ;
} else {
this . currentScope ( ) . __ referencing ( node . left , Reference . RW , node . right ) ;
}
} else {
this . visit ( node . left ) ;
}
this . visit ( node . right ) ;
}
} ,
CatchClause : {
value : function CatchClause ( node ) {
var _ this = this ;
this . scopeManager . __ nestCatchScope ( node ) ;
this . visitPattern ( node . param , { processRightHandNodes : true } , function ( pattern , info ) {
_ this . currentScope ( ) . __ define ( pattern , new Definition ( Variable . CatchClause , node . param , node , null , null , null ) ) ;
_ this . referencingDefaultValue ( pattern , info . assignments , null , true ) ;
} ) ;
this . visit ( node . body ) ;
this . close ( node ) ;
}
} ,
Program : {
value : function Program ( node ) {
this . scopeManager . __ nestGlobalScope ( node ) ;
if ( this . scopeManager . __ isNodejsScope ( ) ) {
// Force strictness of GlobalScope to false when using node.js scope.
this . currentScope ( ) . isStrict = false ;
this . scopeManager . __ nestFunctionScope ( node , false ) ;
}
if ( this . scopeManager . __ isES6 ( ) && this . scopeManager . isModule ( ) ) {
this . scopeManager . __ nestModuleScope ( node ) ;
}
this . visitChildren ( node ) ;
this . close ( node ) ;
}
} ,
Identifier : {
value : function Identifier ( node ) {
this . currentScope ( ) . __ referencing ( node ) ;
}
} ,
UpdateExpression : {
value : function UpdateExpression ( node ) {
if ( isPattern ( node . argument ) ) {
this . currentScope ( ) . __ referencing ( node . argument , Reference . RW , null ) ;
} else {
this . visitChildren ( node ) ;
}
}
} ,
MemberExpression : {
value : function MemberExpression ( node ) {
this . visit ( node . object ) ;
if ( node . computed ) {
this . visit ( node . property ) ;
}
}
} ,
Property : {
value : function Property ( node ) {
this . visitProperty ( node ) ;
}
} ,
MethodDefinition : {
value : function MethodDefinition ( node ) {
this . visitProperty ( node ) ;
}
} ,
BreakStatement : {
value : function BreakStatement ( ) { }
} ,
ContinueStatement : {
value : function ContinueStatement ( ) { }
} ,
LabeledStatement : {
value : function LabeledStatement ( node ) {
this . visit ( node . body ) ;
}
} ,
ForStatement : {
value : function ForStatement ( node ) {
// Create ForStatement declaration.
// NOTE: In ES6, ForStatement dynamically generates
// per iteration environment. However, escope is
// a static analyzer, we only generate one scope for ForStatement.
if ( node . init && node . init . type === Syntax . VariableDeclaration && node . init . kind !== "var" ) {
this . scopeManager . __ nestForScope ( node ) ;
}
this . visitChildren ( node ) ;
this . close ( node ) ;
}
} ,
ClassExpression : {
value : function ClassExpression ( node ) {
this . visitClass ( node ) ;
}
} ,
ClassDeclaration : {
value : function ClassDeclaration ( node ) {
this . visitClass ( node ) ;
}
} ,
CallExpression : {
value : function CallExpression ( node ) {
// Check this is direct call to eval
if ( ! this . scopeManager . __ ignoreEval ( ) && node . callee . type === Syntax . Identifier && node . callee . name === "eval" ) {
// NOTE: This should be `variableScope`. Since direct eval call always creates Lexical environment and
// let / const should be enclosed into it. Only VariableDeclaration affects on the caller's environment.
this . currentScope ( ) . variableScope . __ detectEval ( ) ;
}
this . visitChildren ( node ) ;
}
} ,
BlockStatement : {
value : function BlockStatement ( node ) {
if ( this . scopeManager . __ isES6 ( ) ) {
this . scopeManager . __ nestBlockScope ( node ) ;
}
this . visitChildren ( node ) ;
this . close ( node ) ;
}
} ,
ThisExpression : {
value : function ThisExpression ( ) {
this . currentScope ( ) . variableScope . __ detectThis ( ) ;
}
} ,
WithStatement : {
value : function WithStatement ( node ) {
this . visit ( node . object ) ;
// Then nest scope for WithStatement.
this . scopeManager . __ nestWithScope ( node ) ;
this . visit ( node . body ) ;
this . close ( node ) ;
}
} ,
VariableDeclaration : {
value : function VariableDeclaration ( node ) {
var variableTargetScope , i , iz , decl ;
variableTargetScope = node . kind === "var" ? this . currentScope ( ) . variableScope : this . currentScope ( ) ;
for ( i = 0 , iz = node . declarations . length ; i < iz ; ++ i ) {
decl = node . declarations [ i ] ;
this . visitVariableDeclaration ( variableTargetScope , Variable . Variable , node , i ) ;
if ( decl . init ) {
this . visit ( decl . init ) ;
}
}
}
} ,
SwitchStatement : {
// sec 13.11.8
value : function SwitchStatement ( node ) {
var i , iz ;
this . visit ( node . discriminant ) ;
if ( this . scopeManager . __ isES6 ( ) ) {
this . scopeManager . __ nestSwitchScope ( node ) ;
}
for ( i = 0 , iz = node . cases . length ; i < iz ; ++ i ) {
this . visit ( node . cases [ i ] ) ;
}
this . close ( node ) ;
}
} ,
FunctionDeclaration : {
value : function FunctionDeclaration ( node ) {
this . visitFunction ( node ) ;
}
} ,
FunctionExpression : {
value : function FunctionExpression ( node ) {
this . visitFunction ( node ) ;
}
} ,
ForOfStatement : {
value : function ForOfStatement ( node ) {
this . visitForIn ( node ) ;
}
} ,
ForInStatement : {
value : function ForInStatement ( node ) {
this . visitForIn ( node ) ;
}
} ,
ArrowFunctionExpression : {
value : function ArrowFunctionExpression ( node ) {
this . visitFunction ( node ) ;
}
} ,
ImportDeclaration : {
value : function ImportDeclaration ( node ) {
var importer ;
assert ( this . scopeManager . __ isES6 ( ) && this . scopeManager . isModule ( ) , "ImportDeclaration should appear when the mode is ES6 and in the module context." ) ;
importer = new Importer ( node , this ) ;
importer . visit ( node ) ;
}
} ,
visitExportDeclaration : {
value : function visitExportDeclaration ( node ) {
if ( node . source ) {
return ;
}
if ( node . declaration ) {
this . visit ( node . declaration ) ;
return ;
}
this . visitChildren ( node ) ;
}
} ,
ExportDeclaration : {
value : function ExportDeclaration ( node ) {
this . visitExportDeclaration ( node ) ;
}
} ,
ExportNamedDeclaration : {
value : function ExportNamedDeclaration ( node ) {
this . visitExportDeclaration ( node ) ;
}
} ,
ExportSpecifier : {
value : function ExportSpecifier ( node ) {
var local = node . id || node . local ;
this . visit ( local ) ;
}
}
} ) ;
return Referencer ;
} ) ( esrecurse . Visitor ) ;
module . exports = Referencer ;
/* vim: set sw=4 ts=4 et tw=80 : */
//# sourceMappingURL=data:application/json;base64,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