From 63f813edd7674f5d21c20b554250cf972015e81d Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 4 Oct 2015 13:28:45 -0400 Subject: [PATCH] scope fixes --- src/Statement.js | 12 +----- src/ast/attachScopes.js | 82 ++++++++++++++++++++--------------------- 2 files changed, 42 insertions(+), 52 deletions(-) diff --git a/src/Statement.js b/src/Statement.js index e9eecb8..bf35eba 100644 --- a/src/Statement.js +++ b/src/Statement.js @@ -106,17 +106,7 @@ export default class Statement { } if ( isReference( node, parent ) ) { - // TODO this feels terribly kludgy. Function expression IDs and - // function parameters will show up in the parent scope – this - // hack fixes that - let realScope = scope; - if ( /Function/.test( parent.type ) ) { - if ( parent.type !== 'FunctionDeclaration' || node !== parent.id ) { - realScope = parent.body._scope; - } - } - - const reference = new Reference( node, realScope ); + const reference = new Reference( node, scope ); references.push( reference ); if ( node.type === 'Identifier' ) { diff --git a/src/ast/attachScopes.js b/src/ast/attachScopes.js index ffd47f9..3f0f025 100644 --- a/src/ast/attachScopes.js +++ b/src/ast/attachScopes.js @@ -13,52 +13,52 @@ export default function attachScopes ( statement ) { enter ( node, parent ) { let newScope; - switch ( node.type ) { - case 'FunctionDeclaration': - scope.addDeclaration( node, false, false ); - break; - - case 'BlockStatement': - if ( parent && /Function/.test( parent.type ) ) { - newScope = new Scope({ - parent: scope, - block: false, - params: parent.params - }); - - // named function expressions - the name is considered - // part of the function's scope - if ( parent.type === 'FunctionExpression' && parent.id ) { - newScope.addDeclaration( parent, false, false ); - } - } else { - newScope = new Scope({ - parent: scope, - block: true - }); - } + // function foo () {...} + // class Foo {...} + if ( /(Function|Class)Declaration/.test( node.type ) ) { + scope.addDeclaration( node, false, false ); + } - break; + // var foo = 1 + // TODO can we have multiple declarations at this point? when + // do we create synthetic var nodes? + if ( node.type === 'VariableDeclaration' ) { + const isBlockDeclaration = blockDeclarations[ node.kind ]; + node.declarations.forEach( declarator => { + scope.addDeclaration( declarator, isBlockDeclaration, true ); + }); + } - case 'CatchClause': - newScope = new Scope({ - parent: scope, - params: [ node.param ], - block: true - }); + // create new function scope + if ( /Function/.test( node.type ) ) { + newScope = new Scope({ + parent: scope, + block: false, + params: node.params + }); - break; + // named function expressions - the name is considered + // part of the function's scope + if ( node.type === 'FunctionExpression' && node.id ) { + newScope.addDeclaration( node, false, false ); + } + } - case 'VariableDeclaration': - node.declarations.forEach( declarator => { - const isBlockDeclaration = node.type === 'VariableDeclaration' && blockDeclarations[ node.kind ]; - scope.addDeclaration( declarator, isBlockDeclaration, true ); - }); - break; + // create new block scope + if ( node.type === 'BlockStatement' && !/Function/.test( parent.type ) ) { + newScope = new Scope({ + parent: scope, + block: true + }); + } - case 'ClassDeclaration': - scope.addDeclaration( node, false, false ); - break; + // catch clause has its own block scope + if ( node.type === 'CatchClause' ) { + newScope = new Scope({ + parent: scope, + params: [ node.param ], + block: true + }); } if ( newScope ) {