/
Expander.js
105 lines (66 loc) · 2.96 KB
/
Expander.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
Class('KiokuJS.Linker.Expander', {
isa : 'Data.Visitor',
use : 'KiokuJS.Reference',
has : {
scope : { required : true },
nodes : { required : true }
},
methods : {
visitNode : function (node) {
var scope = this.scope
var oldNode = scope.idToNode(node.ID)
if (oldNode) node.consumeOldNode(oldNode)
if (node.isLive())
node.clearInstance()
else
// newly created instance need to has the __REF_ADR__ as this property
// is being extensively used internally
this.assignRefAdrTo(node.createEmptyInstance())
return node.populate(this)
},
visitReference : function (reference) {
var refID = reference.ID
var refNode = this.nodes[ refID ] || this.scope.idToNode(refID)
if (!refNode)
if (reference.type != 'lazy')
throw new KiokuJS.Exception.LookUp({ id : refID, backendName : "Expander working set" })
else
return reference
if (refNode.isLive()) {
var instance = refNode.getObject()
this.assignRefAdrTo(instance)
return instance
}
// `visit` and not(!) `visitNode` to utilize the `seen` cache for already processed nodes
return this.visit(refNode)
},
visitJooseInstance : function (node, className) {
if (node instanceof KiokuJS.Node) return this.visitNode(node)
if (node instanceof KiokuJS.Reference) return this.visitReference(node)
throw "Invalid Joose instance [" + node + "] encountered during inlining - only `KiokuJS.Node` and `KiokuJS.Reference` allowed"
},
visitArray : function (array, className) {
return Joose.A.map(array, function (value, index) {
return this.visit(value)
}, this)
},
visitObject : function (object, className) {
var res = {}
Joose.O.eachOwn(object, function (value, key) {
res[ key ] = this.visit(value)
}, this)
return res
}
},
my : {
methods : {
expandNodes : function (nodes, scope) {
var instance = new this.HOST({
scope : scope,
nodes : nodes
})
return instance.visit(nodes)
}
}
}
})