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 library fasta.kernel_enum_builder; |
| 6 |
| 7 import 'package:kernel/ast.dart' show |
| 8 Arguments, |
| 9 AsyncMarker, |
| 10 Class, |
| 11 Constructor, |
| 12 ConstructorInvocation, |
| 13 DirectPropertyGet, |
| 14 Expression, |
| 15 Field, |
| 16 FieldInitializer, |
| 17 IntLiteral, |
| 18 InterfaceType, |
| 19 ListLiteral, |
| 20 MapEntry, |
| 21 MapLiteral, |
| 22 MethodInvocation, |
| 23 Name, |
| 24 ProcedureKind, |
| 25 ReturnStatement, |
| 26 StaticGet, |
| 27 StringLiteral, |
| 28 ThisExpression, |
| 29 VariableGet; |
| 30 |
| 31 import '../errors.dart' show |
| 32 inputError; |
| 33 |
| 34 import '../modifier.dart' show |
| 35 constMask, |
| 36 finalMask, |
| 37 staticMask; |
| 38 |
| 39 import "../source/source_class_builder.dart" show |
| 40 SourceClassBuilder; |
| 41 |
| 42 import 'kernel_builder.dart' show |
| 43 Builder, |
| 44 EnumBuilder, |
| 45 FormalParameterBuilder, |
| 46 KernelConstructorBuilder, |
| 47 KernelFieldBuilder, |
| 48 KernelFormalParameterBuilder, |
| 49 KernelInterfaceTypeBuilder, |
| 50 KernelLibraryBuilder, |
| 51 KernelProcedureBuilder, |
| 52 KernelTypeBuilder, |
| 53 LibraryBuilder, |
| 54 MemberBuilder, |
| 55 MetadataBuilder; |
| 56 |
| 57 class KernelEnumBuilder extends SourceClassBuilder |
| 58 implements EnumBuilder<KernelTypeBuilder, InterfaceType> { |
| 59 final List<String> constants; |
| 60 |
| 61 final MapLiteral toStringMap; |
| 62 |
| 63 final KernelTypeBuilder intType; |
| 64 |
| 65 final KernelTypeBuilder stringType; |
| 66 |
| 67 KernelEnumBuilder.internal(List<MetadataBuilder> metadata, String name, |
| 68 Map<String, Builder> members, List<KernelTypeBuilder> types, Class cls, |
| 69 this.constants, this.toStringMap, this.intType, this.stringType, |
| 70 LibraryBuilder parent) |
| 71 : super(metadata, 0, name, null, null, null, members, types, parent, null, |
| 72 cls); |
| 73 |
| 74 factory KernelEnumBuilder(List<MetadataBuilder> metadata, String name, |
| 75 List<String> constants, LibraryBuilder parent) { |
| 76 constants ??= const <String>[]; |
| 77 // TODO(ahe): These types shouldn't be looked up in scope, they come |
| 78 // directly from dart:core. |
| 79 KernelTypeBuilder objectType = |
| 80 new KernelInterfaceTypeBuilder("Object", null); |
| 81 KernelTypeBuilder intType = |
| 82 new KernelInterfaceTypeBuilder("int", null); |
| 83 KernelTypeBuilder stringType = |
| 84 new KernelInterfaceTypeBuilder("String", null); |
| 85 List<KernelTypeBuilder> types = <KernelTypeBuilder>[ |
| 86 objectType, |
| 87 intType, |
| 88 stringType]; |
| 89 Class cls = new Class(name: name); |
| 90 Map<String, Builder> members = <String, Builder>{}; |
| 91 KernelInterfaceTypeBuilder selfType = new KernelInterfaceTypeBuilder( |
| 92 name, null); |
| 93 KernelTypeBuilder listType = |
| 94 new KernelInterfaceTypeBuilder("List", <KernelTypeBuilder>[selfType]); |
| 95 types.add(listType); |
| 96 |
| 97 /// From Dart Programming Language Specification 4th Edition/December 2015: |
| 98 /// metadata class E { |
| 99 /// final int index; |
| 100 /// const E(this.index); |
| 101 /// static const E id0 = const E(0); |
| 102 /// ... |
| 103 /// static const E idn-1 = const E(n - 1); |
| 104 /// static const List<E> values = const <E>[id0, ..., idn-1]; |
| 105 /// String toString() => { 0: ‘E.id0’, . . ., n-1: ‘E.idn-1’}[index] |
| 106 /// } |
| 107 members["index"] = |
| 108 new KernelFieldBuilder(null, intType, "index", finalMask); |
| 109 KernelConstructorBuilder constructorBuilder = new KernelConstructorBuilder( |
| 110 null, constMask, null, "", null, <FormalParameterBuilder>[ |
| 111 new KernelFormalParameterBuilder(null, 0, intType, "index", true)]); |
| 112 members[""] = constructorBuilder; |
| 113 int index = 0; |
| 114 List<MapEntry> toStringEntries = <MapEntry>[]; |
| 115 KernelFieldBuilder valuesBuilder = new KernelFieldBuilder(null, listType, |
| 116 "values", constMask | staticMask); |
| 117 members["values"] = valuesBuilder; |
| 118 KernelProcedureBuilder toStringBuilder = new KernelProcedureBuilder(null, 0, |
| 119 stringType, "toString", null, null, AsyncMarker.Sync, |
| 120 ProcedureKind.Method); |
| 121 members["toString"] = toStringBuilder; |
| 122 String className = name; |
| 123 for (String name in constants) { |
| 124 if (members.containsKey(name)) { |
| 125 inputError(null, null, "Duplicated name: $name"); |
| 126 continue; |
| 127 } |
| 128 KernelFieldBuilder fieldBuilder = |
| 129 new KernelFieldBuilder(null, selfType, name, constMask | staticMask); |
| 130 members[name] = fieldBuilder; |
| 131 toStringEntries.add(new MapEntry( |
| 132 new IntLiteral(index), new StringLiteral("$className.$name"))); |
| 133 index++; |
| 134 } |
| 135 MapLiteral toStringMap = new MapLiteral(toStringEntries, isConst: true); |
| 136 KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal(metadata, |
| 137 name, members, types, cls, constants, toStringMap, intType, stringType, |
| 138 parent); |
| 139 members.forEach((String name, MemberBuilder builder) { |
| 140 builder.parent = enumBuilder; |
| 141 }); |
| 142 selfType.builder = enumBuilder; |
| 143 return enumBuilder; |
| 144 } |
| 145 |
| 146 InterfaceType buildType(List<KernelTypeBuilder> arguments) { |
| 147 return cls.rawType; |
| 148 } |
| 149 |
| 150 Class build(KernelLibraryBuilder libraryBuilder) { |
| 151 if (constants.isEmpty) { |
| 152 libraryBuilder.addCompileTimeError( |
| 153 -1, "An enum declaration can't be empty."); |
| 154 } |
| 155 toStringMap.keyType = intType.build(); |
| 156 toStringMap.valueType = stringType.build(); |
| 157 KernelFieldBuilder indexFieldBuilder = members["index"]; |
| 158 Field indexField = indexFieldBuilder.build(libraryBuilder.library); |
| 159 KernelProcedureBuilder toStringBuilder = members["toString"]; |
| 160 toStringBuilder.body = new ReturnStatement( |
| 161 new MethodInvocation(toStringMap, new Name("[]"), |
| 162 new Arguments(<Expression>[ |
| 163 new DirectPropertyGet(new ThisExpression(), indexField)]))); |
| 164 List<Expression> values = <Expression>[]; |
| 165 for (String name in constants) { |
| 166 KernelFieldBuilder builder = members[name]; |
| 167 values.add(new StaticGet(builder.build(libraryBuilder.library))); |
| 168 } |
| 169 KernelFieldBuilder valuesBuilder = members["values"]; |
| 170 valuesBuilder.build(libraryBuilder.library); |
| 171 valuesBuilder.initializer = |
| 172 new ListLiteral(values, typeArgument: cls.rawType, isConst: true); |
| 173 KernelConstructorBuilder constructorBuilder = members[""]; |
| 174 Constructor constructor = constructorBuilder.build(libraryBuilder.library); |
| 175 constructor.initializers.insert(0, new FieldInitializer(indexField, |
| 176 new VariableGet(constructor.function.positionalParameters.single)) |
| 177 ..parent = constructor); |
| 178 int index = 0; |
| 179 for (String constant in constants) { |
| 180 KernelFieldBuilder field = members[constant]; |
| 181 field.build(libraryBuilder.library); |
| 182 Arguments arguments = |
| 183 new Arguments(<Expression>[new IntLiteral(index++)]); |
| 184 field.initializer = |
| 185 new ConstructorInvocation(constructor, arguments, isConst: true); |
| 186 } |
| 187 return super.build(libraryBuilder); |
| 188 } |
| 189 |
| 190 Builder findConstructorOrFactory(String name) => null; |
| 191 } |
OLD | NEW |