-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathTypeErase.stencil
More file actions
68 lines (56 loc) · 2.33 KB
/
TypeErase.stencil
File metadata and controls
68 lines (56 loc) · 2.33 KB
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
{% for type in types.protocols|annotated:"TypeErase" %}
// MARK: - Type Eraser for {{type.name}}
private class _Any{{type.name}}Base<{{type.annotations.TypeErase}}>: {{type.name}} {
init() {
guard type(of: self) != _Any{{type.name}}Base.self else {
fatalError("_Any{{type.name}}Base<{{type.annotations.TypeErase}}> instances can not be created; create a subclass instance instead")
}
}
{% for m in type.methods %}
func {{m.name}} -> {{m.returnTypeName}} {
fatalError("Must override")
}
{% endfor %}
{% for p in type.variables %}
var {{p.name}}: {{p.typeName}} {
get { fatalError("Must override") }
{% if p.isMutable %}set { fatalError("Must override") }{% endif %}
}
{% endfor %}
}
private final class _Any{{type.name}}Box<Concrete: {{type.name}}>: _Any{{type.name}}Base<Concrete.{{type.annotations.TypeErase}}> {
var concrete: Concrete
typealias {{type.annotations.TypeErase}} = Concrete.{{type.annotations.TypeErase}}
init(_ concrete: Concrete) {
self.concrete = concrete
}
{% for m in type.methods %}
override func {{m.name}} -> {{m.returnTypeName}} {
return concrete.{{m.callName}}({% for p in m.parameters %}{{p.name}}: {{p.name}}{% if not forloop.last %},{% endif %}{% endfor %})
}
{% endfor %}
{% for p in type.variables %}
override var {{p.name}}: {{p.typeName}} {
get { return concrete.{{p.name}} }
{% if p.isMutable %}set { concrete.{{p.name}} = newValue }{% endif %}
}
{% endfor %}
}
final class Any{{type.name}}<{{ type.annotations.TypeErase }}>: {{type.name}} {
private let box: _Any{{type.name}}Base<{{ type.annotations.TypeErase }}>
init<Concrete: {{type.name}}>(_ concrete: Concrete) where Concrete.{{ type.annotations.TypeErase }} == {{ type.annotations.TypeErase }} {
self.box = _Any{{type.name}}Box(concrete)
}
{% for m in type.methods %}
func {{m.name}} -> {{m.returnTypeName}} {
return box.{{m.callName}}({% for p in m.parameters %}{{p.name}}: {{p.name}}{% if not forloop.last %},{% endif %}{% endfor %})
}
{% endfor %}
{% for p in type.variables %}
var {{p.name}}: {{p.typeName}} {
get { return box.{{p.name}} }
{% if p.isMutable %}set { box.{{p.name}} = newValue }{% endif %}
}
{% endfor %}
}
{% endfor %}