You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
1.7 KiB
76 lines
1.7 KiB
var Map = require('es6-map')
|
|
var Set = require('es6-set')
|
|
var ArrayFrom = require('array-from')
|
|
var Binding = require('./binding')
|
|
|
|
module.exports = Scope
|
|
|
|
function Scope (parent) {
|
|
this.parent = parent
|
|
this.bindings = new Map()
|
|
this.undeclaredBindings = new Map()
|
|
}
|
|
|
|
Scope.prototype.define = function (binding) {
|
|
if (this.bindings.has(binding.name)) {
|
|
var existing = this.bindings.get(binding.name)
|
|
binding.getReferences().forEach(function (ref) {
|
|
existing.add(ref)
|
|
})
|
|
} else {
|
|
this.bindings.set(binding.name, binding)
|
|
}
|
|
return this
|
|
}
|
|
|
|
Scope.prototype.has = function (name) {
|
|
return this.bindings.has(name)
|
|
}
|
|
|
|
Scope.prototype.add = function (name, ref) {
|
|
var binding = this.bindings.get(name)
|
|
if (binding) {
|
|
binding.add(ref)
|
|
}
|
|
return this
|
|
}
|
|
|
|
Scope.prototype.addUndeclared = function (name, ref) {
|
|
if (!this.undeclaredBindings.has(name)) {
|
|
this.undeclaredBindings.set(name, new Binding(name))
|
|
}
|
|
|
|
var binding = this.undeclaredBindings.get(name)
|
|
binding.add(ref)
|
|
return this
|
|
}
|
|
|
|
Scope.prototype.getBinding = function (name) {
|
|
return this.bindings.get(name)
|
|
}
|
|
|
|
Scope.prototype.getReferences = function (name) {
|
|
return this.has(name) ? this.bindings.get(name).getReferences() : []
|
|
}
|
|
|
|
Scope.prototype.getUndeclaredNames = function () {
|
|
return ArrayFrom(this.undeclaredBindings.keys())
|
|
}
|
|
|
|
Scope.prototype.forEach = function () {
|
|
this.bindings.forEach.apply(this.bindings, arguments)
|
|
}
|
|
|
|
Scope.prototype.forEachAvailable = function (cb) {
|
|
var seen = new Set()
|
|
this.bindings.forEach(function (binding, name) {
|
|
seen.add(name)
|
|
cb(binding, name)
|
|
})
|
|
this.parent && this.parent.forEachAvailable(function (binding, name) {
|
|
if (!seen.has(name)) {
|
|
seen.add(name)
|
|
cb(binding, name)
|
|
}
|
|
})
|
|
}
|