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, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 KernelProcedureBuilder, | 47 KernelProcedureBuilder, |
48 KernelTypeBuilder, | 48 KernelTypeBuilder, |
49 LibraryBuilder, | 49 LibraryBuilder, |
50 MemberBuilder, | 50 MemberBuilder, |
51 MetadataBuilder; | 51 MetadataBuilder; |
52 | 52 |
53 import '../names.dart' show indexGetName; | 53 import '../names.dart' show indexGetName; |
54 | 54 |
55 class KernelEnumBuilder extends SourceClassBuilder | 55 class KernelEnumBuilder extends SourceClassBuilder |
56 implements EnumBuilder<KernelTypeBuilder, InterfaceType> { | 56 implements EnumBuilder<KernelTypeBuilder, InterfaceType> { |
57 final List<String> constants; | 57 final List<Object> constantNamesAndOffsets; |
58 | 58 |
59 final MapLiteral toStringMap; | 59 final MapLiteral toStringMap; |
60 | 60 |
61 final KernelTypeBuilder intType; | 61 final KernelTypeBuilder intType; |
62 | 62 |
63 final KernelTypeBuilder stringType; | 63 final KernelTypeBuilder stringType; |
64 | 64 |
65 KernelEnumBuilder.internal( | 65 KernelEnumBuilder.internal( |
66 List<MetadataBuilder> metadata, | 66 List<MetadataBuilder> metadata, |
67 String name, | 67 String name, |
68 Map<String, Builder> members, | 68 Map<String, Builder> members, |
69 Class cls, | 69 Class cls, |
70 this.constants, | 70 this.constantNamesAndOffsets, |
71 this.toStringMap, | 71 this.toStringMap, |
72 this.intType, | 72 this.intType, |
73 this.stringType, | 73 this.stringType, |
74 LibraryBuilder parent, | 74 LibraryBuilder parent, |
75 int charOffset) | 75 int charOffset) |
76 : super(metadata, 0, name, null, null, null, members, parent, null, | 76 : super(metadata, 0, name, null, null, null, members, parent, null, |
77 charOffset, cls); | 77 charOffset, cls); |
78 | 78 |
79 factory KernelEnumBuilder( | 79 factory KernelEnumBuilder( |
80 List<MetadataBuilder> metadata, | 80 List<MetadataBuilder> metadata, |
81 String name, | 81 String name, |
82 List<String> constants, | 82 List<Object> constantNamesAndOffsets, |
83 KernelLibraryBuilder parent, | 83 KernelLibraryBuilder parent, |
84 int charOffset, | 84 int charOffset, |
85 int charEndOffset) { | 85 int charEndOffset) { |
86 constants ??= const <String>[]; | 86 constantNamesAndOffsets ??= const <Object>[]; |
87 // TODO(ahe): These types shouldn't be looked up in scope, they come | 87 // TODO(ahe): These types shouldn't be looked up in scope, they come |
88 // directly from dart:core. | 88 // directly from dart:core. |
89 KernelTypeBuilder intType = parent.addType( | 89 KernelTypeBuilder intType = parent.addType( |
90 new KernelNamedTypeBuilder("int", null, charOffset, parent.fileUri)); | 90 new KernelNamedTypeBuilder("int", null, charOffset, parent.fileUri)); |
91 KernelTypeBuilder stringType = parent.addType( | 91 KernelTypeBuilder stringType = parent.addType( |
92 new KernelNamedTypeBuilder("String", null, charOffset, parent.fileUri)); | 92 new KernelNamedTypeBuilder("String", null, charOffset, parent.fileUri)); |
93 Class cls = new Class(name: name); | 93 Class cls = new Class(name: name); |
94 Map<String, Builder> members = <String, Builder>{}; | 94 Map<String, Builder> members = <String, Builder>{}; |
95 KernelNamedTypeBuilder selfType = | 95 KernelNamedTypeBuilder selfType = |
96 new KernelNamedTypeBuilder(name, null, charOffset, parent.fileUri); | 96 new KernelNamedTypeBuilder(name, null, charOffset, parent.fileUri); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 null, | 137 null, |
138 null, | 138 null, |
139 AsyncMarker.Sync, | 139 AsyncMarker.Sync, |
140 ProcedureKind.Method, | 140 ProcedureKind.Method, |
141 parent, | 141 parent, |
142 charOffset, | 142 charOffset, |
143 charOffset, | 143 charOffset, |
144 charEndOffset); | 144 charEndOffset); |
145 members["toString"] = toStringBuilder; | 145 members["toString"] = toStringBuilder; |
146 String className = name; | 146 String className = name; |
147 for (String name in constants) { | 147 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { |
| 148 String name = constantNamesAndOffsets[i]; |
| 149 int charOffset = constantNamesAndOffsets[i + 1]; |
148 if (members.containsKey(name)) { | 150 if (members.containsKey(name)) { |
149 inputError(null, null, "Duplicated name: $name"); | 151 inputError(null, null, "Duplicated name: $name"); |
150 continue; | 152 continue; |
151 } | 153 } |
152 KernelFieldBuilder fieldBuilder = new KernelFieldBuilder( | 154 KernelFieldBuilder fieldBuilder = new KernelFieldBuilder( |
153 null, | 155 null, selfType, name, constMask | staticMask, parent, charOffset); |
154 selfType, | |
155 name, | |
156 constMask | staticMask, | |
157 parent, | |
158 charOffset); // TODO(ahe): Get charOffset from [name]. | |
159 members[name] = fieldBuilder; | 156 members[name] = fieldBuilder; |
160 toStringEntries.add(new MapEntry( | 157 toStringEntries.add(new MapEntry( |
161 new IntLiteral(index), new StringLiteral("$className.$name"))); | 158 new IntLiteral(index), new StringLiteral("$className.$name"))); |
162 index++; | 159 index++; |
163 } | 160 } |
164 MapLiteral toStringMap = new MapLiteral(toStringEntries, isConst: true); | 161 MapLiteral toStringMap = new MapLiteral(toStringEntries, isConst: true); |
165 KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal( | 162 KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal( |
166 metadata, | 163 metadata, |
167 name, | 164 name, |
168 members, | 165 members, |
169 cls, | 166 cls, |
170 constants, | 167 constantNamesAndOffsets, |
171 toStringMap, | 168 toStringMap, |
172 intType, | 169 intType, |
173 stringType, | 170 stringType, |
174 parent, | 171 parent, |
175 charOffset); | 172 charOffset); |
176 // TODO(sigmund): dynamic should be `covariant MemberBuilder`. | 173 // TODO(sigmund): dynamic should be `covariant MemberBuilder`. |
177 members.forEach((String name, dynamic b) { | 174 members.forEach((String name, dynamic b) { |
178 MemberBuilder builder = b; | 175 MemberBuilder builder = b; |
179 builder.parent = enumBuilder; | 176 builder.parent = enumBuilder; |
180 }); | 177 }); |
181 selfType.builder = enumBuilder; | 178 selfType.builder = enumBuilder; |
182 return enumBuilder; | 179 return enumBuilder; |
183 } | 180 } |
184 | 181 |
185 KernelTypeBuilder get mixedInType => null; | 182 KernelTypeBuilder get mixedInType => null; |
186 | 183 |
187 InterfaceType buildType( | 184 InterfaceType buildType( |
188 LibraryBuilder library, List<KernelTypeBuilder> arguments) { | 185 LibraryBuilder library, List<KernelTypeBuilder> arguments) { |
189 return cls.rawType; | 186 return cls.rawType; |
190 } | 187 } |
191 | 188 |
192 Class build(KernelLibraryBuilder libraryBuilder) { | 189 Class build(KernelLibraryBuilder libraryBuilder) { |
193 if (constants.isEmpty) { | 190 if (constantNamesAndOffsets.isEmpty) { |
194 libraryBuilder.addCompileTimeError( | 191 libraryBuilder.addCompileTimeError( |
195 -1, "An enum declaration can't be empty."); | 192 -1, "An enum declaration can't be empty."); |
196 } | 193 } |
197 toStringMap.keyType = intType.build(libraryBuilder); | 194 toStringMap.keyType = intType.build(libraryBuilder); |
198 toStringMap.valueType = stringType.build(libraryBuilder); | 195 toStringMap.valueType = stringType.build(libraryBuilder); |
199 KernelFieldBuilder indexFieldBuilder = members["index"]; | 196 KernelFieldBuilder indexFieldBuilder = members["index"]; |
200 Field indexField = indexFieldBuilder.build(libraryBuilder); | 197 Field indexField = indexFieldBuilder.build(libraryBuilder); |
201 KernelProcedureBuilder toStringBuilder = members["toString"]; | 198 KernelProcedureBuilder toStringBuilder = members["toString"]; |
202 toStringBuilder.body = new ReturnStatement(new MethodInvocation( | 199 toStringBuilder.body = new ReturnStatement(new MethodInvocation( |
203 toStringMap, | 200 toStringMap, |
204 indexGetName, | 201 indexGetName, |
205 new Arguments(<Expression>[ | 202 new Arguments(<Expression>[ |
206 new DirectPropertyGet(new ThisExpression(), indexField) | 203 new DirectPropertyGet(new ThisExpression(), indexField) |
207 ]))); | 204 ]))); |
208 List<Expression> values = <Expression>[]; | 205 List<Expression> values = <Expression>[]; |
209 for (String name in constants) { | 206 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { |
| 207 String name = constantNamesAndOffsets[i]; |
210 KernelFieldBuilder builder = members[name]; | 208 KernelFieldBuilder builder = members[name]; |
211 values.add(new StaticGet(builder.build(libraryBuilder))); | 209 values.add(new StaticGet(builder.build(libraryBuilder))); |
212 } | 210 } |
213 KernelFieldBuilder valuesBuilder = members["values"]; | 211 KernelFieldBuilder valuesBuilder = members["values"]; |
214 valuesBuilder.build(libraryBuilder); | 212 valuesBuilder.build(libraryBuilder); |
215 valuesBuilder.initializer = | 213 valuesBuilder.initializer = |
216 new ListLiteral(values, typeArgument: cls.rawType, isConst: true); | 214 new ListLiteral(values, typeArgument: cls.rawType, isConst: true); |
217 KernelConstructorBuilder constructorBuilder = members[""]; | 215 KernelConstructorBuilder constructorBuilder = members[""]; |
218 Constructor constructor = constructorBuilder.build(libraryBuilder); | 216 Constructor constructor = constructorBuilder.build(libraryBuilder); |
219 constructor.initializers.insert( | 217 constructor.initializers.insert( |
220 0, | 218 0, |
221 new FieldInitializer(indexField, | 219 new FieldInitializer(indexField, |
222 new VariableGet(constructor.function.positionalParameters.single)) | 220 new VariableGet(constructor.function.positionalParameters.single)) |
223 ..parent = constructor); | 221 ..parent = constructor); |
224 int index = 0; | 222 int index = 0; |
225 for (String constant in constants) { | 223 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { |
| 224 String constant = constantNamesAndOffsets[i]; |
226 KernelFieldBuilder field = members[constant]; | 225 KernelFieldBuilder field = members[constant]; |
227 field.build(libraryBuilder); | 226 field.build(libraryBuilder); |
228 Arguments arguments = | 227 Arguments arguments = |
229 new Arguments(<Expression>[new IntLiteral(index++)]); | 228 new Arguments(<Expression>[new IntLiteral(index++)]); |
230 field.initializer = | 229 field.initializer = |
231 new ConstructorInvocation(constructor, arguments, isConst: true); | 230 new ConstructorInvocation(constructor, arguments, isConst: true); |
232 } | 231 } |
233 return super.build(libraryBuilder); | 232 return super.build(libraryBuilder); |
234 } | 233 } |
235 | 234 |
236 Builder findConstructorOrFactory(String name) => null; | 235 Builder findConstructorOrFactory(String name) => null; |
237 } | 236 } |
OLD | NEW |