OLD | NEW |
| (Empty) |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 part of js_ast; | |
6 | |
7 abstract class _TypePrinterBase implements TypeRefVisitor { | |
8 void out(String s); | |
9 void visit(Node node); | |
10 | |
11 void outSeparated(String separator, Iterable items, [action(dynamic item)]) { | |
12 action ??= visit; | |
13 var first = true; | |
14 for (var item in items) { | |
15 if (first) { | |
16 first = false; | |
17 } else { | |
18 out(separator); | |
19 } | |
20 action(item); | |
21 } | |
22 } | |
23 | |
24 void outTypeArg(Iterable<TypeRef> typeArgs) { | |
25 if (typeArgs.isNotEmpty) { | |
26 // TODO(ochafik): Double-check precedence issues when we start emitting | |
27 // type arguments outside type literals (generic method call, etc). | |
28 out('<'); | |
29 outSeparated(", ", typeArgs); | |
30 out('>'); | |
31 } | |
32 } | |
33 | |
34 @override | |
35 visitQualifiedTypeRef(QualifiedTypeRef node) { | |
36 outSeparated(".", node.path); | |
37 } | |
38 } | |
39 | |
40 abstract class TypeScriptTypePrinter extends _TypePrinterBase { | |
41 | |
42 void _outTypeAnnotation(TypeRef type) { | |
43 if (type is OptionalTypeRef) { | |
44 out("?: "); | |
45 visit(type.type); | |
46 } else { | |
47 out(": "); | |
48 visit(type); | |
49 } | |
50 } | |
51 | |
52 @override | |
53 visitGenericTypeRef(GenericTypeRef node) { | |
54 if (node.rawType is FunctionTypeRef) { | |
55 outTypeArg(node.typeArgs); | |
56 visit(node.rawType); | |
57 } else { | |
58 visit(node.rawType); | |
59 outTypeArg(node.typeArgs); | |
60 } | |
61 } | |
62 | |
63 @override | |
64 visitArrayTypeRef(ArrayTypeRef node) { | |
65 if (node.elementType == null) { | |
66 out("Array"); | |
67 } else { | |
68 visit(node.elementType); | |
69 out("[]"); | |
70 } | |
71 } | |
72 | |
73 @override | |
74 visitOptionalTypeRef(OptionalTypeRef node) { | |
75 visit(node.type); | |
76 } | |
77 | |
78 @override | |
79 visitRecordTypeRef(RecordTypeRef node) { | |
80 out('{'); | |
81 outSeparated(", ", node.types.keys, (Identifier name) { | |
82 var type = node.types[name]; | |
83 visit(name); | |
84 _outTypeAnnotation(type); | |
85 }); | |
86 out('}'); | |
87 } | |
88 | |
89 @override | |
90 visitUnionTypeRef(UnionTypeRef node) { | |
91 outSeparated("|", node.types.where((t) => !t.isNull)); | |
92 } | |
93 | |
94 @override | |
95 visitFunctionTypeRef(FunctionTypeRef node) { | |
96 if (node.returnType == null) { | |
97 out('Function'); | |
98 } else { | |
99 out('('); | |
100 if (node.paramTypes == null) { | |
101 out('...any'); | |
102 } else { | |
103 outSeparated(", ", node.paramTypes.keys, (name) { | |
104 var paramType = node.paramTypes[name]; | |
105 visit(name); | |
106 _outTypeAnnotation(paramType); | |
107 }); | |
108 } | |
109 out(') => '); | |
110 visit(node.returnType); | |
111 } | |
112 } | |
113 | |
114 @override | |
115 visitAnyTypeRef(AnyTypeRef node) { | |
116 out("any"); | |
117 } | |
118 | |
119 @override | |
120 visitUnknownTypeRef(UnknownTypeRef node) { | |
121 out("any"); | |
122 } | |
123 } | |
124 | |
125 class ClosureTypePrinter extends _TypePrinterBase implements NodeVisitor { | |
126 final _buffer = new StringBuffer(); | |
127 | |
128 @override | |
129 void out(String s) => _buffer.write(s); | |
130 | |
131 @override | |
132 void visit(Node node) => node.accept(this); | |
133 | |
134 noSuchMethod(Invocation i) => super.noSuchMethod(i); | |
135 | |
136 @override | |
137 visitGenericTypeRef(GenericTypeRef node) { | |
138 visit(node.rawType); | |
139 outTypeArg(node.typeArgs); | |
140 } | |
141 | |
142 @override | |
143 visitIdentifier(Identifier node) { | |
144 //out(localNamer.getName(node)); | |
145 out(node.name); | |
146 } | |
147 | |
148 @override | |
149 visitAccess(PropertyAccess node) { | |
150 var selector = node.selector; | |
151 assert(selector is LiteralString); | |
152 if (selector is! LiteralString) { | |
153 out("?"); | |
154 return; | |
155 } | |
156 visit(node.receiver); | |
157 out("."); | |
158 out(selector.valueWithoutQuotes); | |
159 } | |
160 | |
161 @override toString() => _buffer.toString(); | |
162 | |
163 @override | |
164 visitArrayTypeRef(ArrayTypeRef node) { | |
165 out("Array"); | |
166 if (node.elementType != null) { | |
167 out("<"); | |
168 visit(node.elementType); | |
169 out(">"); | |
170 } | |
171 } | |
172 | |
173 @override | |
174 visitOptionalTypeRef(OptionalTypeRef node) { | |
175 visit(node.type); | |
176 out("="); | |
177 } | |
178 | |
179 @override | |
180 visitRecordTypeRef(RecordTypeRef node) { | |
181 out('{'); | |
182 outSeparated(", ", node.types.keys, (Identifier name) { | |
183 var type = node.types[name]; | |
184 visit(name); | |
185 out(": "); | |
186 visit(type is OptionalTypeRef ? type.orUndefined() : type); | |
187 }); | |
188 out('}'); | |
189 } | |
190 | |
191 @override | |
192 visitAnyTypeRef(AnyTypeRef node) { | |
193 out("*"); | |
194 } | |
195 | |
196 @override | |
197 visitUnknownTypeRef(UnknownTypeRef node) { | |
198 out("?"); | |
199 } | |
200 | |
201 @override | |
202 visitUnionTypeRef(UnionTypeRef node) { | |
203 out("("); | |
204 outSeparated("|", node.types); | |
205 out(")"); | |
206 } | |
207 | |
208 @override | |
209 visitFunctionTypeRef(FunctionTypeRef node) { | |
210 if (node.returnType == null) { | |
211 out('Function'); | |
212 } else { | |
213 out('function('); | |
214 if (node.paramTypes == null) { | |
215 out("...*"); | |
216 } else { | |
217 outSeparated(", ", node.paramTypes.values); | |
218 } | |
219 out(')'); | |
220 if (node.returnType != null) { | |
221 out(":"); | |
222 visit(node.returnType); | |
223 } | |
224 } | |
225 } | |
226 } | |
OLD | NEW |