Chromium Code Reviews| 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 4da1f859e4b80b894a481c9af7bc7867f2a5433e..c1331d67274029c51c21a656abeec0c19ae65556 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 |
| @@ -25,6 +25,7 @@ import '../builder/scope.dart' show |
| import '../builder/builder.dart' show |
| Builder, |
| + ClassBuilder, |
| ConstructorReferenceBuilder, |
| FormalParameterBuilder, |
| LibraryBuilder, |
| @@ -57,6 +58,8 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R> |
| final Uri fileUri; |
| + final List<List> implementationBuilders = <List<List>>[]; |
| + |
| String name; |
| String partOf; |
| @@ -198,7 +201,7 @@ 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) { |
| + if (name.indexOf(".") != -1 && name.indexOf("&") == -1) { |
| addCompileTimeError(charOffset, "Only constructors and factories can have" |
| " names containing a period ('.'): $name"); |
| } |
| @@ -231,26 +234,51 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R> |
| } |
| }); |
| return existing; |
| - } else if (existing != null && (existing.next != null || |
| - ((!existing.isGetter || !builder.isSetter) && |
| - (!existing.isSetter || !builder.isGetter)))) { |
| + } else if (isDuplicatedDefinition(existing, builder)) { |
| addCompileTimeError(charOffset, "Duplicated definition of '$name'."); |
| } |
| return members[name] = builder; |
| } |
| + bool isDuplicatedDefinition(Builder existing, Builder other) { |
| + if (existing == null) return false; |
| + Builder next = existing.next; |
| + if (next == null) { |
| + if (existing.isGetter && other.isSetter) return false; |
| + if (existing.isSetter && other.isGetter) return false; |
| + } else { |
| + if (next is ClassBuilder && !next.isMixinApplication) return true; |
| + } |
| + if (existing is ClassBuilder && other is ClassBuilder) { |
|
karlklose
2017/02/15 09:09:30
Please add a comment about what invariance this ha
ahe
2017/02/15 09:36:51
Done.
|
| + return !existing.isMixinApplication || !other.isMixinApplication; |
| + } |
| + return true; |
| + } |
| + |
| void buildBuilder(Builder builder); |
| R build() { |
| + assert(implementationBuilders.isEmpty); |
| members.forEach((String name, Builder builder) { |
| do { |
| buildBuilder(builder); |
| builder = builder.next; |
| } while (builder != null); |
| }); |
| + for (List list in implementationBuilders) { |
| + String name = list[0]; |
| + Builder builder = list[1]; |
| + int charOffset = list[2]; |
| + addBuilder(name, builder, charOffset); |
| + buildBuilder(builder); |
| + } |
| return null; |
| } |
| + void addImplementationBuilder(String name, Builder builder, int charOffset) { |
| + implementationBuilders.add([name, builder, charOffset]); |
| + } |
| + |
| void validatePart() { |
| if (parts.isNotEmpty) { |
| internalError("Part with parts: $uri"); |