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

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart

Issue 2788153002: Create separate scopes for constructors, setters, and other members. (Closed)
Patch Set: Update subpackage dependencies. 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.kernel_library_builder; 5 library fasta.kernel_library_builder;
6 6
7 import 'package:kernel/ast.dart'; 7 import 'package:kernel/ast.dart';
8 8
9 import 'package:kernel/clone.dart' show CloneVisitor; 9 import 'package:kernel/clone.dart' show CloneVisitor;
10 10
(...skipping 28 matching lines...) Expand all
39 KernelFunctionTypeBuilder, 39 KernelFunctionTypeBuilder,
40 KernelInvalidTypeBuilder, 40 KernelInvalidTypeBuilder,
41 KernelMixinApplicationBuilder, 41 KernelMixinApplicationBuilder,
42 KernelNamedMixinApplicationBuilder, 42 KernelNamedMixinApplicationBuilder,
43 KernelNamedTypeBuilder, 43 KernelNamedTypeBuilder,
44 KernelProcedureBuilder, 44 KernelProcedureBuilder,
45 KernelTypeBuilder, 45 KernelTypeBuilder,
46 KernelTypeVariableBuilder, 46 KernelTypeVariableBuilder,
47 MemberBuilder, 47 MemberBuilder,
48 MetadataBuilder, 48 MetadataBuilder,
49 MixedAccessor,
50 NamedMixinApplicationBuilder, 49 NamedMixinApplicationBuilder,
51 PrefixBuilder, 50 PrefixBuilder,
52 ProcedureBuilder, 51 ProcedureBuilder,
52 Scope,
53 TypeBuilder, 53 TypeBuilder,
54 TypeVariableBuilder, 54 TypeVariableBuilder,
55 compareProcedures; 55 compareProcedures;
56 56
57 class KernelLibraryBuilder 57 class KernelLibraryBuilder
58 extends SourceLibraryBuilder<KernelTypeBuilder, Library> { 58 extends SourceLibraryBuilder<KernelTypeBuilder, Library> {
59 final Library library; 59 final Library library;
60 60
61 final Map<String, SourceClassBuilder> mixinApplicationClasses = 61 final Map<String, SourceClassBuilder> mixinApplicationClasses =
62 <String, SourceClassBuilder>{}; 62 <String, SourceClassBuilder>{};
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 void addClass( 96 void addClass(
97 List<MetadataBuilder> metadata, 97 List<MetadataBuilder> metadata,
98 int modifiers, 98 int modifiers,
99 String className, 99 String className,
100 List<TypeVariableBuilder> typeVariables, 100 List<TypeVariableBuilder> typeVariables,
101 KernelTypeBuilder supertype, 101 KernelTypeBuilder supertype,
102 List<KernelTypeBuilder> interfaces, 102 List<KernelTypeBuilder> interfaces,
103 int charOffset) { 103 int charOffset) {
104 assert(currentDeclaration.parent == libraryDeclaration); 104 assert(currentDeclaration.parent == libraryDeclaration);
105 Map<String, MemberBuilder> members = currentDeclaration.members; 105 Map<String, MemberBuilder> members = currentDeclaration.members;
106 Map<String, MemberBuilder> constructors = currentDeclaration.constructors;
107 Map<String, MemberBuilder> setters = currentDeclaration.setters;
108
109 Scope classScope = new Scope(
110 members, setters, scope.withTypeVariables(typeVariables),
111 isModifiable: false);
112
113 // When looking up a constructor, we don't consider type variables or the
114 // library scope.
115 Scope constructorScope =
116 new Scope(constructors, null, null, isModifiable: false);
106 ClassBuilder cls = new SourceClassBuilder( 117 ClassBuilder cls = new SourceClassBuilder(
107 metadata, 118 metadata,
108 modifiers, 119 modifiers,
109 className, 120 className,
110 typeVariables, 121 typeVariables,
111 supertype, 122 supertype,
112 interfaces, 123 interfaces,
113 members, 124 classScope,
125 constructorScope,
114 this, 126 this,
115 new List<ConstructorReferenceBuilder>.from(constructorReferences), 127 new List<ConstructorReferenceBuilder>.from(constructorReferences),
116 charOffset); 128 charOffset);
117 constructorReferences.clear(); 129 constructorReferences.clear();
118 members.forEach((String name, MemberBuilder builder) { 130 void setParent(String name, MemberBuilder member) {
119 while (builder != null) { 131 while (member != null) {
120 builder.parent = cls; 132 member.parent = cls;
121 builder = builder.next; 133 member = member.next;
122 } 134 }
123 }); 135 }
136
137 members.forEach(setParent);
138 constructors.forEach(setParent);
139 setters.forEach(setParent);
124 // Nested declaration began in `OutlineBuilder.beginClassDeclaration`. 140 // Nested declaration began in `OutlineBuilder.beginClassDeclaration`.
125 endNestedDeclaration().resolveTypes(typeVariables, this); 141 endNestedDeclaration().resolveTypes(typeVariables, this);
126 addBuilder(className, cls, charOffset); 142 addBuilder(className, cls, charOffset);
127 } 143 }
128 144
129 void addNamedMixinApplication( 145 void addNamedMixinApplication(
130 List<MetadataBuilder> metadata, 146 List<MetadataBuilder> metadata,
131 String name, 147 String name,
132 List<TypeVariableBuilder> typeVariables, 148 List<TypeVariableBuilder> typeVariables,
133 int modifiers, 149 int modifiers,
(...skipping 10 matching lines...) Expand all
144 160
145 void addField(List<MetadataBuilder> metadata, int modifiers, 161 void addField(List<MetadataBuilder> metadata, int modifiers,
146 KernelTypeBuilder type, String name, int charOffset) { 162 KernelTypeBuilder type, String name, int charOffset) {
147 addBuilder( 163 addBuilder(
148 name, 164 name,
149 new KernelFieldBuilder( 165 new KernelFieldBuilder(
150 metadata, type, name, modifiers, this, charOffset), 166 metadata, type, name, modifiers, this, charOffset),
151 charOffset); 167 charOffset);
152 } 168 }
153 169
154 String computeConstructorName(String name) { 170 String computeAndValidateConstructorName(String name, int charOffset) {
155 assert(isConstructorName(name, currentDeclaration.name)); 171 String className = currentDeclaration.name;
172 bool startsWithClassName = name.startsWith(className);
173 if (startsWithClassName && name.length == className.length) {
174 // Unnamed constructor or factory.
175 return "";
176 }
156 int index = name.indexOf("."); 177 int index = name.indexOf(".");
157 return index == -1 ? "" : name.substring(index + 1); 178 if (startsWithClassName && index == className.length) {
179 // Named constructor or factory.
180 return name.substring(index + 1);
181 }
182 if (index == -1) {
183 // A legal name.
karlklose 2017/04/03 08:05:37 How about 'A legal name for a method, but not for
ahe 2017/04/04 09:54:51 Done.
184 return null;
185 }
186 String suffix = name.substring(index + 1);
187 addCompileTimeError(
188 charOffset,
189 "'$name' isn't a legal method name.\n"
190 "Did you mean '$className.$suffix'?");
191 return suffix;
158 } 192 }
159 193
160 void addProcedure( 194 void addProcedure(
161 List<MetadataBuilder> metadata, 195 List<MetadataBuilder> metadata,
162 int modifiers, 196 int modifiers,
163 KernelTypeBuilder returnType, 197 KernelTypeBuilder returnType,
164 String name, 198 String name,
165 List<TypeVariableBuilder> typeVariables, 199 List<TypeVariableBuilder> typeVariables,
166 List<FormalParameterBuilder> formals, 200 List<FormalParameterBuilder> formals,
167 AsyncMarker asyncModifier, 201 AsyncMarker asyncModifier,
168 ProcedureKind kind, 202 ProcedureKind kind,
169 int charOffset, 203 int charOffset,
170 int charOpenParenOffset, 204 int charOpenParenOffset,
171 int charEndOffset, 205 int charEndOffset,
172 String nativeMethodName, 206 String nativeMethodName,
173 {bool isTopLevel}) { 207 {bool isTopLevel}) {
174 // Nested declaration began in `OutlineBuilder.beginMethod` or 208 // Nested declaration began in `OutlineBuilder.beginMethod` or
175 // `OutlineBuilder.beginTopLevelMethod`. 209 // `OutlineBuilder.beginTopLevelMethod`.
176 endNestedDeclaration().resolveTypes(typeVariables, this); 210 endNestedDeclaration().resolveTypes(typeVariables, this);
177 ProcedureBuilder procedure; 211 ProcedureBuilder procedure;
178 if (!isTopLevel && isConstructorName(name, currentDeclaration.name)) { 212 String constructorName =
179 name = computeConstructorName(name); 213 isTopLevel ? null : computeAndValidateConstructorName(name, charOffset);
214 if (constructorName != null) {
215 name = constructorName;
180 procedure = new KernelConstructorBuilder( 216 procedure = new KernelConstructorBuilder(
181 metadata, 217 metadata,
182 modifiers & ~abstractMask, 218 modifiers & ~abstractMask,
183 returnType, 219 returnType,
184 name, 220 name,
185 typeVariables, 221 typeVariables,
186 formals, 222 formals,
187 this, 223 this,
188 charOffset, 224 charOffset,
189 charOpenParenOffset, 225 charOpenParenOffset,
(...skipping 17 matching lines...) Expand all
207 } 243 }
208 addBuilder(name, procedure, charOffset); 244 addBuilder(name, procedure, charOffset);
209 if (nativeMethodName != null) { 245 if (nativeMethodName != null) {
210 addNativeMethod(procedure); 246 addNativeMethod(procedure);
211 } 247 }
212 } 248 }
213 249
214 void addFactoryMethod( 250 void addFactoryMethod(
215 List<MetadataBuilder> metadata, 251 List<MetadataBuilder> metadata,
216 int modifiers, 252 int modifiers,
217 ConstructorReferenceBuilder constructorName, 253 ConstructorReferenceBuilder constructorNameReference,
218 List<FormalParameterBuilder> formals, 254 List<FormalParameterBuilder> formals,
219 AsyncMarker asyncModifier, 255 AsyncMarker asyncModifier,
220 ConstructorReferenceBuilder redirectionTarget, 256 ConstructorReferenceBuilder redirectionTarget,
221 int charOffset, 257 int charOffset,
222 int charOpenParenOffset, 258 int charOpenParenOffset,
223 int charEndOffset, 259 int charEndOffset,
224 String nativeMethodName) { 260 String nativeMethodName) {
225 // Nested declaration began in `OutlineBuilder.beginFactoryMethod`. 261 // Nested declaration began in `OutlineBuilder.beginFactoryMethod`.
226 DeclarationBuilder<KernelTypeBuilder> factoryDeclaration = 262 DeclarationBuilder<KernelTypeBuilder> factoryDeclaration =
227 endNestedDeclaration(); 263 endNestedDeclaration();
228 String name = constructorName.name; 264 String name = constructorNameReference.name;
229 if (isConstructorName(name, currentDeclaration.name)) { 265 String constructorName =
230 name = computeConstructorName(name); 266 computeAndValidateConstructorName(name, charOffset);
267 if (constructorName != null) {
268 name = constructorName;
231 } 269 }
232 assert(constructorName.suffix == null); 270 assert(constructorNameReference.suffix == null);
233 KernelProcedureBuilder procedure = new KernelProcedureBuilder( 271 KernelProcedureBuilder procedure = new KernelProcedureBuilder(
234 metadata, 272 metadata,
235 staticMask | modifiers, 273 staticMask | modifiers,
236 null, 274 null,
237 name, 275 name,
238 <TypeVariableBuilder>[], 276 <TypeVariableBuilder>[],
239 formals, 277 formals,
240 asyncModifier, 278 asyncModifier,
241 ProcedureKind.Factory, 279 ProcedureKind.Factory,
242 this, 280 this,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 super.build(); 366 super.build();
329 library.name = name; 367 library.name = name;
330 library.procedures.sort(compareProcedures); 368 library.procedures.sort(compareProcedures);
331 return library; 369 return library;
332 } 370 }
333 371
334 @override 372 @override
335 Builder buildAmbiguousBuilder( 373 Builder buildAmbiguousBuilder(
336 String name, Builder builder, Builder other, int charOffset, 374 String name, Builder builder, Builder other, int charOffset,
337 {bool isExport: false, bool isImport: false}) { 375 {bool isExport: false, bool isImport: false}) {
376 // TODO(ahe): Can I move this to Scope or Prefix?
338 if (builder == other) return builder; 377 if (builder == other) return builder;
339 if (builder is InvalidTypeBuilder) return builder; 378 if (builder is InvalidTypeBuilder) return builder;
340 if (other is InvalidTypeBuilder) return other; 379 if (other is InvalidTypeBuilder) return other;
341 if (builder is AccessErrorBuilder) { 380 if (builder is AccessErrorBuilder) {
342 AccessErrorBuilder error = builder; 381 AccessErrorBuilder error = builder;
343 builder = error.builder; 382 builder = error.builder;
344 } 383 }
345 if (other is AccessErrorBuilder) { 384 if (other is AccessErrorBuilder) {
346 AccessErrorBuilder error = other; 385 AccessErrorBuilder error = other;
347 other = error.builder; 386 other = error.builder;
348 } 387 }
349 bool isLocal = false; 388 bool isLocal = false;
350 Builder preferred; 389 Builder preferred;
351 Uri uri; 390 Uri uri;
352 Uri otherUri; 391 Uri otherUri;
353 Uri preferredUri; 392 Uri preferredUri;
354 Uri hiddenUri; 393 Uri hiddenUri;
355 if (members[name] == builder) { 394 if (scope.local[name] == builder) {
356 isLocal = true; 395 isLocal = true;
357 preferred = builder; 396 preferred = builder;
358 hiddenUri = other.computeLibraryUri(); 397 hiddenUri = other.computeLibraryUri();
359 } else { 398 } else {
360 uri = builder.computeLibraryUri(); 399 uri = builder.computeLibraryUri();
361 otherUri = other.computeLibraryUri(); 400 otherUri = other.computeLibraryUri();
362 if (otherUri?.scheme == "dart" && uri?.scheme != "dart") { 401 if (otherUri?.scheme == "dart" && uri?.scheme != "dart") {
363 preferred = builder; 402 preferred = builder;
364 preferredUri = uri; 403 preferredUri = uri;
365 hiddenUri = otherUri; 404 hiddenUri = otherUri;
(...skipping 21 matching lines...) Expand all
387 } else { 426 } else {
388 addNit( 427 addNit(
389 charOffset, 428 charOffset,
390 "Import of '$name' (from '${preferredUri}') hides import from " 429 "Import of '$name' (from '${preferredUri}') hides import from "
391 "'${hiddenUri}'."); 430 "'${hiddenUri}'.");
392 } 431 }
393 } 432 }
394 return preferred; 433 return preferred;
395 } 434 }
396 if (builder.next == null && other.next == null) { 435 if (builder.next == null && other.next == null) {
397 if (builder.isGetter && other.isSetter) {
398 return new MixedAccessor(builder, other, this);
399 } else if (builder.isSetter && other.isGetter) {
400 return new MixedAccessor(other, builder, this);
401 }
402 if (isImport && builder is PrefixBuilder && other is PrefixBuilder) { 436 if (isImport && builder is PrefixBuilder && other is PrefixBuilder) {
403 // Handles the case where the same prefix is used for different 437 // Handles the case where the same prefix is used for different
404 // imports. 438 // imports.
405 PrefixBuilder prefix = builder; 439 return builder
406 other.exports.forEach((String name, Builder member) { 440 ..exports.merge(other.exports,
407 Builder existing = exports[name]; 441 (String name, Builder existing, Builder member) {
408 if (existing != null) { 442 return buildAmbiguousBuilder(name, existing, member, charOffset,
409 if (existing != member) { 443 isExport: isExport, isImport: isImport);
410 member = buildAmbiguousBuilder(name, existing, member, charOffset, 444 });
411 isExport: isExport, isImport: isImport);
412 }
413 }
414 prefix.exports[name] = member;
415 });
416 return builder;
417 } 445 }
418 } 446 }
419 if (isExport) { 447 if (isExport) {
420 addNit(charOffset, 448 addNit(charOffset,
421 "'$name' is exported from both '${uri}' and '${otherUri}'."); 449 "'$name' is exported from both '${uri}' and '${otherUri}'.");
422 } else { 450 } else {
423 addNit(charOffset, 451 addNit(charOffset,
424 "'$name' is imported from both '${uri}' and '${otherUri}'."); 452 "'$name' is imported from both '${uri}' and '${otherUri}'.");
425 } 453 }
426 return new KernelInvalidTypeBuilder(name, charOffset, fileUri); 454 return new KernelInvalidTypeBuilder(name, charOffset, fileUri);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 } 536 }
509 537
510 @override 538 @override
511 void includePart(covariant KernelLibraryBuilder part) { 539 void includePart(covariant KernelLibraryBuilder part) {
512 super.includePart(part); 540 super.includePart(part);
513 nativeMethods.addAll(part.nativeMethods); 541 nativeMethods.addAll(part.nativeMethods);
514 boundlessTypeVariables.addAll(part.boundlessTypeVariables); 542 boundlessTypeVariables.addAll(part.boundlessTypeVariables);
515 assert(mixinApplicationClasses.isEmpty); 543 assert(mixinApplicationClasses.isEmpty);
516 } 544 }
517 } 545 }
518
519 bool isConstructorName(String name, String className) {
520 if (name.startsWith(className)) {
521 if (name.length == className.length) return true;
522 if (name.startsWith(".", className.length)) return true;
523 }
524 return false;
525 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698