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

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

Issue 2672993003: Handle type variables. (Closed)
Patch Set: Add 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
« no previous file with comments | « pkg/front_end/lib/src/fasta/source/outline_builder.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
(...skipping 29 matching lines...) Expand all
40 ProcedureBuilder, 40 ProcedureBuilder,
41 TypeBuilder, 41 TypeBuilder,
42 TypeDeclarationBuilder, 42 TypeDeclarationBuilder,
43 TypeVariableBuilder, 43 TypeVariableBuilder,
44 Unhandled; 44 Unhandled;
45 45
46 abstract class SourceLibraryBuilder<T extends TypeBuilder, R> 46 abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
47 extends LibraryBuilder<T, R> { 47 extends LibraryBuilder<T, R> {
48 final SourceLoader loader; 48 final SourceLoader loader;
49 49
50 final Map<String, Builder> members = <String, Builder>{}; 50 final BuilderScope<T> libraryScope = new BuilderScope<T>(<String, Builder>{});
51
52 final List<T> types = <T>[];
53 51
54 final List<ConstructorReferenceBuilder> constructorReferences = 52 final List<ConstructorReferenceBuilder> constructorReferences =
55 <ConstructorReferenceBuilder>[]; 53 <ConstructorReferenceBuilder>[];
56 54
57 final List<LibraryBuilder> parts = <LibraryBuilder>[]; 55 final List<LibraryBuilder> parts = <LibraryBuilder>[];
58 56
59 final List<Import> imports = <Import>[]; 57 final List<Import> imports = <Import>[];
60 58
61 final Map<String, Builder> exports = <String, Builder>{}; 59 final Map<String, Builder> exports = <String, Builder>{};
62 60
63 final Scope scope = new Scope(<String, Builder>{}, null, isModifiable: false); 61 final Scope scope = new Scope(<String, Builder>{}, null, isModifiable: false);
64 62
65 final Uri fileUri; 63 final Uri fileUri;
66 64
67 String name; 65 String name;
68 66
69 String partOf; 67 String partOf;
70 68
71 List<MetadataBuilder> metadata; 69 List<MetadataBuilder> metadata;
72 70
73 Map<String, MemberBuilder> classMembers; 71 /// The current declaration that is being built. When we start parsing a
74 72 /// declaration (class, method, and so on), we don't have enough information
75 // TODO(ahe): Rename this. It's not just for classes. 73 /// to create a builder and this object records its members and types until,
76 List<T> classTypes; 74 /// for example, [addClass] is called.
75 BuilderScope<T> innerScope;
77 76
78 SourceLibraryBuilder(this.loader, this.fileUri); 77 SourceLibraryBuilder(this.loader, this.fileUri);
79 78
80 Uri get uri; 79 Uri get uri;
81 80
82 bool get isPart => partOf != null; 81 bool get isPart => partOf != null;
83 82
83 Map<String, Builder> get members => libraryScope.members;
84
85 List<T> get types => libraryScope.types;
86
87 BuilderScope<T> get builderScope => innerScope ?? libraryScope;
88
89 /// When parsing a class, this returns a map of its members (that have been
90 /// parsed so far).
91 Map<String, MemberBuilder> get classMembers {
92 assert(innerScope == builderScope);
93 assert(innerScope.parent == libraryScope);
94 return builderScope.members;
95 }
96
97 List<T> get declarationTypes {
98 assert(innerScope == builderScope);
99 assert(innerScope.parent == libraryScope);
100 return builderScope.types;
101 }
102
84 T addInterfaceType(String name, List<T> arguments); 103 T addInterfaceType(String name, List<T> arguments);
85 104
86 T addMixinApplication(T supertype, List<T> mixins); 105 T addMixinApplication(T supertype, List<T> mixins);
87 106
88 T addType(T type) { 107 T addType(T type) {
89 List<T> types = classTypes ?? this.types; 108 builderScope.addType(type);
90 types.add(type);
91 return type; 109 return type;
92 } 110 }
93 111
94 T addVoidType(); 112 T addVoidType();
95 113
96 ConstructorReferenceBuilder addConstructorReference( 114 ConstructorReferenceBuilder addConstructorReference(
97 String name, List<T> typeArguments, String suffix) { 115 String name, List<T> typeArguments, String suffix) {
98 ConstructorReferenceBuilder ref = 116 ConstructorReferenceBuilder ref =
99 new ConstructorReferenceBuilder(name, typeArguments, suffix); 117 new ConstructorReferenceBuilder(name, typeArguments, suffix);
100 constructorReferences.add(ref); 118 constructorReferences.add(ref);
101 return ref; 119 return ref;
102 } 120 }
103 121
104 void beginNestedScope() { 122 void beginNestedScope({bool hasMembers}) {
105 classMembers = <String, MemberBuilder>{}; 123 innerScope = new BuilderScope(<String, MemberBuilder>{}, builderScope);
106 classTypes = <T>[];
107 } 124 }
108 125
109 void endNestedScope() { 126 BuilderScope<T> endNestedScope() {
110 classMembers = null; 127 BuilderScope<T> previous = innerScope;
111 classTypes = null; 128 innerScope = innerScope.parent;
129 return previous;
112 } 130 }
113 131
114 Uri resolve(String path) => uri.resolve(path); 132 Uri resolve(String path) => uri.resolve(path);
115 133
116 void addExport(List<MetadataBuilder> metadata, String uri, 134 void addExport(List<MetadataBuilder> metadata, String uri,
117 Unhandled conditionalUris, List<Combinator> combinators) { 135 Unhandled conditionalUris, List<Combinator> combinators) {
118 loader.read(resolve(uri)).addExporter(this, combinators); 136 loader.read(resolve(uri)).addExporter(this, combinators);
119 } 137 }
120 138
121 void addImport(List<MetadataBuilder> metadata, String uri, 139 void addImport(List<MetadataBuilder> metadata, String uri,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 FormalParameterBuilder addFormalParameter( 199 FormalParameterBuilder addFormalParameter(
182 List<MetadataBuilder> metadata, int modifiers, 200 List<MetadataBuilder> metadata, int modifiers,
183 T type, String name, bool hasThis); 201 T type, String name, bool hasThis);
184 202
185 TypeVariableBuilder addTypeVariable(String name, T bound); 203 TypeVariableBuilder addTypeVariable(String name, T bound);
186 204
187 Builder addBuilder(String name, Builder builder) { 205 Builder addBuilder(String name, Builder builder) {
188 // TODO(ahe): Set the parent correctly here. Could then change the 206 // TODO(ahe): Set the parent correctly here. Could then change the
189 // implementation of MemberBuilder.isTopLevel to test explicitly for a 207 // implementation of MemberBuilder.isTopLevel to test explicitly for a
190 // LibraryBuilder. 208 // LibraryBuilder.
191 if (classMembers == null) { 209 if (builderScope == libraryScope) {
192 if (builder is MemberBuilder) { 210 if (builder is MemberBuilder) {
193 builder.parent = this; 211 builder.parent = this;
194 } else if (builder is TypeDeclarationBuilder) { 212 } else if (builder is TypeDeclarationBuilder) {
195 builder.parent = this; 213 builder.parent = this;
196 } else if (builder is PrefixBuilder) { 214 } else if (builder is PrefixBuilder) {
197 assert(builder.parent == this); 215 assert(builder.parent == this);
198 } else { 216 } else {
199 return internalError("Unhandled: ${builder.runtimeType}"); 217 return internalError("Unhandled: ${builder.runtimeType}");
200 } 218 }
219 } else {
220 assert(builderScope.parent == libraryScope);
201 } 221 }
202 Map<String, Builder> members = classMembers ?? this.members; 222 Map<String, Builder> members = builderScope.members;
203 Builder existing = members[name]; 223 Builder existing = members[name];
204 builder.next = existing; 224 builder.next = existing;
205 if (builder is PrefixBuilder && existing is PrefixBuilder) { 225 if (builder is PrefixBuilder && existing is PrefixBuilder) {
206 assert(existing.next == null); 226 assert(existing.next == null);
207 builder.exports.forEach((String name, Builder builder) { 227 builder.exports.forEach((String name, Builder builder) {
208 Builder other = existing.exports.putIfAbsent(name, () => builder); 228 Builder other = existing.exports.putIfAbsent(name, () => builder);
209 if (other != builder) { 229 if (other != builder) {
210 existing.exports[name] = 230 existing.exports[name] =
211 other.combineAmbiguousImport(name, builder, this); 231 other.combineAmbiguousImport(name, builder, this);
212 } 232 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 } 353 }
334 354
335 int resolveConstructors(_) { 355 int resolveConstructors(_) {
336 int count = 0; 356 int count = 0;
337 members.forEach((String name, Builder member) { 357 members.forEach((String name, Builder member) {
338 count += member.resolveConstructors(this); 358 count += member.resolveConstructors(this);
339 }); 359 });
340 return count; 360 return count;
341 } 361 }
342 } 362 }
363
364 /// Unlike [Scope], this scope is used during construction of builders to
365 /// ensure types and members are added to and resolved in the correct location.
366 class BuilderScope<T extends TypeBuilder> {
367 final BuilderScope<T> parent;
368
369 final Map<String, Builder> members;
370
371 final List<T> types = <T>[];
372
373 BuilderScope(this.members, [this.parent]);
374
375 void addMember(String name, MemberBuilder builder) {
376 if (members == null) {
377 parent.addMember(name, builder);
378 } else {
379 members[name] = builder;
380 }
381 }
382
383 MemberBuilder lookupMember(String name) {
384 return members == null ? parent.lookupMember(name) : members[name];
385 }
386
387 void addType(T type) {
388 types.add(type);
389 }
390
391 /// Resolves type variables in [types] and propagate other types to [parent].
392 void resolveTypes(List<TypeVariableBuilder> typeVariables) {
393 // TODO(ahe): The input to this method, [typeVariables], shouldn't be just
394 // type variables. It should be everything that's in scope, for example,
395 // members (of a class) or formal parameters (of a method).
396 if (typeVariables == null) {
397 // If there are no type variables in the scope, propagate our types to be
398 // resolved in the parent scope.
399 parent.types.addAll(types);
400 } else {
401 Map<String, TypeVariableBuilder> map = <String, TypeVariableBuilder>{};
402 for (TypeVariableBuilder builder in typeVariables) {
403 map[builder.name] = builder;
404 }
405 for (T type in types) {
406 String name = type.name;
407 TypeVariableBuilder builder;
408 if (name != null) {
409 builder = map[name];
410 }
411 if (builder == null) {
412 // Since name didn't resolve in this scope, propagate it to the
413 // parent scope.
414 parent.addType(type);
415 } else {
416 type.bind(builder);
417 }
418 }
419 }
420 types.clear();
421 }
422 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/source/outline_builder.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698