1 | var Map = require('es6-map')
|
2 | var Set = require('es6-set')
|
3 | var ArrayFrom = require('array-from')
|
4 | var Binding = require('./binding')
|
5 |
|
6 | module.exports = Scope
|
7 |
|
8 | function Scope (parent) {
|
9 | this.parent = parent
|
10 | this.bindings = new Map()
|
11 | this.undeclaredBindings = new Map()
|
12 | }
|
13 |
|
14 | Scope.prototype.define = function (binding) {
|
15 | if (this.bindings.has(binding.name)) {
|
16 | var existing = this.bindings.get(binding.name)
|
17 | binding.getReferences().forEach(function (ref) {
|
18 | existing.add(ref)
|
19 | })
|
20 | } else {
|
21 | this.bindings.set(binding.name, binding)
|
22 | }
|
23 | return this
|
24 | }
|
25 |
|
26 | Scope.prototype.has = function (name) {
|
27 | return this.bindings.has(name)
|
28 | }
|
29 |
|
30 | Scope.prototype.add = function (name, ref) {
|
31 | var binding = this.bindings.get(name)
|
32 | if (binding) {
|
33 | binding.add(ref)
|
34 | }
|
35 | return this
|
36 | }
|
37 |
|
38 | Scope.prototype.addUndeclared = function (name, ref) {
|
39 | if (!this.undeclaredBindings.has(name)) {
|
40 | this.undeclaredBindings.set(name, new Binding(name))
|
41 | }
|
42 |
|
43 | var binding = this.undeclaredBindings.get(name)
|
44 | binding.add(ref)
|
45 | return this
|
46 | }
|
47 |
|
48 | Scope.prototype.getBinding = function (name) {
|
49 | return this.bindings.get(name)
|
50 | }
|
51 |
|
52 | Scope.prototype.getReferences = function (name) {
|
53 | return this.has(name) ? this.bindings.get(name).getReferences() : []
|
54 | }
|
55 |
|
56 | Scope.prototype.getUndeclaredNames = function () {
|
57 | return ArrayFrom(this.undeclaredBindings.keys())
|
58 | }
|
59 |
|
60 | Scope.prototype.forEach = function () {
|
61 | this.bindings.forEach.apply(this.bindings, arguments)
|
62 | }
|
63 |
|
64 | Scope.prototype.forEachAvailable = function (cb) {
|
65 | var seen = new Set()
|
66 | this.bindings.forEach(function (binding, name) {
|
67 | seen.add(name)
|
68 | cb(binding, name)
|
69 | })
|
70 | this.parent && this.parent.forEachAvailable(function (binding, name) {
|
71 | if (!seen.has(name)) {
|
72 | seen.add(name)
|
73 | cb(binding, name)
|
74 | }
|
75 | })
|
76 | }
|