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