"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 PatternVisitor = _ interopRequire ( require ( "./pattern-visitor" ) ) ;
var _ definition = require ( "./definition" ) ;
var ParameterDefinition = _ definition . ParameterDefinition ;
var Definition = _ definition . Definition ;
var assert = _ interopRequire ( require ( "assert" ) ) ;
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 ) ;
}
}
// 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$Visitor ) {
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$Visitor ) ;
_ 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$Visitor2 ) {
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$Visitor2 ) ;
_ 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 ;
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 ( PatternVisitor . 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 ( PatternVisitor . 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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