From 96e074d4f118fedbd32af76f037159d26cafe246 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 4 Oct 2015 15:43:34 -0400 Subject: [PATCH] place function IDs in correct scope --- src/Module.js | 2 +- src/Statement.js | 8 +++++++- src/ast/Scope.js | 1 + src/ast/attachScopes.js | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Module.js b/src/Module.js index a96125d..8ea8222 100644 --- a/src/Module.js +++ b/src/Module.js @@ -535,7 +535,7 @@ export default class Module { statement.references.forEach( reference => { const declaration = reference.declaration; - if ( reference.declaration ) { + if ( declaration ) { const { start, end } = reference; const name = declaration.render( es6 ); diff --git a/src/Statement.js b/src/Statement.js index 4c63e6c..ae83957 100644 --- a/src/Statement.js +++ b/src/Statement.js @@ -135,7 +135,13 @@ export default class Statement { } if ( isReference( node, parent ) ) { - const reference = new Reference( node, scope ); + // function declaration IDs are a special case – they're associated + // with the parent scope + const referenceScope = parent.type === 'FunctionDeclaration' && node === parent.id ? + scope.parent : + scope; + + const reference = new Reference( node, referenceScope ); references.push( reference ); reference.isImmediatelyUsed = !readDepth; diff --git a/src/ast/Scope.js b/src/ast/Scope.js index 64c90be..4bd4576 100644 --- a/src/ast/Scope.js +++ b/src/ast/Scope.js @@ -86,6 +86,7 @@ export default class Scope { this.parent.addDeclaration( node, isBlockDeclaration, isVar ); } else { extractNames( node.id ).forEach( name => { + if ( this.declarations[ name ] ) throw new Error( `Duplicate declaration (${name})` ); this.declarations[ name ] = new Declaration( name ); }); } diff --git a/src/ast/attachScopes.js b/src/ast/attachScopes.js index 3f0f025..57680da 100644 --- a/src/ast/attachScopes.js +++ b/src/ast/attachScopes.js @@ -11,8 +11,6 @@ export default function attachScopes ( statement ) { walk( node, { enter ( node, parent ) { - let newScope; - // function foo () {...} // class Foo {...} if ( /(Function|Class)Declaration/.test( node.type ) ) { @@ -29,6 +27,8 @@ export default function attachScopes ( statement ) { }); } + let newScope; + // create new function scope if ( /Function/.test( node.type ) ) { newScope = new Scope({