Browse Source

Added parents to the scope.

gh-109
Oskar Segersvärd 9 years ago
parent
commit
9eec7060f2
  1. 15
      src/Scope.js
  2. 21
      test/testScope.js

15
src/Scope.js

@ -29,10 +29,11 @@ function underscorePrefix ( x ) {
// ## Scope
// A Scope is a mapping from string names to `Identifiers`.
export default class Scope {
constructor () {
constructor ( parent ) {
this.ids = [];
this.names = blank();
this.parent = parent || null;
this.used = blank();
}
@ -89,6 +90,13 @@ export default class Scope {
return this.names[ name ];
}
// Returns true if `name` is in Scope.
inScope ( name ) {
if ( name in this.names ) return true;
return this.parent ? this.parent.inScope( name ) : false;
}
// Returns a list of `[ name, identifier ]` tuples.
localIds () {
return keys( this.names ).map( name => [ name, this.lookup( name ) ] );
@ -96,6 +104,10 @@ export default class Scope {
// Lookup the identifier referred to by `name`.
lookup ( name ) {
if ( !( name in this.names ) && this.parent ) {
return this.parent.lookup( name );
}
let id = this.ids[ this.names[ name ] ];
while ( id instanceof Reference ) {
@ -121,6 +133,7 @@ export default class Scope {
virtual () {
const scope = new Scope();
scope.ids = this.ids;
scope.parent = this.parent;
return scope;
}
}

21
test/testScope.js

@ -18,6 +18,27 @@ describe( 'Scope', function () {
assert.equal( scope.lookup( 'b' ), scope.lookup( 'a' ) );
});
describe( 'parent:', function () {
var parent = new Scope(),
child = new Scope( parent );
it( 'allows children access to its names', function () {
parent.define( 'a' );
assert.equal( child.lookup( 'a' ), parent.lookup( 'a' ) );
});
it( 'names in the child scope shadows the parent', function () {
child.define( 'a' );
assert.notEqual( child.lookup( 'a' ), parent.lookup( 'a' ) );
child.define( 'b' );
assert.equal( parent.lookup( 'b' ), undefined );
});
});
describe( 'virtual scope:', function () {
var real, a, b;

Loading…
Cancel
Save