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

Side by Side Diff: pkg/front_end/lib/src/fasta/source/source_library_builder.dart

Issue 2689303003: Implement type variables in mixin applications. (Closed)
Patch Set: Address comments. Created 3 years, 10 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.source_library_builder; 5 library fasta.source_library_builder;
6 6
7 import 'package:kernel/ast.dart' show 7 import 'package:kernel/ast.dart' show
8 AsyncMarker, 8 AsyncMarker,
9 ProcedureKind; 9 ProcedureKind;
10 10
11 import '../combinator.dart' show 11 import '../combinator.dart' show
12 Combinator; 12 Combinator;
13 13
14 import '../errors.dart' show 14 import '../errors.dart' show
15 internalError; 15 internalError;
16 16
17 import '../import.dart' show 17 import '../import.dart' show
18 Import; 18 Import;
19 19
20 import 'source_loader.dart' show 20 import 'source_loader.dart' show
21 SourceLoader; 21 SourceLoader;
22 22
23 import '../builder/scope.dart' show 23 import '../builder/scope.dart' show
24 Scope; 24 Scope;
25 25
26 import '../builder/builder.dart' show 26 import '../builder/builder.dart' show
27 Builder, 27 Builder,
28 ClassBuilder,
28 ConstructorReferenceBuilder, 29 ConstructorReferenceBuilder,
29 FormalParameterBuilder, 30 FormalParameterBuilder,
30 LibraryBuilder, 31 LibraryBuilder,
31 MemberBuilder, 32 MemberBuilder,
32 MetadataBuilder, 33 MetadataBuilder,
33 PrefixBuilder, 34 PrefixBuilder,
34 ProcedureBuilder, 35 ProcedureBuilder,
35 TypeBuilder, 36 TypeBuilder,
36 TypeDeclarationBuilder, 37 TypeDeclarationBuilder,
37 TypeVariableBuilder, 38 TypeVariableBuilder,
(...skipping 12 matching lines...) Expand all
50 final List<SourceLibraryBuilder<T, R>> parts = <SourceLibraryBuilder<T, R>>[]; 51 final List<SourceLibraryBuilder<T, R>> parts = <SourceLibraryBuilder<T, R>>[];
51 52
52 final List<Import> imports = <Import>[]; 53 final List<Import> imports = <Import>[];
53 54
54 final Map<String, Builder> exports = <String, Builder>{}; 55 final Map<String, Builder> exports = <String, Builder>{};
55 56
56 final Scope scope = new Scope(<String, Builder>{}, null, isModifiable: false); 57 final Scope scope = new Scope(<String, Builder>{}, null, isModifiable: false);
57 58
58 final Uri fileUri; 59 final Uri fileUri;
59 60
61 final List<List> implementationBuilders = <List<List>>[];
62
60 String name; 63 String name;
61 64
62 String partOf; 65 String partOf;
63 66
64 List<MetadataBuilder> metadata; 67 List<MetadataBuilder> metadata;
65 68
66 /// The current declaration that is being built. When we start parsing a 69 /// The current declaration that is being built. When we start parsing a
67 /// declaration (class, method, and so on), we don't have enough information 70 /// declaration (class, method, and so on), we don't have enough information
68 /// to create a builder and this object records its members and types until, 71 /// to create a builder and this object records its members and types until,
69 /// for example, [addClass] is called. 72 /// for example, [addClass] is called.
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 AsyncMarker asyncModifier, ConstructorReferenceBuilder redirectionTarget, 194 AsyncMarker asyncModifier, ConstructorReferenceBuilder redirectionTarget,
192 int charOffset, String nativeMethodName); 195 int charOffset, String nativeMethodName);
193 196
194 FormalParameterBuilder addFormalParameter( 197 FormalParameterBuilder addFormalParameter(
195 List<MetadataBuilder> metadata, int modifiers, 198 List<MetadataBuilder> metadata, int modifiers,
196 T type, String name, bool hasThis, int charOffset); 199 T type, String name, bool hasThis, int charOffset);
197 200
198 TypeVariableBuilder addTypeVariable(String name, T bound, int charOffset); 201 TypeVariableBuilder addTypeVariable(String name, T bound, int charOffset);
199 202
200 Builder addBuilder(String name, Builder builder, int charOffset) { 203 Builder addBuilder(String name, Builder builder, int charOffset) {
201 if (name.indexOf(".") != -1) { 204 if (name.indexOf(".") != -1 && name.indexOf("&") == -1) {
202 addCompileTimeError(charOffset, "Only constructors and factories can have" 205 addCompileTimeError(charOffset, "Only constructors and factories can have"
203 " names containing a period ('.'): $name"); 206 " names containing a period ('.'): $name");
204 } 207 }
205 // TODO(ahe): Set the parent correctly here. Could then change the 208 // TODO(ahe): Set the parent correctly here. Could then change the
206 // implementation of MemberBuilder.isTopLevel to test explicitly for a 209 // implementation of MemberBuilder.isTopLevel to test explicitly for a
207 // LibraryBuilder. 210 // LibraryBuilder.
208 if (currentDeclaration == libraryDeclaration) { 211 if (currentDeclaration == libraryDeclaration) {
209 if (builder is MemberBuilder) { 212 if (builder is MemberBuilder) {
210 builder.parent = this; 213 builder.parent = this;
211 } else if (builder is TypeDeclarationBuilder) { 214 } else if (builder is TypeDeclarationBuilder) {
(...skipping 12 matching lines...) Expand all
224 if (builder is PrefixBuilder && existing is PrefixBuilder) { 227 if (builder is PrefixBuilder && existing is PrefixBuilder) {
225 assert(existing.next == null); 228 assert(existing.next == null);
226 builder.exports.forEach((String name, Builder builder) { 229 builder.exports.forEach((String name, Builder builder) {
227 Builder other = existing.exports.putIfAbsent(name, () => builder); 230 Builder other = existing.exports.putIfAbsent(name, () => builder);
228 if (other != builder) { 231 if (other != builder) {
229 existing.exports[name] = 232 existing.exports[name] =
230 other.combineAmbiguousImport(name, builder, this); 233 other.combineAmbiguousImport(name, builder, this);
231 } 234 }
232 }); 235 });
233 return existing; 236 return existing;
234 } else if (existing != null && (existing.next != null || 237 } else if (isDuplicatedDefinition(existing, builder)) {
235 ((!existing.isGetter || !builder.isSetter) &&
236 (!existing.isSetter || !builder.isGetter)))) {
237 addCompileTimeError(charOffset, "Duplicated definition of '$name'."); 238 addCompileTimeError(charOffset, "Duplicated definition of '$name'.");
238 } 239 }
239 return members[name] = builder; 240 return members[name] = builder;
240 } 241 }
241 242
243 bool isDuplicatedDefinition(Builder existing, Builder other) {
244 if (existing == null) return false;
245 Builder next = existing.next;
246 if (next == null) {
247 if (existing.isGetter && other.isSetter) return false;
248 if (existing.isSetter && other.isGetter) return false;
249 } else {
250 if (next is ClassBuilder && !next.isMixinApplication) return true;
251 }
252 if (existing is ClassBuilder && other is ClassBuilder) {
253 // We allow multiple mixin applications with the same name. An
254 // alternative is to share these mixin applications. This situation can
255 // happen if you have `class A extends Object with Mixin {}` and `class B
256 // extends Object with Mixin {}` in the same library.
257 return !existing.isMixinApplication || !other.isMixinApplication;
258 }
259 return true;
260 }
261
242 void buildBuilder(Builder builder); 262 void buildBuilder(Builder builder);
243 263
244 R build() { 264 R build() {
265 assert(implementationBuilders.isEmpty);
245 members.forEach((String name, Builder builder) { 266 members.forEach((String name, Builder builder) {
246 do { 267 do {
247 buildBuilder(builder); 268 buildBuilder(builder);
248 builder = builder.next; 269 builder = builder.next;
249 } while (builder != null); 270 } while (builder != null);
250 }); 271 });
272 for (List list in implementationBuilders) {
273 String name = list[0];
274 Builder builder = list[1];
275 int charOffset = list[2];
276 addBuilder(name, builder, charOffset);
277 buildBuilder(builder);
278 }
251 return null; 279 return null;
252 } 280 }
253 281
282 void addImplementationBuilder(String name, Builder builder, int charOffset) {
283 implementationBuilders.add([name, builder, charOffset]);
284 }
285
254 void validatePart() { 286 void validatePart() {
255 if (parts.isNotEmpty) { 287 if (parts.isNotEmpty) {
256 internalError("Part with parts: $uri"); 288 internalError("Part with parts: $uri");
257 } 289 }
258 if (exporters.isNotEmpty) { 290 if (exporters.isNotEmpty) {
259 internalError( 291 internalError(
260 "${exporters.first.exporter.uri} attempts to export the part $uri."); 292 "${exporters.first.exporter.uri} attempts to export the part $uri.");
261 } 293 }
262 } 294 }
263 295
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 } 469 }
438 470
439 /// Called to register [procedure] as a factory whose types are collected in 471 /// Called to register [procedure] as a factory whose types are collected in
440 /// [factoryDeclaration]. Later, once the class has been built, we can 472 /// [factoryDeclaration]. Later, once the class has been built, we can
441 /// synthesize type variables on the factory matching the class'. 473 /// synthesize type variables on the factory matching the class'.
442 void addFactoryDeclaration( 474 void addFactoryDeclaration(
443 ProcedureBuilder procedure, DeclarationBuilder<T> factoryDeclaration) { 475 ProcedureBuilder procedure, DeclarationBuilder<T> factoryDeclaration) {
444 factoryDeclarations[procedure] = factoryDeclaration; 476 factoryDeclarations[procedure] = factoryDeclaration;
445 } 477 }
446 } 478 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/source/source_class_builder.dart ('k') | pkg/front_end/test/fasta/mixin.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698