OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library fasta.kernel_enum_builder; | 5 library fasta.kernel_enum_builder; |
6 | 6 |
7 import 'package:kernel/ast.dart' | 7 import 'package:kernel/ast.dart' |
8 show | 8 show |
9 Arguments, | 9 Arguments, |
10 Class, | 10 Class, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 KernelNamedTypeBuilder, | 54 KernelNamedTypeBuilder, |
55 KernelProcedureBuilder, | 55 KernelProcedureBuilder, |
56 KernelTypeBuilder, | 56 KernelTypeBuilder, |
57 LibraryBuilder, | 57 LibraryBuilder, |
58 MemberBuilder, | 58 MemberBuilder, |
59 MetadataBuilder, | 59 MetadataBuilder, |
60 Scope; | 60 Scope; |
61 | 61 |
62 class KernelEnumBuilder extends SourceClassBuilder | 62 class KernelEnumBuilder extends SourceClassBuilder |
63 implements EnumBuilder<KernelTypeBuilder, InterfaceType> { | 63 implements EnumBuilder<KernelTypeBuilder, InterfaceType> { |
64 final List<Object> constantNamesAndOffsets; | 64 final List<Object> constantNamesAndOffsetsAndDocs; |
65 | 65 |
66 final MapLiteral toStringMap; | 66 final MapLiteral toStringMap; |
67 | 67 |
68 final KernelNamedTypeBuilder intType; | 68 final KernelNamedTypeBuilder intType; |
69 | 69 |
70 final KernelNamedTypeBuilder stringType; | 70 final KernelNamedTypeBuilder stringType; |
71 | 71 |
72 final KernelNamedTypeBuilder objectType; | 72 final KernelNamedTypeBuilder objectType; |
73 | 73 |
74 final KernelNamedTypeBuilder listType; | 74 final KernelNamedTypeBuilder listType; |
75 | 75 |
76 KernelEnumBuilder.internal( | 76 KernelEnumBuilder.internal( |
77 String documentationComment, | 77 String documentationComment, |
78 List<MetadataBuilder> metadata, | 78 List<MetadataBuilder> metadata, |
79 String name, | 79 String name, |
80 Scope scope, | 80 Scope scope, |
81 Scope constructors, | 81 Scope constructors, |
82 Class cls, | 82 Class cls, |
83 this.constantNamesAndOffsets, | 83 this.constantNamesAndOffsetsAndDocs, |
84 this.toStringMap, | 84 this.toStringMap, |
85 this.intType, | 85 this.intType, |
86 this.listType, | 86 this.listType, |
87 this.objectType, | 87 this.objectType, |
88 this.stringType, | 88 this.stringType, |
89 LibraryBuilder parent, | 89 LibraryBuilder parent, |
90 int charOffset) | 90 int charOffset) |
91 : super(documentationComment, metadata, 0, name, null, null, null, scope, | 91 : super(documentationComment, metadata, 0, name, null, null, null, scope, |
92 constructors, parent, null, charOffset, cls); | 92 constructors, parent, null, charOffset, cls); |
93 | 93 |
94 factory KernelEnumBuilder( | 94 factory KernelEnumBuilder( |
| 95 String documentationComment, |
95 List<MetadataBuilder> metadata, | 96 List<MetadataBuilder> metadata, |
96 String name, | 97 String name, |
97 List<Object> constantNamesAndOffsets, | 98 List<Object> constantNamesAndOffsetsAndDocs, |
98 KernelLibraryBuilder parent, | 99 KernelLibraryBuilder parent, |
99 int charOffset, | 100 int charOffset, |
100 int charEndOffset) { | 101 int charEndOffset) { |
101 constantNamesAndOffsets ??= const <Object>[]; | 102 constantNamesAndOffsetsAndDocs ??= const <Object>[]; |
102 // TODO(ahe): These types shouldn't be looked up in scope, they come | 103 // TODO(ahe): These types shouldn't be looked up in scope, they come |
103 // directly from dart:core. | 104 // directly from dart:core. |
104 KernelTypeBuilder intType = | 105 KernelTypeBuilder intType = |
105 new KernelNamedTypeBuilder("int", null, charOffset, parent.fileUri); | 106 new KernelNamedTypeBuilder("int", null, charOffset, parent.fileUri); |
106 KernelTypeBuilder stringType = | 107 KernelTypeBuilder stringType = |
107 new KernelNamedTypeBuilder("String", null, charOffset, parent.fileUri); | 108 new KernelNamedTypeBuilder("String", null, charOffset, parent.fileUri); |
108 KernelNamedTypeBuilder objectType = | 109 KernelNamedTypeBuilder objectType = |
109 new KernelNamedTypeBuilder("Object", null, charOffset, parent.fileUri); | 110 new KernelNamedTypeBuilder("Object", null, charOffset, parent.fileUri); |
110 Class cls = new Class(name: name); | 111 Class cls = new Class(name: name); |
111 Map<String, MemberBuilder> members = <String, MemberBuilder>{}; | 112 Map<String, MemberBuilder> members = <String, MemberBuilder>{}; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 "toString", | 165 "toString", |
165 null, | 166 null, |
166 null, | 167 null, |
167 ProcedureKind.Method, | 168 ProcedureKind.Method, |
168 parent, | 169 parent, |
169 charOffset, | 170 charOffset, |
170 charOffset, | 171 charOffset, |
171 charEndOffset); | 172 charEndOffset); |
172 members["toString"] = toStringBuilder; | 173 members["toString"] = toStringBuilder; |
173 String className = name; | 174 String className = name; |
174 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { | 175 for (int i = 0; i < constantNamesAndOffsetsAndDocs.length; i += 3) { |
175 String name = constantNamesAndOffsets[i]; | 176 String name = constantNamesAndOffsetsAndDocs[i]; |
176 int charOffset = constantNamesAndOffsets[i + 1]; | 177 int charOffset = constantNamesAndOffsetsAndDocs[i + 1]; |
| 178 String documentationComment = constantNamesAndOffsetsAndDocs[i + 2]; |
177 if (members.containsKey(name)) { | 179 if (members.containsKey(name)) { |
178 parent.addCompileTimeError(templateDuplicatedName.withArguments(name), | 180 parent.addCompileTimeError(templateDuplicatedName.withArguments(name), |
179 charOffset, parent.fileUri); | 181 charOffset, parent.fileUri); |
180 constantNamesAndOffsets[i] = null; | 182 constantNamesAndOffsetsAndDocs[i] = null; |
181 continue; | 183 continue; |
182 } | 184 } |
183 if (name == className) { | 185 if (name == className) { |
184 parent.addCompileTimeError( | 186 parent.addCompileTimeError( |
185 templateEnumConstantSameNameAsEnclosing.withArguments(name), | 187 templateEnumConstantSameNameAsEnclosing.withArguments(name), |
186 charOffset, | 188 charOffset, |
187 parent.fileUri); | 189 parent.fileUri); |
188 constantNamesAndOffsets[i] = null; | 190 constantNamesAndOffsetsAndDocs[i] = null; |
189 continue; | 191 continue; |
190 } | 192 } |
191 KernelFieldBuilder fieldBuilder = new KernelFieldBuilder( | 193 KernelFieldBuilder fieldBuilder = new KernelFieldBuilder( |
192 null, | 194 documentationComment, |
193 null, | 195 null, |
194 selfType, | 196 selfType, |
195 name, | 197 name, |
196 constMask | staticMask, | 198 constMask | staticMask, |
197 parent, | 199 parent, |
198 charOffset, | 200 charOffset, |
199 null, | 201 null, |
200 true); | 202 true); |
201 members[name] = fieldBuilder; | 203 members[name] = fieldBuilder; |
202 toStringEntries.add(new MapEntry( | 204 toStringEntries.add(new MapEntry( |
203 new IntLiteral(index), new StringLiteral("$className.$name"))); | 205 new IntLiteral(index), new StringLiteral("$className.$name"))); |
204 index++; | 206 index++; |
205 } | 207 } |
206 MapLiteral toStringMap = new MapLiteral(toStringEntries, isConst: true); | 208 MapLiteral toStringMap = new MapLiteral(toStringEntries, isConst: true); |
207 KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal( | 209 KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal( |
208 null, | 210 documentationComment, |
209 metadata, | 211 metadata, |
210 name, | 212 name, |
211 new Scope(members, null, parent.scope, isModifiable: false), | 213 new Scope(members, null, parent.scope, isModifiable: false), |
212 new Scope(constructors, null, null, isModifiable: false), | 214 new Scope(constructors, null, null, isModifiable: false), |
213 cls, | 215 cls, |
214 constantNamesAndOffsets, | 216 constantNamesAndOffsetsAndDocs, |
215 toStringMap, | 217 toStringMap, |
216 intType, | 218 intType, |
217 listType, | 219 listType, |
218 objectType, | 220 objectType, |
219 stringType, | 221 stringType, |
220 parent, | 222 parent, |
221 charOffset); | 223 charOffset); |
222 // TODO(sigmund): dynamic should be `covariant MemberBuilder`. | 224 // TODO(sigmund): dynamic should be `covariant MemberBuilder`. |
223 void setParent(String name, dynamic b) { | 225 void setParent(String name, dynamic b) { |
224 MemberBuilder builder = b; | 226 MemberBuilder builder = b; |
225 builder.parent = enumBuilder; | 227 builder.parent = enumBuilder; |
226 } | 228 } |
227 | 229 |
228 members.forEach(setParent); | 230 members.forEach(setParent); |
229 constructors.forEach(setParent); | 231 constructors.forEach(setParent); |
230 selfType.bind(enumBuilder); | 232 selfType.bind(enumBuilder); |
231 return enumBuilder; | 233 return enumBuilder; |
232 } | 234 } |
233 | 235 |
234 KernelTypeBuilder get mixedInType => null; | 236 KernelTypeBuilder get mixedInType => null; |
235 | 237 |
236 InterfaceType buildType( | 238 InterfaceType buildType( |
237 LibraryBuilder library, List<KernelTypeBuilder> arguments) { | 239 LibraryBuilder library, List<KernelTypeBuilder> arguments) { |
238 return cls.rawType; | 240 return cls.rawType; |
239 } | 241 } |
240 | 242 |
241 @override | 243 @override |
242 Class build(KernelLibraryBuilder libraryBuilder, LibraryBuilder coreLibrary) { | 244 Class build(KernelLibraryBuilder libraryBuilder, LibraryBuilder coreLibrary) { |
243 cls.isEnum = true; | 245 cls.isEnum = true; |
244 if (constantNamesAndOffsets.isEmpty) { | 246 if (constantNamesAndOffsetsAndDocs.isEmpty) { |
245 libraryBuilder.addCompileTimeError( | 247 libraryBuilder.addCompileTimeError( |
246 messageEnumDeclartionEmpty, charOffset, fileUri); | 248 messageEnumDeclartionEmpty, charOffset, fileUri); |
247 } | 249 } |
248 intType.resolveIn(coreLibrary.scope); | 250 intType.resolveIn(coreLibrary.scope); |
249 stringType.resolveIn(coreLibrary.scope); | 251 stringType.resolveIn(coreLibrary.scope); |
250 objectType.resolveIn(coreLibrary.scope); | 252 objectType.resolveIn(coreLibrary.scope); |
251 listType.resolveIn(coreLibrary.scope); | 253 listType.resolveIn(coreLibrary.scope); |
252 toStringMap.keyType = intType.build(libraryBuilder); | 254 toStringMap.keyType = intType.build(libraryBuilder); |
253 toStringMap.valueType = stringType.build(libraryBuilder); | 255 toStringMap.valueType = stringType.build(libraryBuilder); |
254 KernelFieldBuilder indexFieldBuilder = this["index"]; | 256 KernelFieldBuilder indexFieldBuilder = this["index"]; |
255 Field indexField = indexFieldBuilder.build(libraryBuilder); | 257 Field indexField = indexFieldBuilder.build(libraryBuilder); |
256 KernelProcedureBuilder toStringBuilder = this["toString"]; | 258 KernelProcedureBuilder toStringBuilder = this["toString"]; |
257 toStringBuilder.body = new ReturnStatement(new MethodInvocation( | 259 toStringBuilder.body = new ReturnStatement(new MethodInvocation( |
258 toStringMap, | 260 toStringMap, |
259 indexGetName, | 261 indexGetName, |
260 new Arguments(<Expression>[ | 262 new Arguments(<Expression>[ |
261 new DirectPropertyGet(new ThisExpression(), indexField) | 263 new DirectPropertyGet(new ThisExpression(), indexField) |
262 ]))); | 264 ]))); |
263 List<Expression> values = <Expression>[]; | 265 List<Expression> values = <Expression>[]; |
264 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { | 266 for (int i = 0; i < constantNamesAndOffsetsAndDocs.length; i += 3) { |
265 String name = constantNamesAndOffsets[i]; | 267 String name = constantNamesAndOffsetsAndDocs[i]; |
266 if (name != null) { | 268 if (name != null) { |
267 KernelFieldBuilder builder = this[name]; | 269 KernelFieldBuilder builder = this[name]; |
268 values.add(new StaticGet(builder.build(libraryBuilder))); | 270 values.add(new StaticGet(builder.build(libraryBuilder))); |
269 } | 271 } |
270 } | 272 } |
271 KernelFieldBuilder valuesBuilder = this["values"]; | 273 KernelFieldBuilder valuesBuilder = this["values"]; |
272 valuesBuilder.build(libraryBuilder); | 274 valuesBuilder.build(libraryBuilder); |
273 valuesBuilder.initializer = | 275 valuesBuilder.initializer = |
274 new ListLiteral(values, typeArgument: cls.rawType, isConst: true); | 276 new ListLiteral(values, typeArgument: cls.rawType, isConst: true); |
275 KernelConstructorBuilder constructorBuilder = constructorScopeBuilder[""]; | 277 KernelConstructorBuilder constructorBuilder = constructorScopeBuilder[""]; |
(...skipping 11 matching lines...) Expand all Loading... |
287 // unnamed constructor requires no arguments. But that information isn't | 289 // unnamed constructor requires no arguments. But that information isn't |
288 // always available at this point, and it's not really a situation that | 290 // always available at this point, and it's not really a situation that |
289 // can happen unless you start modifying the SDK sources. | 291 // can happen unless you start modifying the SDK sources. |
290 addCompileTimeError(messageNoUnnamedConstructorInObject, -1); | 292 addCompileTimeError(messageNoUnnamedConstructorInObject, -1); |
291 } else { | 293 } else { |
292 constructor.initializers.add( | 294 constructor.initializers.add( |
293 new SuperInitializer(superConstructor.target, new Arguments.empty()) | 295 new SuperInitializer(superConstructor.target, new Arguments.empty()) |
294 ..parent = constructor); | 296 ..parent = constructor); |
295 } | 297 } |
296 int index = 0; | 298 int index = 0; |
297 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { | 299 for (int i = 0; i < constantNamesAndOffsetsAndDocs.length; i += 3) { |
298 String constant = constantNamesAndOffsets[i]; | 300 String constant = constantNamesAndOffsetsAndDocs[i]; |
299 if (constant != null) { | 301 if (constant != null) { |
300 KernelFieldBuilder field = this[constant]; | 302 KernelFieldBuilder field = this[constant]; |
301 field.build(libraryBuilder); | 303 field.build(libraryBuilder); |
302 Arguments arguments = | 304 Arguments arguments = |
303 new Arguments(<Expression>[new IntLiteral(index++)]); | 305 new Arguments(<Expression>[new IntLiteral(index++)]); |
304 field.initializer = | 306 field.initializer = |
305 new ConstructorInvocation(constructor, arguments, isConst: true); | 307 new ConstructorInvocation(constructor, arguments, isConst: true); |
306 } | 308 } |
307 } | 309 } |
308 return super.build(libraryBuilder, coreLibrary); | 310 return super.build(libraryBuilder, coreLibrary); |
309 } | 311 } |
310 | 312 |
311 @override | 313 @override |
312 Builder findConstructorOrFactory( | 314 Builder findConstructorOrFactory( |
313 String name, int charOffset, Uri uri, LibraryBuilder library) { | 315 String name, int charOffset, Uri uri, LibraryBuilder library) { |
314 return null; | 316 return null; |
315 } | 317 } |
316 } | 318 } |
OLD | NEW |