Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(391)

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart

Issue 2800083002: Complain about incorrect this/super constructor initializers. (Closed)
Patch Set: Address comments. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 // TODO(ahe): Ideally, we would also want to check that [Object]'s
251 // unnamed constructor requires no arguments. But that information isn't
252 // always available at this point, and it's not really a situation that
253 // can happen unless you start modifying the SDK sources.
254 addCompileTimeError(-1, "'Object' has no unnamed constructor.");
255 } else {
256 constructor.initializers.add(
257 new SuperInitializer(superConstructor.target, new Arguments.empty())
258 ..parent = constructor);
259 }
229 int index = 0; 260 int index = 0;
230 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) { 261 for (int i = 0; i < constantNamesAndOffsets.length; i += 2) {
231 String constant = constantNamesAndOffsets[i]; 262 String constant = constantNamesAndOffsets[i];
232 KernelFieldBuilder field = this[constant]; 263 KernelFieldBuilder field = this[constant];
233 field.build(libraryBuilder); 264 field.build(libraryBuilder);
234 Arguments arguments = 265 Arguments arguments =
235 new Arguments(<Expression>[new IntLiteral(index++)]); 266 new Arguments(<Expression>[new IntLiteral(index++)]);
236 field.initializer = 267 field.initializer =
237 new ConstructorInvocation(constructor, arguments, isConst: true); 268 new ConstructorInvocation(constructor, arguments, isConst: true);
238 } 269 }
239 return super.build(libraryBuilder); 270 return super.build(libraryBuilder, coreLibrary);
240 } 271 }
241 272
242 @override 273 @override
243 Builder findConstructorOrFactory(String name, int charOffset, Uri uri) { 274 Builder findConstructorOrFactory(String name, int charOffset, Uri uri) {
244 return null; 275 return null;
245 } 276 }
246 } 277 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart ('k') | pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698