| Index: pkg/front_end/lib/src/fasta/source/source_library_builder.dart
|
| diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
|
| index 8ee14d6c82a8149c7a3471ebbe8787db2e6a2c85..c1f800081db8724dc9b36232f4a034a605ff3032 100644
|
| --- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
|
| +++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
|
| @@ -38,8 +38,7 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
| extends LibraryBuilder<T, R> {
|
| final SourceLoader loader;
|
|
|
| - final DeclarationBuilder<T> libraryDeclaration =
|
| - new DeclarationBuilder<T>(<String, Builder>{}, null);
|
| + final DeclarationBuilder<T> libraryDeclaration;
|
|
|
| final List<ConstructorReferenceBuilder> constructorReferences =
|
| <ConstructorReferenceBuilder>[];
|
| @@ -48,9 +47,7 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
|
|
| final List<Import> imports = <Import>[];
|
|
|
| - final Map<String, Builder> exports = <String, Builder>{};
|
| -
|
| - final Scope scope = new Scope.top();
|
| + final Scope importScope;
|
|
|
| final Uri fileUri;
|
|
|
| @@ -72,18 +69,20 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
|
|
| bool canAddImplementationBuilders = false;
|
|
|
| - SourceLibraryBuilder(this.loader, Uri fileUri)
|
| - : fileUri = fileUri,
|
| - super(fileUri) {
|
| - currentDeclaration = libraryDeclaration;
|
| - }
|
| + SourceLibraryBuilder(SourceLoader loader, Uri fileUri)
|
| + : this.fromScopes(loader, fileUri, new DeclarationBuilder<T>.library(),
|
| + new Scope.top());
|
| +
|
| + SourceLibraryBuilder.fromScopes(
|
| + this.loader, this.fileUri, this.libraryDeclaration, this.importScope)
|
| + : currentDeclaration = libraryDeclaration,
|
| + super(
|
| + fileUri, libraryDeclaration.toScope(importScope), new Scope.top());
|
|
|
| Uri get uri;
|
|
|
| bool get isPart => partOfName != null || partOfUri != null;
|
|
|
| - Map<String, Builder> get members => libraryDeclaration.members;
|
| -
|
| List<T> get types => libraryDeclaration.types;
|
|
|
| T addNamedType(String name, List<T> arguments, int charOffset);
|
| @@ -105,9 +104,8 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
| return ref;
|
| }
|
|
|
| - void beginNestedDeclaration(String name, {bool hasMembers}) {
|
| - currentDeclaration = new DeclarationBuilder(
|
| - <String, MemberBuilder>{}, name, currentDeclaration);
|
| + void beginNestedDeclaration(String name, {bool hasMembers: true}) {
|
| + currentDeclaration = currentDeclaration.createNested(name, hasMembers);
|
| }
|
|
|
| DeclarationBuilder<T> endNestedDeclaration() {
|
| @@ -234,12 +232,6 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
| TypeVariableBuilder addTypeVariable(String name, T bound, int charOffset);
|
|
|
| Builder addBuilder(String name, Builder builder, int charOffset) {
|
| - if (name.indexOf(".") != -1 && name.indexOf("&") == -1) {
|
| - addCompileTimeError(
|
| - charOffset,
|
| - "Only constructors and factories can have"
|
| - " names containing a period ('.'): $name");
|
| - }
|
| // TODO(ahe): Set the parent correctly here. Could then change the
|
| // implementation of MemberBuilder.isTopLevel to test explicitly for a
|
| // LibraryBuilder.
|
| @@ -256,19 +248,22 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
| } else {
|
| assert(currentDeclaration.parent == libraryDeclaration);
|
| }
|
| - Map<String, Builder> members = currentDeclaration.members;
|
| + bool isConstructor = builder is ProcedureBuilder &&
|
| + (builder.isConstructor || builder.isFactory);
|
| + Map<String, Builder> members = isConstructor
|
| + ? currentDeclaration.constructors
|
| + : (builder.isSetter
|
| + ? currentDeclaration.setters
|
| + : currentDeclaration.members);
|
| Builder existing = members[name];
|
| builder.next = existing;
|
| if (builder is PrefixBuilder && existing is PrefixBuilder) {
|
| assert(existing.next == null);
|
| - builder.exports.forEach((String name, Builder builder) {
|
| - Builder other = existing.exports.putIfAbsent(name, () => builder);
|
| - if (other != builder) {
|
| - existing.exports[name] =
|
| - buildAmbiguousBuilder(name, other, builder, charOffset);
|
| - }
|
| - });
|
| - return existing;
|
| + return existing
|
| + ..exports.merge(builder.exports,
|
| + (String name, Builder existing, Builder member) {
|
| + return buildAmbiguousBuilder(name, existing, member, charOffset);
|
| + });
|
| } else if (isDuplicatedDefinition(existing, builder)) {
|
| addCompileTimeError(charOffset, "Duplicated definition of '$name'.");
|
| }
|
| @@ -313,6 +308,17 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
| buildBuilder(builder);
|
| }
|
| canAddImplementationBuilders = false;
|
| +
|
| + scope.setters.forEach((String name, Builder setter) {
|
| + Builder member = scopeBuilder[name];
|
| + if (member == null || !member.isField || member.isFinal) return;
|
| + // TODO(ahe): charOffset is missing.
|
| + addCompileTimeError(
|
| + setter.charOffset, "Conflicts with member '${name}'.");
|
| + addCompileTimeError(
|
| + member.charOffset, "Conflicts with setter '${name}'.");
|
| + });
|
| +
|
| return null;
|
| }
|
|
|
| @@ -381,14 +387,12 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
| types.addAll(part.types);
|
| constructorReferences.addAll(part.constructorReferences);
|
| part.partOfLibrary = this;
|
| + part.scope.becomePartOf(scope);
|
| // TODO(ahe): Include metadata from part?
|
| }
|
|
|
| void buildInitialScopes() {
|
| forEach(addToExportScope);
|
| - forEach((String name, Builder member) {
|
| - addToScope(name, member, member.charOffset, false);
|
| - });
|
| }
|
|
|
| void addImportsToScope() {
|
| @@ -408,15 +412,16 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
|
|
| @override
|
| void addToScope(String name, Builder member, int charOffset, bool isImport) {
|
| - Builder existing = scope.lookup(name, member.charOffset, fileUri);
|
| + Map<String, Builder> map =
|
| + member.isSetter ? importScope.setters : importScope.local;
|
| + Builder existing = map[name];
|
| if (existing != null) {
|
| if (existing != member) {
|
| - scope.local[name] = buildAmbiguousBuilder(
|
| - name, existing, member, charOffset,
|
| + map[name] = buildAmbiguousBuilder(name, existing, member, charOffset,
|
| isImport: isImport);
|
| }
|
| } else {
|
| - scope.local[name] = member;
|
| + map[name] = member;
|
| }
|
| }
|
|
|
| @@ -424,15 +429,17 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
| bool addToExportScope(String name, Builder member) {
|
| if (name.startsWith("_")) return false;
|
| if (member is PrefixBuilder) return false;
|
| - Builder existing = exports[name];
|
| + Map<String, Builder> map =
|
| + member.isSetter ? exports.setters : exports.local;
|
| + Builder existing = map[name];
|
| if (existing == member) return false;
|
| if (existing != null) {
|
| Builder result =
|
| buildAmbiguousBuilder(name, existing, member, -1, isExport: true);
|
| - exports[name] = result;
|
| + map[name] = result;
|
| return result != existing;
|
| } else {
|
| - exports[name] = member;
|
| + map[name] = member;
|
| }
|
| return true;
|
| }
|
| @@ -471,25 +478,30 @@ class DeclarationBuilder<T extends TypeBuilder> {
|
|
|
| final Map<String, Builder> members;
|
|
|
| + final Map<String, Builder> constructors;
|
| +
|
| + final Map<String, Builder> setters;
|
| +
|
| final List<T> types = <T>[];
|
|
|
| final String name;
|
|
|
| - final Map<ProcedureBuilder, DeclarationBuilder<T>> factoryDeclarations =
|
| - <ProcedureBuilder, DeclarationBuilder<T>>{};
|
| + final Map<ProcedureBuilder, DeclarationBuilder<T>> factoryDeclarations;
|
|
|
| - DeclarationBuilder(this.members, this.name, [this.parent]);
|
| + DeclarationBuilder(this.members, this.setters, this.constructors,
|
| + this.factoryDeclarations, this.name, this.parent);
|
|
|
| - void addMember(String name, MemberBuilder builder) {
|
| - if (members == null) {
|
| - parent.addMember(name, builder);
|
| - } else {
|
| - members[name] = builder;
|
| - }
|
| - }
|
| + DeclarationBuilder.library()
|
| + : this(<String, Builder>{}, <String, Builder>{}, null, null, null, null);
|
|
|
| - MemberBuilder lookupMember(String name) {
|
| - return members == null ? parent.lookupMember(name) : members[name];
|
| + DeclarationBuilder createNested(String name, bool hasMembers) {
|
| + return new DeclarationBuilder<T>(
|
| + hasMembers ? <String, MemberBuilder>{} : null,
|
| + hasMembers ? <String, MemberBuilder>{} : null,
|
| + hasMembers ? <String, MemberBuilder>{} : null,
|
| + <ProcedureBuilder, DeclarationBuilder<T>>{},
|
| + name,
|
| + this);
|
| }
|
|
|
| void addType(T type) {
|
| @@ -546,4 +558,8 @@ class DeclarationBuilder<T extends TypeBuilder> {
|
| ProcedureBuilder procedure, DeclarationBuilder<T> factoryDeclaration) {
|
| factoryDeclarations[procedure] = factoryDeclaration;
|
| }
|
| +
|
| + Scope toScope(Scope parent) {
|
| + return new Scope(members, setters, parent, isModifiable: false);
|
| + }
|
| }
|
|
|