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

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

Issue 2788153002: Create separate scopes for constructors, setters, and other members. (Closed)
Patch Set: One more flaky standalone/io test. Created 3 years, 8 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
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_class_builder; 5 library fasta.source_class_builder;
6 6
7 import 'package:kernel/ast.dart' 7 import 'package:kernel/ast.dart'
8 show Class, Constructor, Supertype, TreeNode, setParents; 8 show Class, Constructor, Supertype, TreeNode, setParents;
9 9
10 import '../errors.dart' show internalError; 10 import '../errors.dart' show internalError;
11 11
12 import '../kernel/kernel_builder.dart' 12 import '../kernel/kernel_builder.dart'
13 show 13 show
14 Builder, 14 Builder,
15 ConstructorReferenceBuilder, 15 ConstructorReferenceBuilder,
16 KernelClassBuilder, 16 KernelClassBuilder,
17 KernelFieldBuilder, 17 KernelFieldBuilder,
18 KernelFunctionBuilder, 18 KernelFunctionBuilder,
19 KernelLibraryBuilder, 19 KernelLibraryBuilder,
20 KernelTypeBuilder, 20 KernelTypeBuilder,
21 KernelTypeVariableBuilder, 21 KernelTypeVariableBuilder,
22 LibraryBuilder, 22 LibraryBuilder,
23 MetadataBuilder, 23 MetadataBuilder,
24 ProcedureBuilder, 24 Scope,
25 TypeVariableBuilder, 25 TypeVariableBuilder,
26 compareProcedures; 26 compareProcedures;
27 27
28 import '../dill/dill_member_builder.dart' show DillMemberBuilder; 28 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
29 29
30 import '../util/relativize.dart' show relativizeUri; 30 import '../util/relativize.dart' show relativizeUri;
31 31
32 Class initializeClass( 32 Class initializeClass(
33 Class cls, String name, LibraryBuilder parent, int charOffset) { 33 Class cls, String name, LibraryBuilder parent, int charOffset) {
34 cls ??= new Class(name: name); 34 cls ??= new Class(name: name);
35 cls.fileUri ??= relativizeUri(parent.fileUri); 35 cls.fileUri ??= relativizeUri(parent.fileUri);
36 if (cls.fileOffset == TreeNode.noOffset) { 36 if (cls.fileOffset == TreeNode.noOffset) {
37 cls.fileOffset = charOffset; 37 cls.fileOffset = charOffset;
38 } 38 }
39 return cls; 39 return cls;
40 } 40 }
41 41
42 class SourceClassBuilder extends KernelClassBuilder { 42 class SourceClassBuilder extends KernelClassBuilder {
43 final Class cls; 43 final Class cls;
44 44
45 @override
46 final Map<String, Builder> constructors;
47
48 final Map<String, Builder> membersInScope;
49
50 final List<ConstructorReferenceBuilder> constructorReferences; 45 final List<ConstructorReferenceBuilder> constructorReferences;
51 46
52 final KernelTypeBuilder mixedInType; 47 final KernelTypeBuilder mixedInType;
53 48
54 SourceClassBuilder( 49 SourceClassBuilder(
55 List<MetadataBuilder> metadata, 50 List<MetadataBuilder> metadata,
56 int modifiers, 51 int modifiers,
57 String name, 52 String name,
58 List<TypeVariableBuilder> typeVariables, 53 List<TypeVariableBuilder> typeVariables,
59 KernelTypeBuilder supertype, 54 KernelTypeBuilder supertype,
60 List<KernelTypeBuilder> interfaces, 55 List<KernelTypeBuilder> interfaces,
61 Map<String, Builder> members, 56 Scope scope,
57 Scope constructors,
62 LibraryBuilder parent, 58 LibraryBuilder parent,
63 this.constructorReferences, 59 this.constructorReferences,
64 int charOffset, 60 int charOffset,
65 [Class cls, 61 [Class cls,
66 this.mixedInType]) 62 this.mixedInType])
67 : cls = initializeClass(cls, name, parent, charOffset), 63 : cls = initializeClass(cls, name, parent, charOffset),
68 membersInScope = computeMembersInScope(members),
69 constructors = computeConstructors(members),
70 super(metadata, modifiers, name, typeVariables, supertype, interfaces, 64 super(metadata, modifiers, name, typeVariables, supertype, interfaces,
71 members, parent, charOffset); 65 scope, constructors, parent, charOffset);
72 66
73 int resolveTypes(LibraryBuilder library) { 67 int resolveTypes(LibraryBuilder library) {
74 int count = 0; 68 int count = 0;
75 if (typeVariables != null) { 69 if (typeVariables != null) {
76 for (KernelTypeVariableBuilder t in typeVariables) { 70 for (KernelTypeVariableBuilder t in typeVariables) {
77 cls.typeParameters.add(t.parameter); 71 cls.typeParameters.add(t.parameter);
78 } 72 }
79 setParents(cls.typeParameters, cls); 73 setParents(cls.typeParameters, cls);
80 count += cls.typeParameters.length; 74 count += cls.typeParameters.length;
81 } 75 }
82 return count + super.resolveTypes(library); 76 return count + super.resolveTypes(library);
83 } 77 }
84 78
85 Class build(KernelLibraryBuilder library) { 79 Class build(KernelLibraryBuilder library) {
86 void buildBuilder(Builder builder) { 80 void buildBuilders(String name, Builder builder) {
87 if (builder is KernelFieldBuilder) { 81 do {
88 // TODO(ahe): It would be nice to have a common interface for the build 82 if (builder is KernelFieldBuilder) {
89 // method to avoid duplicating these two cases. 83 // TODO(ahe): It would be nice to have a common interface for the
90 cls.addMember(builder.build(library)); 84 // build method to avoid duplicating these two cases.
91 } else if (builder is KernelFunctionBuilder) { 85 cls.addMember(builder.build(library));
92 cls.addMember(builder.build(library)); 86 } else if (builder is KernelFunctionBuilder) {
93 } else { 87 cls.addMember(builder.build(library));
94 internalError("Unhandled builder: ${builder.runtimeType}"); 88 } else {
95 } 89 internalError("Unhandled builder: ${builder.runtimeType}");
90 }
91 builder = builder.next;
92 } while (builder != null);
96 } 93 }
97 94
98 members.forEach((String name, Builder builder) { 95 scope.forEach(buildBuilders);
99 do { 96 constructors.forEach(buildBuilders);
100 buildBuilder(builder);
101 builder = builder.next;
102 } while (builder != null);
103 });
104 cls.supertype = supertype?.buildSupertype(library); 97 cls.supertype = supertype?.buildSupertype(library);
105 cls.mixedInType = mixedInType?.buildSupertype(library); 98 cls.mixedInType = mixedInType?.buildSupertype(library);
106 // TODO(ahe): If `cls.supertype` is null, and this isn't Object, report a 99 // TODO(ahe): If `cls.supertype` is null, and this isn't Object, report a
107 // compile-time error. 100 // compile-time error.
108 cls.isAbstract = isAbstract; 101 cls.isAbstract = isAbstract;
109 if (interfaces != null) { 102 if (interfaces != null) {
110 for (KernelTypeBuilder interface in interfaces) { 103 for (KernelTypeBuilder interface in interfaces) {
111 Supertype supertype = interface.buildSupertype(library); 104 Supertype supertype = interface.buildSupertype(library);
112 if (supertype != null) { 105 if (supertype != null) {
113 // TODO(ahe): Report an error if supertype is null. 106 // TODO(ahe): Report an error if supertype is null.
114 cls.implementedTypes.add(supertype); 107 cls.implementedTypes.add(supertype);
115 } 108 }
116 } 109 }
117 } 110 }
118 111
112 constructors.forEach((String name, Builder constructor) {
113 Builder member = scopeBuilder[name];
114 if (member == null) return;
115 // TODO(ahe): charOffset is missing.
116 addCompileTimeError(
117 constructor.charOffset, "Conflicts with member '${name}'.");
118 if (constructor.isFactory) {
119 addCompileTimeError(member.charOffset,
120 "Conflicts with factory '${this.name}.${name}'.");
121 } else {
122 addCompileTimeError(member.charOffset,
123 "Conflicts with constructor '${this.name}.${name}'.");
124 }
125 });
126
127 scope.setters.forEach((String name, Builder setter) {
128 Builder member = scopeBuilder[name];
129 if (member == null || !member.isField || member.isFinal) return;
130 // TODO(ahe): charOffset is missing.
131 var report = member.isInstanceMember != setter.isInstanceMember
132 ? addWarning
133 : addCompileTimeError;
134 report(setter.charOffset, "Conflicts with member '${name}'.");
135 report(member.charOffset, "Conflicts with setter '${name}'.");
136 });
137
119 cls.procedures.sort(compareProcedures); 138 cls.procedures.sort(compareProcedures);
120 return cls; 139 return cls;
121 } 140 }
122 141
123 void addSyntheticConstructor(Constructor constructor) { 142 void addSyntheticConstructor(Constructor constructor) {
124 String name = constructor.name.name; 143 String name = constructor.name.name;
125 cls.constructors.add(constructor); 144 cls.constructors.add(constructor);
126 constructor.parent = cls; 145 constructor.parent = cls;
127 DillMemberBuilder memberBuilder = new DillMemberBuilder(constructor, this); 146 DillMemberBuilder memberBuilder = new DillMemberBuilder(constructor, this);
128 memberBuilder.next = constructors[name]; 147 memberBuilder.next = constructorScopeBuilder[name];
129 constructors[name] = memberBuilder; 148 constructorScopeBuilder.addMember(name, memberBuilder);
130 } 149 }
131 } 150 }
132
133 Map<String, Builder> computeMembersInScope(Map<String, Builder> members) {
134 Map<String, Builder> membersInScope = <String, Builder>{};
135 members.forEach((String name, Builder builder) {
136 if (builder is ProcedureBuilder) {
137 if (builder.isConstructor || builder.isFactory) return;
138 }
139 membersInScope[name] = builder;
140 });
141 return membersInScope;
142 }
143
144 Map<String, Builder> computeConstructors(Map<String, Builder> members) {
145 Map<String, Builder> constructors = <String, Builder>{};
146 members.forEach((String name, Builder builder) {
147 if (builder is ProcedureBuilder &&
148 (builder.isConstructor || builder.isFactory)) {
149 constructors[name] = builder;
150 }
151 });
152 return constructors;
153 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/source/diet_listener.dart ('k') | pkg/front_end/lib/src/fasta/source/source_library_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698