Chromium Code Reviews| 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 AsyncMarker, | 10 AsyncMarker, |
| 11 Class, | 11 Class, |
| 12 Constructor, | 12 Constructor, |
| 13 ConstructorInvocation, | 13 ConstructorInvocation, |
| 14 DirectPropertyGet, | 14 DirectPropertyGet, |
| 15 Expression, | 15 Expression, |
| 16 Field, | 16 Field, |
| 17 FieldInitializer, | 17 FieldInitializer, |
| 18 IntLiteral, | 18 IntLiteral, |
| 19 InterfaceType, | 19 InterfaceType, |
| 20 ListLiteral, | 20 ListLiteral, |
| 21 MapEntry, | 21 MapEntry, |
| 22 MapLiteral, | 22 MapLiteral, |
| 23 MethodInvocation, | 23 MethodInvocation, |
| 24 ProcedureKind, | 24 ProcedureKind, |
| 25 ReturnStatement, | 25 ReturnStatement, |
| 26 StaticGet, | 26 StaticGet, |
| 27 StringLiteral, | 27 StringLiteral, |
| 28 SuperInitializer, | |
| 28 ThisExpression, | 29 ThisExpression, |
| 29 VariableGet; | 30 VariableGet; |
| 30 | 31 |
| 31 import '../errors.dart' show inputError; | 32 import '../errors.dart' show inputError; |
| 32 | 33 |
| 33 import '../modifier.dart' show constMask, finalMask, staticMask; | 34 import '../modifier.dart' show constMask, finalMask, staticMask; |
| 34 | 35 |
| 35 import '../names.dart' show indexGetName; | 36 import '../names.dart' show indexGetName; |
| 36 | 37 |
| 37 import '../source/source_class_builder.dart' show SourceClassBuilder; | 38 import '../source/source_class_builder.dart' show SourceClassBuilder; |
| 38 | 39 |
| 39 import 'kernel_builder.dart' | 40 import 'kernel_builder.dart' |
| 40 show | 41 show |
| 41 Builder, | 42 Builder, |
| 42 EnumBuilder, | 43 EnumBuilder, |
| 43 FormalParameterBuilder, | 44 FormalParameterBuilder, |
| 45 KernelClassBuilder, | |
| 44 KernelConstructorBuilder, | 46 KernelConstructorBuilder, |
| 45 KernelFieldBuilder, | 47 KernelFieldBuilder, |
| 46 KernelFormalParameterBuilder, | 48 KernelFormalParameterBuilder, |
| 47 KernelLibraryBuilder, | 49 KernelLibraryBuilder, |
| 48 KernelNamedTypeBuilder, | 50 KernelNamedTypeBuilder, |
| 49 KernelProcedureBuilder, | 51 KernelProcedureBuilder, |
| 50 KernelTypeBuilder, | 52 KernelTypeBuilder, |
| 51 LibraryBuilder, | 53 LibraryBuilder, |
| 52 MemberBuilder, | 54 MemberBuilder, |
| 53 MetadataBuilder, | 55 MetadataBuilder, |
| 54 Scope; | 56 Scope; |
| 55 | 57 |
| 56 class KernelEnumBuilder extends SourceClassBuilder | 58 class KernelEnumBuilder extends SourceClassBuilder |
| 57 implements EnumBuilder<KernelTypeBuilder, InterfaceType> { | 59 implements EnumBuilder<KernelTypeBuilder, InterfaceType> { |
| 58 final List<Object> constantNamesAndOffsets; | 60 final List<Object> constantNamesAndOffsets; |
| 59 | 61 |
| 60 final MapLiteral toStringMap; | 62 final MapLiteral toStringMap; |
| 61 | 63 |
| 62 final KernelTypeBuilder intType; | 64 final KernelNamedTypeBuilder intType; |
| 63 | 65 |
| 64 final KernelTypeBuilder stringType; | 66 final KernelNamedTypeBuilder stringType; |
| 67 | |
| 68 final KernelNamedTypeBuilder objectType; | |
| 69 | |
| 70 final KernelNamedTypeBuilder listType; | |
| 65 | 71 |
| 66 KernelEnumBuilder.internal( | 72 KernelEnumBuilder.internal( |
| 67 List<MetadataBuilder> metadata, | 73 List<MetadataBuilder> metadata, |
| 68 String name, | 74 String name, |
| 69 Scope scope, | 75 Scope scope, |
| 70 Scope constructors, | 76 Scope constructors, |
| 71 Class cls, | 77 Class cls, |
| 72 this.constantNamesAndOffsets, | 78 this.constantNamesAndOffsets, |
| 73 this.toStringMap, | 79 this.toStringMap, |
| 74 this.intType, | 80 this.intType, |
| 81 this.listType, | |
| 82 this.objectType, | |
| 75 this.stringType, | 83 this.stringType, |
| 76 LibraryBuilder parent, | 84 LibraryBuilder parent, |
| 77 int charOffset) | 85 int charOffset) |
| 78 : super(metadata, 0, name, null, null, null, scope, constructors, parent, | 86 : super(metadata, 0, name, null, null, null, scope, constructors, parent, |
| 79 null, charOffset, cls); | 87 null, charOffset, cls); |
| 80 | 88 |
| 81 factory KernelEnumBuilder( | 89 factory KernelEnumBuilder( |
| 82 List<MetadataBuilder> metadata, | 90 List<MetadataBuilder> metadata, |
| 83 String name, | 91 String name, |
| 84 List<Object> constantNamesAndOffsets, | 92 List<Object> constantNamesAndOffsets, |
| 85 KernelLibraryBuilder parent, | 93 KernelLibraryBuilder parent, |
| 86 int charOffset, | 94 int charOffset, |
| 87 int charEndOffset) { | 95 int charEndOffset) { |
| 88 constantNamesAndOffsets ??= const <Object>[]; | 96 constantNamesAndOffsets ??= const <Object>[]; |
| 89 // TODO(ahe): These types shouldn't be looked up in scope, they come | 97 // TODO(ahe): These types shouldn't be looked up in scope, they come |
| 90 // directly from dart:core. | 98 // directly from dart:core. |
| 91 KernelTypeBuilder intType = parent.addType( | 99 KernelTypeBuilder intType = |
| 92 new KernelNamedTypeBuilder("int", null, charOffset, parent.fileUri)); | 100 new KernelNamedTypeBuilder("int", null, charOffset, parent.fileUri); |
| 93 KernelTypeBuilder stringType = parent.addType( | 101 KernelTypeBuilder stringType = |
| 94 new KernelNamedTypeBuilder("String", null, charOffset, parent.fileUri)); | 102 new KernelNamedTypeBuilder("String", null, charOffset, parent.fileUri); |
| 103 KernelNamedTypeBuilder objectType = | |
| 104 new KernelNamedTypeBuilder("Object", null, charOffset, parent.fileUri); | |
| 95 Class cls = new Class(name: name); | 105 Class cls = new Class(name: name); |
| 96 Map<String, MemberBuilder> members = <String, MemberBuilder>{}; | 106 Map<String, MemberBuilder> members = <String, MemberBuilder>{}; |
| 97 Map<String, MemberBuilder> constructors = <String, MemberBuilder>{}; | 107 Map<String, MemberBuilder> constructors = <String, MemberBuilder>{}; |
| 98 KernelNamedTypeBuilder selfType = | 108 KernelNamedTypeBuilder selfType = |
| 99 new KernelNamedTypeBuilder(name, null, charOffset, parent.fileUri); | 109 new KernelNamedTypeBuilder(name, null, charOffset, parent.fileUri); |
| 100 KernelTypeBuilder listType = parent.addType(new KernelNamedTypeBuilder( | 110 KernelTypeBuilder listType = new KernelNamedTypeBuilder( |
| 101 "List", <KernelTypeBuilder>[selfType], charOffset, parent.fileUri)); | 111 "List", <KernelTypeBuilder>[selfType], charOffset, parent.fileUri); |
| 102 | 112 |
| 103 /// From Dart Programming Language Specification 4th Edition/December 2015: | 113 /// From Dart Programming Language Specification 4th Edition/December 2015: |
| 104 /// metadata class E { | 114 /// metadata class E { |
| 105 /// final int index; | 115 /// final int index; |
| 106 /// const E(this.index); | 116 /// const E(this.index); |
| 107 /// static const E id0 = const E(0); | 117 /// static const E id0 = const E(0); |
| 108 /// ... | 118 /// ... |
| 109 /// static const E idn-1 = const E(n - 1); | 119 /// static const E idn-1 = const E(n - 1); |
| 110 /// static const List<E> values = const <E>[id0, ..., idn-1]; | 120 /// static const List<E> values = const <E>[id0, ..., idn-1]; |
| 111 /// String toString() => { 0: ‘E.id0’, . . ., n-1: ‘E.idn-1’}[index] | 121 /// String toString() => { 0: ‘E.id0’, . . ., n-1: ‘E.idn-1’}[index] |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 MapLiteral toStringMap = new MapLiteral(toStringEntries, isConst: true); | 174 MapLiteral toStringMap = new MapLiteral(toStringEntries, isConst: true); |
| 165 KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal( | 175 KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal( |
| 166 metadata, | 176 metadata, |
| 167 name, | 177 name, |
| 168 new Scope(members, null, parent.scope, isModifiable: false), | 178 new Scope(members, null, parent.scope, isModifiable: false), |
| 169 new Scope(constructors, null, null, isModifiable: false), | 179 new Scope(constructors, null, null, isModifiable: false), |
| 170 cls, | 180 cls, |
| 171 constantNamesAndOffsets, | 181 constantNamesAndOffsets, |
| 172 toStringMap, | 182 toStringMap, |
| 173 intType, | 183 intType, |
| 184 listType, | |
| 185 objectType, | |
| 174 stringType, | 186 stringType, |
| 175 parent, | 187 parent, |
| 176 charOffset); | 188 charOffset); |
| 177 // TODO(sigmund): dynamic should be `covariant MemberBuilder`. | 189 // TODO(sigmund): dynamic should be `covariant MemberBuilder`. |
| 178 void setParent(String name, dynamic b) { | 190 void setParent(String name, dynamic b) { |
| 179 MemberBuilder builder = b; | 191 MemberBuilder builder = b; |
| 180 builder.parent = enumBuilder; | 192 builder.parent = enumBuilder; |
| 181 } | 193 } |
| 182 | 194 |
| 183 members.forEach(setParent); | 195 members.forEach(setParent); |
| 184 constructors.forEach(setParent); | 196 constructors.forEach(setParent); |
| 185 selfType.builder = enumBuilder; | 197 selfType.bind(enumBuilder); |
| 186 return enumBuilder; | 198 return enumBuilder; |
| 187 } | 199 } |
| 188 | 200 |
| 189 KernelTypeBuilder get mixedInType => null; | 201 KernelTypeBuilder get mixedInType => null; |
| 190 | 202 |
| 191 InterfaceType buildType( | 203 InterfaceType buildType( |
| 192 LibraryBuilder library, List<KernelTypeBuilder> arguments) { | 204 LibraryBuilder library, List<KernelTypeBuilder> arguments) { |
| 193 return cls.rawType; | 205 return cls.rawType; |
| 194 } | 206 } |
| 195 | 207 |
| 196 Class build(KernelLibraryBuilder libraryBuilder) { | 208 @override |
| 209 Class build(KernelLibraryBuilder libraryBuilder, LibraryBuilder coreLibrary) { | |
| 197 if (constantNamesAndOffsets.isEmpty) { | 210 if (constantNamesAndOffsets.isEmpty) { |
| 198 libraryBuilder.addCompileTimeError( | 211 libraryBuilder.addCompileTimeError( |
| 199 -1, "An enum declaration can't be empty."); | 212 -1, "An enum declaration can't be empty."); |
| 200 } | 213 } |
| 214 intType.resolveIn(coreLibrary.scope); | |
| 215 stringType.resolveIn(coreLibrary.scope); | |
| 216 objectType.resolveIn(coreLibrary.scope); | |
| 217 listType.resolveIn(coreLibrary.scope); | |
| 201 toStringMap.keyType = intType.build(libraryBuilder); | 218 toStringMap.keyType = intType.build(libraryBuilder); |
| 202 toStringMap.valueType = stringType.build(libraryBuilder); | 219 toStringMap.valueType = stringType.build(libraryBuilder); |
| 203 KernelFieldBuilder indexFieldBuilder = this["index"]; | 220 KernelFieldBuilder indexFieldBuilder = this["index"]; |
| 204 Field indexField = indexFieldBuilder.build(libraryBuilder); | 221 Field indexField = indexFieldBuilder.build(libraryBuilder); |
| 205 KernelProcedureBuilder toStringBuilder = this["toString"]; | 222 KernelProcedureBuilder toStringBuilder = this["toString"]; |
| 206 toStringBuilder.body = new ReturnStatement(new MethodInvocation( | 223 toStringBuilder.body = new ReturnStatement(new MethodInvocation( |
| 207 toStringMap, | 224 toStringMap, |
| 208 indexGetName, | 225 indexGetName, |
| 209 new Arguments(<Expression>[ | 226 new Arguments(<Expression>[ |
| 210 new DirectPropertyGet(new ThisExpression(), indexField) | 227 new DirectPropertyGet(new ThisExpression(), indexField) |
| 211 ]))); | 228 ]))); |
| 212 List<Expression> values = <Expression>[]; | 229 List<Expression> values = <Expression>[]; |
| 213 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { | 230 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { |
| 214 String name = constantNamesAndOffsets[i]; | 231 String name = constantNamesAndOffsets[i]; |
| 215 KernelFieldBuilder builder = this[name]; | 232 KernelFieldBuilder builder = this[name]; |
| 216 values.add(new StaticGet(builder.build(libraryBuilder))); | 233 values.add(new StaticGet(builder.build(libraryBuilder))); |
| 217 } | 234 } |
| 218 KernelFieldBuilder valuesBuilder = this["values"]; | 235 KernelFieldBuilder valuesBuilder = this["values"]; |
| 219 valuesBuilder.build(libraryBuilder); | 236 valuesBuilder.build(libraryBuilder); |
| 220 valuesBuilder.initializer = | 237 valuesBuilder.initializer = |
| 221 new ListLiteral(values, typeArgument: cls.rawType, isConst: true); | 238 new ListLiteral(values, typeArgument: cls.rawType, isConst: true); |
| 222 KernelConstructorBuilder constructorBuilder = constructorScopeBuilder[""]; | 239 KernelConstructorBuilder constructorBuilder = constructorScopeBuilder[""]; |
| 223 Constructor constructor = constructorBuilder.build(libraryBuilder); | 240 Constructor constructor = constructorBuilder.build(libraryBuilder); |
| 224 constructor.initializers.insert( | 241 constructor.initializers.insert( |
| 225 0, | 242 0, |
| 226 new FieldInitializer(indexField, | 243 new FieldInitializer(indexField, |
| 227 new VariableGet(constructor.function.positionalParameters.single)) | 244 new VariableGet(constructor.function.positionalParameters.single)) |
| 228 ..parent = constructor); | 245 ..parent = constructor); |
| 246 KernelClassBuilder objectClass = objectType.builder; | |
| 247 MemberBuilder superConstructor = | |
| 248 objectClass.findConstructorOrFactory("", charOffset, fileUri); | |
| 249 if (superConstructor == null || !superConstructor.isConstructor) { | |
| 250 addCompileTimeError( | |
| 251 -1, "'Object' has no constructor that takes no arguments."); | |
|
Paul Berry
2017/04/07 15:56:38
Similar issue here to the one above.
ahe
2017/04/07 18:19:18
Will do.
| |
| 252 } else { | |
| 253 constructor.initializers.add( | |
| 254 new SuperInitializer(superConstructor.target, new Arguments.empty()) | |
| 255 ..parent = constructor); | |
| 256 } | |
| 229 int index = 0; | 257 int index = 0; |
| 230 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { | 258 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { |
| 231 String constant = constantNamesAndOffsets[i]; | 259 String constant = constantNamesAndOffsets[i]; |
| 232 KernelFieldBuilder field = this[constant]; | 260 KernelFieldBuilder field = this[constant]; |
| 233 field.build(libraryBuilder); | 261 field.build(libraryBuilder); |
| 234 Arguments arguments = | 262 Arguments arguments = |
| 235 new Arguments(<Expression>[new IntLiteral(index++)]); | 263 new Arguments(<Expression>[new IntLiteral(index++)]); |
| 236 field.initializer = | 264 field.initializer = |
| 237 new ConstructorInvocation(constructor, arguments, isConst: true); | 265 new ConstructorInvocation(constructor, arguments, isConst: true); |
| 238 } | 266 } |
| 239 return super.build(libraryBuilder); | 267 return super.build(libraryBuilder, coreLibrary); |
| 240 } | 268 } |
| 241 | 269 |
| 242 @override | 270 @override |
| 243 Builder findConstructorOrFactory(String name, int charOffset, Uri uri) { | 271 Builder findConstructorOrFactory(String name, int charOffset, Uri uri) { |
| 244 return null; | 272 return null; |
| 245 } | 273 } |
| 246 } | 274 } |
| OLD | NEW |