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

Side by Side Diff: pkg/compiler/lib/src/resolution/class_hierarchy.dart

Issue 1363993004: Report info messages together with their error, warning, or hint. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 2 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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 dart2js.resolution.class_hierarchy; 5 library dart2js.resolution.class_hierarchy;
6 6
7 import '../compiler.dart' show 7 import '../compiler.dart' show
8 Compiler; 8 Compiler;
9 import '../dart_types.dart'; 9 import '../dart_types.dart';
10 import '../diagnostics/invariant.dart' show 10 import '../diagnostics/invariant.dart' show
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 // Resolve the bounds of type variables. 61 // Resolve the bounds of type variables.
62 Iterator<DartType> types = element.typeVariables.iterator; 62 Iterator<DartType> types = element.typeVariables.iterator;
63 Link<Node> nodeLink = node.nodes; 63 Link<Node> nodeLink = node.nodes;
64 while (!nodeLink.isEmpty) { 64 while (!nodeLink.isEmpty) {
65 types.moveNext(); 65 types.moveNext();
66 TypeVariableType typeVariable = types.current; 66 TypeVariableType typeVariable = types.current;
67 String typeName = typeVariable.name; 67 String typeName = typeVariable.name;
68 TypeVariable typeNode = nodeLink.head; 68 TypeVariable typeNode = nodeLink.head;
69 registry.useType(typeNode, typeVariable); 69 registry.useType(typeNode, typeVariable);
70 if (nameSet.contains(typeName)) { 70 if (nameSet.contains(typeName)) {
71 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, 71 compiler.reportErrorMessage(
72 {'typeVariableName': typeName}); 72 typeNode,
73 MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
74 {'typeVariableName': typeName});
73 } 75 }
74 nameSet.add(typeName); 76 nameSet.add(typeName);
75 77
76 TypeVariableElementX variableElement = typeVariable.element; 78 TypeVariableElementX variableElement = typeVariable.element;
77 if (typeNode.bound != null) { 79 if (typeNode.bound != null) {
78 DartType boundType = typeResolver.resolveTypeAnnotation( 80 DartType boundType = typeResolver.resolveTypeAnnotation(
79 this, typeNode.bound); 81 this, typeNode.bound);
80 variableElement.boundCache = boundType; 82 variableElement.boundCache = boundType;
81 83
82 void checkTypeVariableBound() { 84 void checkTypeVariableBound() {
83 Link<TypeVariableElement> seenTypeVariables = 85 Link<TypeVariableElement> seenTypeVariables =
84 const Link<TypeVariableElement>(); 86 const Link<TypeVariableElement>();
85 seenTypeVariables = seenTypeVariables.prepend(variableElement); 87 seenTypeVariables = seenTypeVariables.prepend(variableElement);
86 DartType bound = boundType; 88 DartType bound = boundType;
87 while (bound.isTypeVariable) { 89 while (bound.isTypeVariable) {
88 TypeVariableElement element = bound.element; 90 TypeVariableElement element = bound.element;
89 if (seenTypeVariables.contains(element)) { 91 if (seenTypeVariables.contains(element)) {
90 if (identical(element, variableElement)) { 92 if (identical(element, variableElement)) {
91 // Only report an error on the checked type variable to avoid 93 // Only report an error on the checked type variable to avoid
92 // generating multiple errors for the same cyclicity. 94 // generating multiple errors for the same cyclicity.
93 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, 95 compiler.reportWarningMessage(
96 typeNode.name,
97 MessageKind.CYCLIC_TYPE_VARIABLE,
94 {'typeVariableName': variableElement.name}); 98 {'typeVariableName': variableElement.name});
95 } 99 }
96 break; 100 break;
97 } 101 }
98 seenTypeVariables = seenTypeVariables.prepend(element); 102 seenTypeVariables = seenTypeVariables.prepend(element);
99 bound = element.bound; 103 bound = element.bound;
100 } 104 }
101 } 105 }
102 addDeferredAction(element, checkTypeVariableBound); 106 addDeferredAction(element, checkTypeVariableBound);
103 } else { 107 } else {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 } 191 }
188 calculateAllSupertypes(element); 192 calculateAllSupertypes(element);
189 193
190 if (!element.hasConstructor) { 194 if (!element.hasConstructor) {
191 Element superMember = element.superclass.localLookup(''); 195 Element superMember = element.superclass.localLookup('');
192 if (superMember == null || !superMember.isGenerativeConstructor) { 196 if (superMember == null || !superMember.isGenerativeConstructor) {
193 MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR; 197 MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR;
194 Map arguments = {'constructorName': ''}; 198 Map arguments = {'constructorName': ''};
195 // TODO(ahe): Why is this a compile-time error? Or if it is an error, 199 // TODO(ahe): Why is this a compile-time error? Or if it is an error,
196 // why do we bother to registerThrowNoSuchMethod below? 200 // why do we bother to registerThrowNoSuchMethod below?
197 compiler.reportError(node, kind, arguments); 201 compiler.reportErrorMessage(node, kind, arguments);
198 superMember = new ErroneousElementX( 202 superMember = new ErroneousElementX(
199 kind, arguments, '', element); 203 kind, arguments, '', element);
200 registry.registerThrowNoSuchMethod(); 204 registry.registerThrowNoSuchMethod();
201 } else { 205 } else {
202 ConstructorElement superConstructor = superMember; 206 ConstructorElement superConstructor = superMember;
203 superConstructor.computeType(compiler); 207 superConstructor.computeType(compiler);
204 if (!CallStructure.NO_ARGS.signatureApplies( 208 if (!CallStructure.NO_ARGS.signatureApplies(
205 superConstructor.functionSignature)) { 209 superConstructor.functionSignature)) {
206 MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT; 210 MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT;
207 compiler.reportError(node, kind); 211 compiler.reportErrorMessage(node, kind);
208 superMember = new ErroneousElementX(kind, {}, '', element); 212 superMember = new ErroneousElementX(kind, {}, '', element);
209 } 213 }
210 } 214 }
211 FunctionElement constructor = 215 FunctionElement constructor =
212 new SynthesizedConstructorElementX.forDefault(superMember, element); 216 new SynthesizedConstructorElementX.forDefault(superMember, element);
213 if (superMember.isErroneous) { 217 if (superMember.isErroneous) {
214 compiler.elementsWithCompileTimeErrors.add(constructor); 218 compiler.elementsWithCompileTimeErrors.add(constructor);
215 } 219 }
216 element.setDefaultConstructor(constructor, compiler); 220 element.setDefaultConstructor(constructor, compiler);
217 } 221 }
218 return element.computeType(compiler); 222 return element.computeType(compiler);
219 } 223 }
220 224
221 @override 225 @override
222 DartType visitEnum(Enum node) { 226 DartType visitEnum(Enum node) {
223 if (element == null) { 227 if (element == null) {
224 throw compiler.internalError(node, 'element is null'); 228 throw compiler.internalError(node, 'element is null');
225 } 229 }
226 if (element.resolutionState != STATE_STARTED) { 230 if (element.resolutionState != STATE_STARTED) {
227 throw compiler.internalError(element, 231 throw compiler.internalError(element,
228 'cyclic resolution of class $element'); 232 'cyclic resolution of class $element');
229 } 233 }
230 234
231 InterfaceType enumType = element.computeType(compiler); 235 InterfaceType enumType = element.computeType(compiler);
232 element.supertype = compiler.objectClass.computeType(compiler); 236 element.supertype = compiler.objectClass.computeType(compiler);
233 element.interfaces = const Link<DartType>(); 237 element.interfaces = const Link<DartType>();
234 calculateAllSupertypes(element); 238 calculateAllSupertypes(element);
235 239
236 if (node.names.nodes.isEmpty) { 240 if (node.names.nodes.isEmpty) {
237 compiler.reportError(node, 241 compiler.reportErrorMessage(
238 MessageKind.EMPTY_ENUM_DECLARATION, 242 node,
239 {'enumName': element.name}); 243 MessageKind.EMPTY_ENUM_DECLARATION,
244 {'enumName': element.name});
240 } 245 }
241 246
242 EnumCreator creator = new EnumCreator(compiler, element); 247 EnumCreator creator = new EnumCreator(compiler, element);
243 creator.createMembers(); 248 creator.createMembers();
244 return enumType; 249 return enumType;
245 } 250 }
246 251
247 /// Resolves the mixed type for [mixinNode] and checks that the the mixin type 252 /// Resolves the mixed type for [mixinNode] and checks that the the mixin type
248 /// is a valid, non-blacklisted interface type. The mixin type is returned. 253 /// is a valid, non-blacklisted interface type. The mixin type is returned.
249 DartType checkMixinType(TypeAnnotation mixinNode) { 254 DartType checkMixinType(TypeAnnotation mixinNode) {
250 DartType mixinType = resolveType(mixinNode); 255 DartType mixinType = resolveType(mixinNode);
251 if (isBlackListed(mixinType)) { 256 if (isBlackListed(mixinType)) {
252 compiler.reportError(mixinNode, 257 compiler.reportErrorMessage(
253 MessageKind.CANNOT_MIXIN, {'type': mixinType}); 258 mixinNode,
259 MessageKind.CANNOT_MIXIN,
260 {'type': mixinType});
254 } else if (mixinType.isTypeVariable) { 261 } else if (mixinType.isTypeVariable) {
255 compiler.reportError(mixinNode, MessageKind.CLASS_NAME_EXPECTED); 262 compiler.reportErrorMessage(
263 mixinNode,
264 MessageKind.CLASS_NAME_EXPECTED);
256 } else if (mixinType.isMalformed) { 265 } else if (mixinType.isMalformed) {
257 compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED, 266 compiler.reportErrorMessage(
267 mixinNode,
268 MessageKind.CANNOT_MIXIN_MALFORMED,
258 {'className': element.name, 'malformedType': mixinType}); 269 {'className': element.name, 'malformedType': mixinType});
259 } else if (mixinType.isEnumType) { 270 } else if (mixinType.isEnumType) {
260 compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_ENUM, 271 compiler.reportErrorMessage(
272 mixinNode,
273 MessageKind.CANNOT_MIXIN_ENUM,
261 {'className': element.name, 'enumType': mixinType}); 274 {'className': element.name, 'enumType': mixinType});
262 } 275 }
263 return mixinType; 276 return mixinType;
264 } 277 }
265 278
266 DartType visitNamedMixinApplication(NamedMixinApplication node) { 279 DartType visitNamedMixinApplication(NamedMixinApplication node) {
267 if (element == null) { 280 if (element == null) {
268 throw compiler.internalError(node, 'element is null'); 281 throw compiler.internalError(node, 'element is null');
269 } 282 }
270 if (element.resolutionState != STATE_STARTED) { 283 if (element.resolutionState != STATE_STARTED) {
271 throw compiler.internalError(element, 284 throw compiler.internalError(element,
272 'cyclic resolution of class $element'); 285 'cyclic resolution of class $element');
273 } 286 }
274 287
275 if (identical(node.classKeyword.stringValue, 'typedef')) { 288 if (identical(node.classKeyword.stringValue, 'typedef')) {
276 // TODO(aprelev@gmail.com): Remove this deprecation diagnostic 289 // TODO(aprelev@gmail.com): Remove this deprecation diagnostic
277 // together with corresponding TODO in parser.dart. 290 // together with corresponding TODO in parser.dart.
278 compiler.reportWarning(node.classKeyword, 291 compiler.reportWarningMessage(
292 node.classKeyword,
279 MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX); 293 MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX);
280 } 294 }
281 295
282 element.computeType(compiler); 296 element.computeType(compiler);
283 scope = new TypeDeclarationScope(scope, element); 297 scope = new TypeDeclarationScope(scope, element);
284 resolveTypeVariableBounds(node.typeParameters); 298 resolveTypeVariableBounds(node.typeParameters);
285 299
286 // Generate anonymous mixin application elements for the 300 // Generate anonymous mixin application elements for the
287 // intermediate mixin applications (excluding the last). 301 // intermediate mixin applications (excluding the last).
288 DartType supertype = resolveSupertype(element, node.superclass); 302 DartType supertype = resolveSupertype(element, node.superclass);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 DartType mixinType) { 436 DartType mixinType) {
423 ClassElement mixin = mixinType.element; 437 ClassElement mixin = mixinType.element;
424 mixin.ensureResolved(compiler); 438 mixin.ensureResolved(compiler);
425 439
426 // Check for cycles in the mixin chain. 440 // Check for cycles in the mixin chain.
427 ClassElement previous = mixinApplication; // For better error messages. 441 ClassElement previous = mixinApplication; // For better error messages.
428 ClassElement current = mixin; 442 ClassElement current = mixin;
429 while (current != null && current.isMixinApplication) { 443 while (current != null && current.isMixinApplication) {
430 MixinApplicationElement currentMixinApplication = current; 444 MixinApplicationElement currentMixinApplication = current;
431 if (currentMixinApplication == mixinApplication) { 445 if (currentMixinApplication == mixinApplication) {
432 compiler.reportError( 446 compiler.reportErrorMessage(
433 mixinApplication, MessageKind.ILLEGAL_MIXIN_CYCLE, 447 mixinApplication,
448 MessageKind.ILLEGAL_MIXIN_CYCLE,
434 {'mixinName1': current.name, 'mixinName2': previous.name}); 449 {'mixinName1': current.name, 'mixinName2': previous.name});
435 // We have found a cycle in the mixin chain. Return null as 450 // We have found a cycle in the mixin chain. Return null as
436 // the mixin for this application to avoid getting into 451 // the mixin for this application to avoid getting into
437 // infinite recursion when traversing members. 452 // infinite recursion when traversing members.
438 return null; 453 return null;
439 } 454 }
440 previous = current; 455 previous = current;
441 current = currentMixinApplication.mixin; 456 current = currentMixinApplication.mixin;
442 } 457 }
443 registry.registerMixinUse(mixinApplication, mixin); 458 registry.registerMixinUse(mixinApplication, mixin);
444 return mixinType; 459 return mixinType;
445 } 460 }
446 461
447 DartType resolveType(TypeAnnotation node) { 462 DartType resolveType(TypeAnnotation node) {
448 return typeResolver.resolveTypeAnnotation(this, node); 463 return typeResolver.resolveTypeAnnotation(this, node);
449 } 464 }
450 465
451 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { 466 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) {
452 DartType supertype = resolveType(superclass); 467 DartType supertype = resolveType(superclass);
453 if (supertype != null) { 468 if (supertype != null) {
454 if (supertype.isMalformed) { 469 if (supertype.isMalformed) {
455 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_MALFORMED, 470 compiler.reportErrorMessage(
471 superclass,
472 MessageKind.CANNOT_EXTEND_MALFORMED,
456 {'className': element.name, 'malformedType': supertype}); 473 {'className': element.name, 'malformedType': supertype});
457 return objectType; 474 return objectType;
458 } else if (supertype.isEnumType) { 475 } else if (supertype.isEnumType) {
459 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_ENUM, 476 compiler.reportErrorMessage(
477 superclass,
478 MessageKind.CANNOT_EXTEND_ENUM,
460 {'className': element.name, 'enumType': supertype}); 479 {'className': element.name, 'enumType': supertype});
461 return objectType; 480 return objectType;
462 } else if (!supertype.isInterfaceType) { 481 } else if (!supertype.isInterfaceType) {
463 compiler.reportError(superclass.typeName, 482 compiler.reportErrorMessage(
483 superclass.typeName,
464 MessageKind.CLASS_NAME_EXPECTED); 484 MessageKind.CLASS_NAME_EXPECTED);
465 return objectType; 485 return objectType;
466 } else if (isBlackListed(supertype)) { 486 } else if (isBlackListed(supertype)) {
467 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND, 487 compiler.reportErrorMessage(
488 superclass,
489 MessageKind.CANNOT_EXTEND,
468 {'type': supertype}); 490 {'type': supertype});
469 return objectType; 491 return objectType;
470 } 492 }
471 } 493 }
472 return supertype; 494 return supertype;
473 } 495 }
474 496
475 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { 497 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) {
476 Link<DartType> result = const Link<DartType>(); 498 Link<DartType> result = const Link<DartType>();
477 if (interfaces == null) return result; 499 if (interfaces == null) return result;
478 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { 500 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) {
479 DartType interfaceType = resolveType(link.head); 501 DartType interfaceType = resolveType(link.head);
480 if (interfaceType != null) { 502 if (interfaceType != null) {
481 if (interfaceType.isMalformed) { 503 if (interfaceType.isMalformed) {
482 compiler.reportError(superclass, 504 compiler.reportErrorMessage(
505 superclass,
483 MessageKind.CANNOT_IMPLEMENT_MALFORMED, 506 MessageKind.CANNOT_IMPLEMENT_MALFORMED,
484 {'className': element.name, 'malformedType': interfaceType}); 507 {'className': element.name, 'malformedType': interfaceType});
485 } else if (interfaceType.isEnumType) { 508 } else if (interfaceType.isEnumType) {
486 compiler.reportError(superclass, 509 compiler.reportErrorMessage(
510 superclass,
487 MessageKind.CANNOT_IMPLEMENT_ENUM, 511 MessageKind.CANNOT_IMPLEMENT_ENUM,
488 {'className': element.name, 'enumType': interfaceType}); 512 {'className': element.name, 'enumType': interfaceType});
489 } else if (!interfaceType.isInterfaceType) { 513 } else if (!interfaceType.isInterfaceType) {
490 // TODO(johnniwinther): Handle dynamic. 514 // TODO(johnniwinther): Handle dynamic.
491 TypeAnnotation typeAnnotation = link.head; 515 TypeAnnotation typeAnnotation = link.head;
492 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); 516 compiler.reportErrorMessage(
517 typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
493 } else { 518 } else {
494 if (interfaceType == element.supertype) { 519 if (interfaceType == element.supertype) {
495 compiler.reportError( 520 compiler.reportErrorMessage(
496 superclass, 521 superclass,
497 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, 522 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
498 {'type': interfaceType}); 523 {'type': interfaceType});
499 compiler.reportError( 524 compiler.reportErrorMessage(
500 link.head, 525 link.head,
501 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, 526 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
502 {'type': interfaceType}); 527 {'type': interfaceType});
503 } 528 }
504 if (result.contains(interfaceType)) { 529 if (result.contains(interfaceType)) {
505 compiler.reportError( 530 compiler.reportErrorMessage(
506 link.head, 531 link.head,
507 MessageKind.DUPLICATE_IMPLEMENTS, 532 MessageKind.DUPLICATE_IMPLEMENTS,
508 {'type': interfaceType}); 533 {'type': interfaceType});
509 } 534 }
510 result = result.prepend(interfaceType); 535 result = result.prepend(interfaceType);
511 if (isBlackListed(interfaceType)) { 536 if (isBlackListed(interfaceType)) {
512 error(link.head, MessageKind.CANNOT_IMPLEMENT, 537 compiler.reportErrorMessage(
513 {'type': interfaceType}); 538 link.head,
539 MessageKind.CANNOT_IMPLEMENT,
540 {'type': interfaceType});
514 } 541 }
515 } 542 }
516 } 543 }
517 } 544 }
518 return result; 545 return result;
519 } 546 }
520 547
521 /** 548 /**
522 * Compute the list of all supertypes. 549 * Compute the list of all supertypes.
523 * 550 *
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 void visitIdentifier(Identifier node) { 680 void visitIdentifier(Identifier node) {
654 Element element = lookupInScope(compiler, node, context, node.source); 681 Element element = lookupInScope(compiler, node, context, node.source);
655 if (element != null && element.isClass) { 682 if (element != null && element.isClass) {
656 loadSupertype(element, node); 683 loadSupertype(element, node);
657 } 684 }
658 } 685 }
659 686
660 void visitSend(Send node) { 687 void visitSend(Send node) {
661 Identifier prefix = node.receiver.asIdentifier(); 688 Identifier prefix = node.receiver.asIdentifier();
662 if (prefix == null) { 689 if (prefix == null) {
663 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); 690 compiler.reportErrorMessage(
691 node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
664 return; 692 return;
665 } 693 }
666 Element element = lookupInScope(compiler, prefix, context, prefix.source); 694 Element element = lookupInScope(compiler, prefix, context, prefix.source);
667 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { 695 if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
668 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); 696 compiler.reportErrorMessage(
697 node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
669 return; 698 return;
670 } 699 }
671 PrefixElement prefixElement = element; 700 PrefixElement prefixElement = element;
672 Identifier selector = node.selector.asIdentifier(); 701 Identifier selector = node.selector.asIdentifier();
673 var e = prefixElement.lookupLocalMember(selector.source); 702 var e = prefixElement.lookupLocalMember(selector.source);
674 if (e == null || !e.impliesType) { 703 if (e == null || !e.impliesType) {
675 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, 704 compiler.reportErrorMessage(
676 {'typeName': node.selector}); 705 node.selector,
706 MessageKind.CANNOT_RESOLVE_TYPE,
707 {'typeName': node.selector});
677 return; 708 return;
678 } 709 }
679 loadSupertype(e, node); 710 loadSupertype(e, node);
680 } 711 }
681 } 712 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698