| 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 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |