| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of resolution; | 5 part of resolution; |
| 6 | 6 |
| 7 abstract class TreeElements { | 7 abstract class TreeElements { |
| 8 Element operator[](Node node); | 8 Element operator[](Node node); |
| 9 Selector getSelector(Send send); | 9 Selector getSelector(Send send); |
| 10 DartType getType(Node node); | 10 DartType getType(Node node); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 Element patchParameter = patchParameters.head; | 147 Element patchParameter = patchParameters.head; |
| 148 // Hack: Use unparser to test parameter equality. This only works because | 148 // Hack: Use unparser to test parameter equality. This only works because |
| 149 // we are restricting patch uses and the approach cannot be used | 149 // we are restricting patch uses and the approach cannot be used |
| 150 // elsewhere. | 150 // elsewhere. |
| 151 String originParameterText = | 151 String originParameterText = |
| 152 originParameter.parseNode(compiler).toString(); | 152 originParameter.parseNode(compiler).toString(); |
| 153 String patchParameterText = | 153 String patchParameterText = |
| 154 patchParameter.parseNode(compiler).toString(); | 154 patchParameter.parseNode(compiler).toString(); |
| 155 if (originParameterText != patchParameterText) { | 155 if (originParameterText != patchParameterText) { |
| 156 error(originParameter.parseNode(compiler), | 156 error(originParameter.parseNode(compiler), |
| 157 MessageKind.PATCH_PARAMETER_MISMATCH, | 157 MessageKind.PATCH_PARAMETER_MISMATCH, |
| 158 [origin.name, originParameterText, patchParameterText]); | 158 {'methodName': origin.name, |
| 159 'originParameter': originParameterText, |
| 160 'patchParameter': patchParameterText}); |
| 159 } | 161 } |
| 160 | 162 |
| 161 originParameters = originParameters.tail; | 163 originParameters = originParameters.tail; |
| 162 patchParameters = patchParameters.tail; | 164 patchParameters = patchParameters.tail; |
| 163 } | 165 } |
| 164 } | 166 } |
| 165 | 167 |
| 166 void checkMatchingPatchSignatures(FunctionElement origin, | 168 void checkMatchingPatchSignatures(FunctionElement origin, |
| 167 FunctionElement patch) { | 169 FunctionElement patch) { |
| 168 // TODO(johnniwinther): Show both origin and patch locations on errors. | 170 // TODO(johnniwinther): Show both origin and patch locations on errors. |
| 169 FunctionExpression originTree = compiler.withCurrentElement(origin, () { | 171 FunctionExpression originTree = compiler.withCurrentElement(origin, () { |
| 170 return origin.parseNode(compiler); | 172 return origin.parseNode(compiler); |
| 171 }); | 173 }); |
| 172 FunctionSignature originSignature = compiler.withCurrentElement(origin, () { | 174 FunctionSignature originSignature = compiler.withCurrentElement(origin, () { |
| 173 return origin.computeSignature(compiler); | 175 return origin.computeSignature(compiler); |
| 174 }); | 176 }); |
| 175 FunctionExpression patchTree = compiler.withCurrentElement(patch, () { | 177 FunctionExpression patchTree = compiler.withCurrentElement(patch, () { |
| 176 return patch.parseNode(compiler); | 178 return patch.parseNode(compiler); |
| 177 }); | 179 }); |
| 178 FunctionSignature patchSignature = compiler.withCurrentElement(patch, () { | 180 FunctionSignature patchSignature = compiler.withCurrentElement(patch, () { |
| 179 return patch.computeSignature(compiler); | 181 return patch.computeSignature(compiler); |
| 180 }); | 182 }); |
| 181 | 183 |
| 182 if (originSignature.returnType != patchSignature.returnType) { | 184 if (originSignature.returnType != patchSignature.returnType) { |
| 183 compiler.withCurrentElement(patch, () { | 185 compiler.withCurrentElement(patch, () { |
| 184 Node errorNode = | 186 Node errorNode = |
| 185 patchTree.returnType != null ? patchTree.returnType : patchTree; | 187 patchTree.returnType != null ? patchTree.returnType : patchTree; |
| 186 error(errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH, [origin.name, | 188 error(errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH, |
| 187 originSignature.returnType, patchSignature.returnType]); | 189 {'methodName': origin.name, |
| 190 'originReturnType': originSignature.returnType, |
| 191 'patchReturnType': patchSignature.returnType}); |
| 188 }); | 192 }); |
| 189 } | 193 } |
| 190 if (originSignature.requiredParameterCount != | 194 if (originSignature.requiredParameterCount != |
| 191 patchSignature.requiredParameterCount) { | 195 patchSignature.requiredParameterCount) { |
| 192 compiler.withCurrentElement(patch, () { | 196 compiler.withCurrentElement(patch, () { |
| 193 error(patchTree, | 197 error(patchTree, |
| 194 MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH, | 198 MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH, |
| 195 [origin.name, originSignature.requiredParameterCount, | 199 {'methodName': origin.name, |
| 196 patchSignature.requiredParameterCount]); | 200 'originParameterCount': originSignature.requiredParameterCount, |
| 201 'patchParameterCount': patchSignature.requiredParameterCount}); |
| 197 }); | 202 }); |
| 198 } else { | 203 } else { |
| 199 checkMatchingPatchParameters(origin, | 204 checkMatchingPatchParameters(origin, |
| 200 originSignature.requiredParameters, | 205 originSignature.requiredParameters, |
| 201 patchSignature.requiredParameters); | 206 patchSignature.requiredParameters); |
| 202 } | 207 } |
| 203 if (originSignature.optionalParameterCount != 0 && | 208 if (originSignature.optionalParameterCount != 0 && |
| 204 patchSignature.optionalParameterCount != 0) { | 209 patchSignature.optionalParameterCount != 0) { |
| 205 if (originSignature.optionalParametersAreNamed != | 210 if (originSignature.optionalParametersAreNamed != |
| 206 patchSignature.optionalParametersAreNamed) { | 211 patchSignature.optionalParametersAreNamed) { |
| 207 compiler.withCurrentElement(patch, () { | 212 compiler.withCurrentElement(patch, () { |
| 208 error(patchTree, | 213 error(patchTree, |
| 209 MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH, | 214 MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH, |
| 210 [origin.name]); | 215 {'methodName': origin.name}); |
| 211 }); | 216 }); |
| 212 } | 217 } |
| 213 } | 218 } |
| 214 if (originSignature.optionalParameterCount != | 219 if (originSignature.optionalParameterCount != |
| 215 patchSignature.optionalParameterCount) { | 220 patchSignature.optionalParameterCount) { |
| 216 compiler.withCurrentElement(patch, () { | 221 compiler.withCurrentElement(patch, () { |
| 217 error(patchTree, | 222 error(patchTree, |
| 218 MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH, | 223 MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH, |
| 219 [origin.name, originSignature.optionalParameterCount, | 224 {'methodName': origin.name, |
| 220 patchSignature.optionalParameterCount]); | 225 'originParameterCount': originSignature.optionalParameterCount, |
| 226 'patchParameterCount': patchSignature.optionalParameterCount}); |
| 221 }); | 227 }); |
| 222 } else { | 228 } else { |
| 223 checkMatchingPatchParameters(origin, | 229 checkMatchingPatchParameters(origin, |
| 224 originSignature.optionalParameters, | 230 originSignature.optionalParameters, |
| 225 patchSignature.optionalParameters); | 231 patchSignature.optionalParameters); |
| 226 } | 232 } |
| 227 } | 233 } |
| 228 | 234 |
| 229 TreeElements resolveMethodElement(FunctionElement element) { | 235 TreeElements resolveMethodElement(FunctionElement element) { |
| 230 assert(invariant(element, element.isDeclaration)); | 236 assert(invariant(element, element.isDeclaration)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 visitor.visit(body); | 310 visitor.visit(body); |
| 305 } | 311 } |
| 306 | 312 |
| 307 void resolveConstructorImplementation(FunctionElement constructor, | 313 void resolveConstructorImplementation(FunctionElement constructor, |
| 308 FunctionExpression node) { | 314 FunctionExpression node) { |
| 309 if (!identical(constructor.defaultImplementation, constructor)) return; | 315 if (!identical(constructor.defaultImplementation, constructor)) return; |
| 310 ClassElement intrface = constructor.getEnclosingClass(); | 316 ClassElement intrface = constructor.getEnclosingClass(); |
| 311 if (!intrface.isInterface()) return; | 317 if (!intrface.isInterface()) return; |
| 312 DartType defaultType = intrface.defaultClass; | 318 DartType defaultType = intrface.defaultClass; |
| 313 if (defaultType == null) { | 319 if (defaultType == null) { |
| 314 error(node, MessageKind.NO_DEFAULT_CLASS, [intrface.name]); | 320 error(node, MessageKind.NO_DEFAULT_CLASS, |
| 321 {'interfaceName': intrface.name}); |
| 315 } | 322 } |
| 316 ClassElement defaultClass = defaultType.element; | 323 ClassElement defaultClass = defaultType.element; |
| 317 defaultClass.ensureResolved(compiler); | 324 defaultClass.ensureResolved(compiler); |
| 318 assert(defaultClass.resolutionState == STATE_DONE); | 325 assert(defaultClass.resolutionState == STATE_DONE); |
| 319 assert(defaultClass.supertypeLoadState == STATE_DONE); | 326 assert(defaultClass.supertypeLoadState == STATE_DONE); |
| 320 if (defaultClass.isInterface()) { | 327 if (defaultClass.isInterface()) { |
| 321 error(node, MessageKind.CANNOT_INSTANTIATE_INTERFACE, | 328 error(node, MessageKind.CANNOT_INSTANTIATE_INTERFACE, |
| 322 [defaultClass.name]); | 329 {'interfaceName': defaultClass.name}); |
| 323 } | 330 } |
| 324 // We have now established the following: | 331 // We have now established the following: |
| 325 // [intrface] is an interface, let's say "MyInterface". | 332 // [intrface] is an interface, let's say "MyInterface". |
| 326 // [defaultClass] is a class, let's say "MyClass". | 333 // [defaultClass] is a class, let's say "MyClass". |
| 327 | 334 |
| 328 Selector selector; | 335 Selector selector; |
| 329 // If the default class implements the interface then we must use the | 336 // If the default class implements the interface then we must use the |
| 330 // default class' name. Otherwise we look for a factory with the name | 337 // default class' name. Otherwise we look for a factory with the name |
| 331 // of the interface. | 338 // of the interface. |
| 332 if (defaultClass.implementsInterface(intrface)) { | 339 if (defaultClass.implementsInterface(intrface)) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 353 constructor.defaultImplementation = | 360 constructor.defaultImplementation = |
| 354 defaultClass.lookupFactoryConstructor(selector); | 361 defaultClass.lookupFactoryConstructor(selector); |
| 355 } | 362 } |
| 356 if (constructor.defaultImplementation == null) { | 363 if (constructor.defaultImplementation == null) { |
| 357 // We failed to find a constructor named either | 364 // We failed to find a constructor named either |
| 358 // "MyInterface.name" or "MyClass.name". | 365 // "MyInterface.name" or "MyClass.name". |
| 359 // TODO(aprelev@gmail.com): Use constructorNameForDiagnostics in | 366 // TODO(aprelev@gmail.com): Use constructorNameForDiagnostics in |
| 360 // the error message below. | 367 // the error message below. |
| 361 error(node, | 368 error(node, |
| 362 MessageKind.CANNOT_FIND_CONSTRUCTOR2, | 369 MessageKind.CANNOT_FIND_CONSTRUCTOR2, |
| 363 [selector.name, defaultClass.name]); | 370 {'constructorName': selector.name, 'className': defaultClass.name}); |
| 364 } | 371 } |
| 365 } | 372 } |
| 366 | 373 |
| 367 TreeElements resolveField(VariableElement element) { | 374 TreeElements resolveField(VariableElement element) { |
| 368 Node tree = element.parseNode(compiler); | 375 Node tree = element.parseNode(compiler); |
| 369 if(element.modifiers.isStatic() && element.variables.isTopLevel()) { | 376 if(element.modifiers.isStatic() && element.variables.isTopLevel()) { |
| 370 error(element.modifiers.getStatic(), | 377 error(element.modifiers.getStatic(), |
| 371 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 378 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
| 372 } | 379 } |
| 373 ResolverVisitor visitor = visitorFor(element); | 380 ResolverVisitor visitor = visitorFor(element); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 * | 416 * |
| 410 * Warning: do not call this method directly. It should only be | 417 * Warning: do not call this method directly. It should only be |
| 411 * called by [resolveClass] and [ClassSupertypeResolver]. | 418 * called by [resolveClass] and [ClassSupertypeResolver]. |
| 412 */ | 419 */ |
| 413 void loadSupertypes(ClassElement cls, Spannable from) { | 420 void loadSupertypes(ClassElement cls, Spannable from) { |
| 414 compiler.withCurrentElement(cls, () => measure(() { | 421 compiler.withCurrentElement(cls, () => measure(() { |
| 415 if (cls.supertypeLoadState == STATE_DONE) return; | 422 if (cls.supertypeLoadState == STATE_DONE) return; |
| 416 if (cls.supertypeLoadState == STATE_STARTED) { | 423 if (cls.supertypeLoadState == STATE_STARTED) { |
| 417 compiler.reportMessage( | 424 compiler.reportMessage( |
| 418 compiler.spanFromSpannable(from), | 425 compiler.spanFromSpannable(from), |
| 419 MessageKind.CYCLIC_CLASS_HIERARCHY.error([cls.name]), | 426 MessageKind.CYCLIC_CLASS_HIERARCHY.error({'className': cls.name}), |
| 420 Diagnostic.ERROR); | 427 Diagnostic.ERROR); |
| 421 cls.supertypeLoadState = STATE_DONE; | 428 cls.supertypeLoadState = STATE_DONE; |
| 422 cls.allSupertypes = const Link<DartType>().prepend( | 429 cls.allSupertypes = const Link<DartType>().prepend( |
| 423 compiler.objectClass.computeType(compiler)); | 430 compiler.objectClass.computeType(compiler)); |
| 424 // TODO(ahe): We should also set cls.supertype here to avoid | 431 // TODO(ahe): We should also set cls.supertype here to avoid |
| 425 // creating a malformed class hierarchy. | 432 // creating a malformed class hierarchy. |
| 426 return; | 433 return; |
| 427 } | 434 } |
| 428 cls.supertypeLoadState = STATE_STARTED; | 435 cls.supertypeLoadState = STATE_STARTED; |
| 429 compiler.withCurrentElement(cls, () { | 436 compiler.withCurrentElement(cls, () { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 } | 528 } |
| 522 } | 529 } |
| 523 | 530 |
| 524 void checkMixinApplication(MixinApplicationElement mixinApplication) { | 531 void checkMixinApplication(MixinApplicationElement mixinApplication) { |
| 525 Modifiers modifiers = mixinApplication.modifiers; | 532 Modifiers modifiers = mixinApplication.modifiers; |
| 526 int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT; | 533 int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT; |
| 527 if (illegalFlags != 0) { | 534 if (illegalFlags != 0) { |
| 528 Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags); | 535 Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags); |
| 529 CompilationError error = | 536 CompilationError error = |
| 530 MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS.error( | 537 MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS.error( |
| 531 [illegalModifiers]); | 538 {'modifiers': illegalModifiers}); |
| 532 compiler.reportMessage(compiler.spanFromSpannable(modifiers), | 539 compiler.reportMessage(compiler.spanFromSpannable(modifiers), |
| 533 error, Diagnostic.ERROR); | 540 error, Diagnostic.ERROR); |
| 534 } | 541 } |
| 535 | 542 |
| 536 // In case of cyclic mixin applications, the mixin chain will have | 543 // In case of cyclic mixin applications, the mixin chain will have |
| 537 // been cut. If so, we have already reported the error to the | 544 // been cut. If so, we have already reported the error to the |
| 538 // user so we just return from here. | 545 // user so we just return from here. |
| 539 ClassElement mixin = mixinApplication.mixin; | 546 ClassElement mixin = mixinApplication.mixin; |
| 540 if (mixin == null) return; | 547 if (mixin == null) return; |
| 541 | 548 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 566 }); | 573 }); |
| 567 } | 574 } |
| 568 | 575 |
| 569 void checkMixinSuperUses(TreeElements resolutionTree, | 576 void checkMixinSuperUses(TreeElements resolutionTree, |
| 570 MixinApplicationElement mixinApplication, | 577 MixinApplicationElement mixinApplication, |
| 571 ClassElement mixin) { | 578 ClassElement mixin) { |
| 572 if (resolutionTree == null) return; | 579 if (resolutionTree == null) return; |
| 573 Set<Node> superUses = resolutionTree.superUses; | 580 Set<Node> superUses = resolutionTree.superUses; |
| 574 if (superUses.isEmpty) return; | 581 if (superUses.isEmpty) return; |
| 575 CompilationError error = MessageKind.ILLEGAL_MIXIN_WITH_SUPER.error( | 582 CompilationError error = MessageKind.ILLEGAL_MIXIN_WITH_SUPER.error( |
| 576 [mixin.name]); | 583 {'className': mixin.name}); |
| 577 compiler.reportMessage(compiler.spanFromElement(mixinApplication), | 584 compiler.reportMessage(compiler.spanFromElement(mixinApplication), |
| 578 error, Diagnostic.ERROR); | 585 error, Diagnostic.ERROR); |
| 579 // Show the user the problematic uses of 'super' in the mixin. | 586 // Show the user the problematic uses of 'super' in the mixin. |
| 580 for (Node use in superUses) { | 587 for (Node use in superUses) { |
| 581 CompilationError error = MessageKind.ILLEGAL_MIXIN_SUPER_USE.error(); | 588 CompilationError error = MessageKind.ILLEGAL_MIXIN_SUPER_USE.error(); |
| 582 compiler.reportMessage(compiler.spanFromNode(use), | 589 compiler.reportMessage(compiler.spanFromNode(use), |
| 583 error, Diagnostic.INFO); | 590 error, Diagnostic.INFO); |
| 584 } | 591 } |
| 585 } | 592 } |
| 586 | 593 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 604 if (member.isConstructor()) { | 611 if (member.isConstructor()) { |
| 605 final mismatchedFlagsBits = | 612 final mismatchedFlagsBits = |
| 606 member.modifiers.flags & | 613 member.modifiers.flags & |
| 607 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); | 614 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); |
| 608 if (mismatchedFlagsBits != 0) { | 615 if (mismatchedFlagsBits != 0) { |
| 609 final mismatchedFlags = | 616 final mismatchedFlags = |
| 610 new Modifiers.withFlags(null, mismatchedFlagsBits); | 617 new Modifiers.withFlags(null, mismatchedFlagsBits); |
| 611 compiler.reportMessage( | 618 compiler.reportMessage( |
| 612 compiler.spanFromElement(member), | 619 compiler.spanFromElement(member), |
| 613 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS.error( | 620 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS.error( |
| 614 [mismatchedFlags]), | 621 {'modifiers': mismatchedFlags}), |
| 615 Diagnostic.ERROR); | 622 Diagnostic.ERROR); |
| 616 } | 623 } |
| 617 checkConstructorNameHack(holder, member); | 624 checkConstructorNameHack(holder, member); |
| 618 } | 625 } |
| 619 checkAbstractField(member); | 626 checkAbstractField(member); |
| 620 checkValidOverride(member, cls.lookupSuperMember(member.name)); | 627 checkValidOverride(member, cls.lookupSuperMember(member.name)); |
| 621 checkUserDefinableOperator(member); | 628 checkUserDefinableOperator(member); |
| 622 }); | 629 }); |
| 623 }); | 630 }); |
| 624 } | 631 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 638 | 645 |
| 639 // If the name could not be deconstructed, this is is from a | 646 // If the name could not be deconstructed, this is is from a |
| 640 // factory method from a deprecated interface implementation. | 647 // factory method from a deprecated interface implementation. |
| 641 if (name == null) return; | 648 if (name == null) return; |
| 642 | 649 |
| 643 Element otherMember = holder.lookupLocalMember(name); | 650 Element otherMember = holder.lookupLocalMember(name); |
| 644 if (otherMember != null) { | 651 if (otherMember != null) { |
| 645 if (compiler.onDeprecatedFeature(member, 'conflicting constructor')) { | 652 if (compiler.onDeprecatedFeature(member, 'conflicting constructor')) { |
| 646 compiler.reportMessage( | 653 compiler.reportMessage( |
| 647 compiler.spanFromElement(otherMember), | 654 compiler.spanFromElement(otherMember), |
| 648 MessageKind.GENERIC.error(['This member conflicts with a' | 655 MessageKind.GENERIC.error({'text': 'This member conflicts with a' |
| 649 ' constructor.']), | 656 ' constructor.'}), |
| 650 Diagnostic.INFO); | 657 Diagnostic.INFO); |
| 651 } | 658 } |
| 652 } | 659 } |
| 653 } | 660 } |
| 654 | 661 |
| 655 void checkAbstractField(Element member) { | 662 void checkAbstractField(Element member) { |
| 656 // Only check for getters. The test can only fail if there is both a setter | 663 // Only check for getters. The test can only fail if there is both a setter |
| 657 // and a getter with the same name, and we only need to check each abstract | 664 // and a getter with the same name, and we only need to check each abstract |
| 658 // field once, so we just ignore setters. | 665 // field once, so we just ignore setters. |
| 659 if (!member.isGetter()) return; | 666 if (!member.isGetter()) return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 672 | 679 |
| 673 if (field.getter == null) return; | 680 if (field.getter == null) return; |
| 674 if (field.setter == null) return; | 681 if (field.setter == null) return; |
| 675 int getterFlags = field.getter.modifiers.flags | Modifiers.FLAG_ABSTRACT; | 682 int getterFlags = field.getter.modifiers.flags | Modifiers.FLAG_ABSTRACT; |
| 676 int setterFlags = field.setter.modifiers.flags | Modifiers.FLAG_ABSTRACT; | 683 int setterFlags = field.setter.modifiers.flags | Modifiers.FLAG_ABSTRACT; |
| 677 if (!identical(getterFlags, setterFlags)) { | 684 if (!identical(getterFlags, setterFlags)) { |
| 678 final mismatchedFlags = | 685 final mismatchedFlags = |
| 679 new Modifiers.withFlags(null, getterFlags ^ setterFlags); | 686 new Modifiers.withFlags(null, getterFlags ^ setterFlags); |
| 680 compiler.reportMessage( | 687 compiler.reportMessage( |
| 681 compiler.spanFromElement(field.getter), | 688 compiler.spanFromElement(field.getter), |
| 682 MessageKind.GETTER_MISMATCH.error([mismatchedFlags]), | 689 MessageKind.GETTER_MISMATCH.error({'modifiers': mismatchedFlags}), |
| 683 Diagnostic.ERROR); | 690 Diagnostic.ERROR); |
| 684 compiler.reportMessage( | 691 compiler.reportMessage( |
| 685 compiler.spanFromElement(field.setter), | 692 compiler.spanFromElement(field.setter), |
| 686 MessageKind.SETTER_MISMATCH.error([mismatchedFlags]), | 693 MessageKind.SETTER_MISMATCH.error({'modifiers': mismatchedFlags}), |
| 687 Diagnostic.ERROR); | 694 Diagnostic.ERROR); |
| 688 } | 695 } |
| 689 } | 696 } |
| 690 | 697 |
| 691 void checkUserDefinableOperator(Element member) { | 698 void checkUserDefinableOperator(Element member) { |
| 692 FunctionElement function = member.asFunctionElement(); | 699 FunctionElement function = member.asFunctionElement(); |
| 693 if (function == null) return; | 700 if (function == null) return; |
| 694 String value = member.name.stringValue; | 701 String value = member.name.stringValue; |
| 695 if (value == null) return; | 702 if (value == null) return; |
| 696 if (!(isUserDefinableOperator(value) || identical(value, 'unary-'))) return; | 703 if (!(isUserDefinableOperator(value) || identical(value, 'unary-'))) return; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 Node errorNode = node; | 735 Node errorNode = node; |
| 729 if (node.parameters != null) { | 736 if (node.parameters != null) { |
| 730 if (signature.requiredParameterCount < requiredParameterCount) { | 737 if (signature.requiredParameterCount < requiredParameterCount) { |
| 731 errorNode = node.parameters; | 738 errorNode = node.parameters; |
| 732 } else { | 739 } else { |
| 733 errorNode = node.parameters.nodes.skip(requiredParameterCount).head; | 740 errorNode = node.parameters.nodes.skip(requiredParameterCount).head; |
| 734 } | 741 } |
| 735 } | 742 } |
| 736 compiler.reportMessage( | 743 compiler.reportMessage( |
| 737 compiler.spanFromSpannable(errorNode), | 744 compiler.spanFromSpannable(errorNode), |
| 738 messageKind.error([function.name]), | 745 messageKind.error({'operatorName': function.name}), |
| 739 Diagnostic.ERROR); | 746 Diagnostic.ERROR); |
| 740 } | 747 } |
| 741 if (signature.optionalParameterCount != 0) { | 748 if (signature.optionalParameterCount != 0) { |
| 742 Node errorNode = | 749 Node errorNode = |
| 743 node.parameters.nodes.skip(signature.requiredParameterCount).head; | 750 node.parameters.nodes.skip(signature.requiredParameterCount).head; |
| 744 if (signature.optionalParametersAreNamed) { | 751 if (signature.optionalParametersAreNamed) { |
| 745 compiler.reportMessage( | 752 compiler.reportMessage( |
| 746 compiler.spanFromSpannable(errorNode), | 753 compiler.spanFromSpannable(errorNode), |
| 747 MessageKind.OPERATOR_NAMED_PARAMETERS.error([function.name]), | 754 MessageKind.OPERATOR_NAMED_PARAMETERS.error( |
| 755 {'operatorName': function.name}), |
| 748 Diagnostic.ERROR); | 756 Diagnostic.ERROR); |
| 749 } else { | 757 } else { |
| 750 compiler.reportMessage( | 758 compiler.reportMessage( |
| 751 compiler.spanFromSpannable(errorNode), | 759 compiler.spanFromSpannable(errorNode), |
| 752 MessageKind.OPERATOR_OPTIONAL_PARAMETERS.error([function.name]), | 760 MessageKind.OPERATOR_OPTIONAL_PARAMETERS.error( |
| 761 {'operatorName': function.name}), |
| 753 Diagnostic.ERROR); | 762 Diagnostic.ERROR); |
| 754 } | 763 } |
| 755 } | 764 } |
| 756 } | 765 } |
| 757 | 766 |
| 758 reportErrorWithContext(Element errorneousElement, | 767 reportErrorWithContext(Element errorneousElement, |
| 759 MessageKind errorMessage, | 768 MessageKind errorMessage, |
| 760 Element contextElement, | 769 Element contextElement, |
| 761 MessageKind contextMessage) { | 770 MessageKind contextMessage) { |
| 762 compiler.reportMessage( | 771 compiler.reportMessage( |
| 763 compiler.spanFromElement(errorneousElement), | 772 compiler.spanFromElement(errorneousElement), |
| 764 errorMessage.error([contextElement.name, | 773 errorMessage.error( |
| 765 contextElement.getEnclosingClass().name]), | 774 {'memberName': contextElement.name, |
| 775 'className': contextElement.getEnclosingClass().name}), |
| 766 Diagnostic.ERROR); | 776 Diagnostic.ERROR); |
| 767 compiler.reportMessage( | 777 compiler.reportMessage( |
| 768 compiler.spanFromElement(contextElement), | 778 compiler.spanFromElement(contextElement), |
| 769 contextMessage.error(), | 779 contextMessage.error(), |
| 770 Diagnostic.INFO); | 780 Diagnostic.INFO); |
| 771 } | 781 } |
| 772 | 782 |
| 773 void checkValidOverride(Element member, Element superMember) { | 783 void checkValidOverride(Element member, Element superMember) { |
| 774 if (superMember == null) return; | 784 if (superMember == null) return; |
| 775 if (member.modifiers.isStatic()) { | 785 if (member.modifiers.isStatic()) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 ResolverVisitor visitor = | 875 ResolverVisitor visitor = |
| 866 visitorFor(annotation.annotatedElement.enclosingElement); | 876 visitorFor(annotation.annotatedElement.enclosingElement); |
| 867 node.accept(visitor); | 877 node.accept(visitor); |
| 868 annotation.value = compiler.metadataHandler.compileNodeWithDefinitions( | 878 annotation.value = compiler.metadataHandler.compileNodeWithDefinitions( |
| 869 node, visitor.mapping, isConst: true); | 879 node, visitor.mapping, isConst: true); |
| 870 | 880 |
| 871 annotation.resolutionState = STATE_DONE; | 881 annotation.resolutionState = STATE_DONE; |
| 872 })); | 882 })); |
| 873 } | 883 } |
| 874 | 884 |
| 875 error(Node node, MessageKind kind, [arguments = const []]) { | 885 error(Node node, MessageKind kind, [arguments = const {}]) { |
| 876 ResolutionError message = new ResolutionError(kind, arguments); | 886 ResolutionError message = new ResolutionError(kind, arguments); |
| 877 compiler.reportError(node, message); | 887 compiler.reportError(node, message); |
| 878 } | 888 } |
| 879 } | 889 } |
| 880 | 890 |
| 881 class InitializerResolver { | 891 class InitializerResolver { |
| 882 final ResolverVisitor visitor; | 892 final ResolverVisitor visitor; |
| 883 final Map<SourceString, Node> initialized; | 893 final Map<SourceString, Node> initialized; |
| 884 Link<Node> initializers; | 894 Link<Node> initializers; |
| 885 bool hasSuper; | 895 bool hasSuper; |
| 886 | 896 |
| 887 InitializerResolver(this.visitor) | 897 InitializerResolver(this.visitor) |
| 888 : initialized = new Map<SourceString, Node>(), hasSuper = false; | 898 : initialized = new Map<SourceString, Node>(), hasSuper = false; |
| 889 | 899 |
| 890 error(Node node, MessageKind kind, [arguments = const []]) { | 900 error(Node node, MessageKind kind, [arguments = const {}]) { |
| 891 visitor.error(node, kind, arguments); | 901 visitor.error(node, kind, arguments); |
| 892 } | 902 } |
| 893 | 903 |
| 894 warning(Node node, MessageKind kind, [arguments = const []]) { | 904 warning(Node node, MessageKind kind, [arguments = const {}]) { |
| 895 visitor.warning(node, kind, arguments); | 905 visitor.warning(node, kind, arguments); |
| 896 } | 906 } |
| 897 | 907 |
| 898 bool isFieldInitializer(SendSet node) { | 908 bool isFieldInitializer(SendSet node) { |
| 899 if (node.selector.asIdentifier() == null) return false; | 909 if (node.selector.asIdentifier() == null) return false; |
| 900 if (node.receiver == null) return true; | 910 if (node.receiver == null) return true; |
| 901 if (node.receiver.asIdentifier() == null) return false; | 911 if (node.receiver.asIdentifier() == null) return false; |
| 902 return node.receiver.asIdentifier().isThis(); | 912 return node.receiver.asIdentifier().isThis(); |
| 903 } | 913 } |
| 904 | 914 |
| 905 void checkForDuplicateInitializers(SourceString name, Node init) { | 915 void checkForDuplicateInitializers(SourceString name, Node init) { |
| 906 if (initialized.containsKey(name)) { | 916 if (initialized.containsKey(name)) { |
| 907 error(init, MessageKind.DUPLICATE_INITIALIZER, [name]); | 917 error(init, MessageKind.DUPLICATE_INITIALIZER, {'fieldName': name}); |
| 908 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, [name]); | 918 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, |
| 919 {'fieldName': name}); |
| 909 } | 920 } |
| 910 initialized[name] = init; | 921 initialized[name] = init; |
| 911 } | 922 } |
| 912 | 923 |
| 913 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { | 924 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { |
| 914 // init is of the form [this.]field = value. | 925 // init is of the form [this.]field = value. |
| 915 final Node selector = init.selector; | 926 final Node selector = init.selector; |
| 916 final SourceString name = selector.asIdentifier().source; | 927 final SourceString name = selector.asIdentifier().source; |
| 917 // Lookup target field. | 928 // Lookup target field. |
| 918 Element target; | 929 Element target; |
| 919 if (isFieldInitializer(init)) { | 930 if (isFieldInitializer(init)) { |
| 920 target = constructor.getEnclosingClass().lookupLocalMember(name); | 931 target = constructor.getEnclosingClass().lookupLocalMember(name); |
| 921 if (target == null) { | 932 if (target == null) { |
| 922 error(selector, MessageKind.CANNOT_RESOLVE, [name]); | 933 error(selector, MessageKind.CANNOT_RESOLVE, {'name': name}); |
| 923 } else if (target.kind != ElementKind.FIELD) { | 934 } else if (target.kind != ElementKind.FIELD) { |
| 924 error(selector, MessageKind.NOT_A_FIELD, [name]); | 935 error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name}); |
| 925 } else if (!target.isInstanceMember()) { | 936 } else if (!target.isInstanceMember()) { |
| 926 error(selector, MessageKind.INIT_STATIC_FIELD, [name]); | 937 error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name}); |
| 927 } | 938 } |
| 928 } else { | 939 } else { |
| 929 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); | 940 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); |
| 930 } | 941 } |
| 931 visitor.useElement(init, target); | 942 visitor.useElement(init, target); |
| 932 visitor.world.registerStaticUse(target); | 943 visitor.world.registerStaticUse(target); |
| 933 checkForDuplicateInitializers(name, init); | 944 checkForDuplicateInitializers(name, init); |
| 934 // Resolve initializing value. | 945 // Resolve initializing value. |
| 935 visitor.visitInStaticContext(init.arguments.head); | 946 visitor.visitInStaticContext(init.arguments.head); |
| 936 } | 947 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 Selector constructorSelector) { | 1040 Selector constructorSelector) { |
| 1030 if (lookedupConstructor == null | 1041 if (lookedupConstructor == null |
| 1031 || !lookedupConstructor.isGenerativeConstructor()) { | 1042 || !lookedupConstructor.isGenerativeConstructor()) { |
| 1032 var fullConstructorName = | 1043 var fullConstructorName = |
| 1033 visitor.compiler.resolver.constructorNameForDiagnostics( | 1044 visitor.compiler.resolver.constructorNameForDiagnostics( |
| 1034 className, | 1045 className, |
| 1035 constructorSelector.name); | 1046 constructorSelector.name); |
| 1036 MessageKind kind = isImplicitSuperCall | 1047 MessageKind kind = isImplicitSuperCall |
| 1037 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT | 1048 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT |
| 1038 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; | 1049 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; |
| 1039 error(diagnosticNode, kind, [fullConstructorName]); | 1050 error(diagnosticNode, kind, {'constructorName': fullConstructorName}); |
| 1040 } else { | 1051 } else { |
| 1041 if (!call.applies(lookedupConstructor, visitor.compiler)) { | 1052 if (!call.applies(lookedupConstructor, visitor.compiler)) { |
| 1042 MessageKind kind = isImplicitSuperCall | 1053 MessageKind kind = isImplicitSuperCall |
| 1043 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT | 1054 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT |
| 1044 : MessageKind.NO_MATCHING_CONSTRUCTOR; | 1055 : MessageKind.NO_MATCHING_CONSTRUCTOR; |
| 1045 error(diagnosticNode, kind); | 1056 error(diagnosticNode, kind); |
| 1046 } | 1057 } |
| 1047 } | 1058 } |
| 1048 } | 1059 } |
| 1049 | 1060 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 R visitNode(Node node) { | 1139 R visitNode(Node node) { |
| 1129 cancel(node, | 1140 cancel(node, |
| 1130 'internal error: Unhandled node: ${node.getObjectDescription()}'); | 1141 'internal error: Unhandled node: ${node.getObjectDescription()}'); |
| 1131 } | 1142 } |
| 1132 | 1143 |
| 1133 R visitEmptyStatement(Node node) => null; | 1144 R visitEmptyStatement(Node node) => null; |
| 1134 | 1145 |
| 1135 /** Convenience method for visiting nodes that may be null. */ | 1146 /** Convenience method for visiting nodes that may be null. */ |
| 1136 R visit(Node node) => (node == null) ? null : node.accept(this); | 1147 R visit(Node node) => (node == null) ? null : node.accept(this); |
| 1137 | 1148 |
| 1138 void error(Node node, MessageKind kind, [arguments = const []]) { | 1149 void error(Node node, MessageKind kind, [Map arguments = const {}]) { |
| 1139 ResolutionError message = new ResolutionError(kind, arguments); | 1150 ResolutionError message = new ResolutionError(kind, arguments); |
| 1140 compiler.reportError(node, message); | 1151 compiler.reportError(node, message); |
| 1141 } | 1152 } |
| 1142 | 1153 |
| 1143 void warning(Node node, MessageKind kind, [arguments = const []]) { | 1154 void warning(Node node, MessageKind kind, [Map arguments = const {}]) { |
| 1144 ResolutionWarning message = new ResolutionWarning(kind, arguments); | 1155 ResolutionWarning message = new ResolutionWarning(kind, arguments); |
| 1145 compiler.reportWarning(node, message); | 1156 compiler.reportWarning(node, message); |
| 1146 } | 1157 } |
| 1147 | 1158 |
| 1148 void cancel(Node node, String message) { | 1159 void cancel(Node node, String message) { |
| 1149 compiler.cancel(message, node: node); | 1160 compiler.cancel(message, node: node); |
| 1150 } | 1161 } |
| 1151 | 1162 |
| 1152 void internalError(Node node, String message) { | 1163 void internalError(Node node, String message) { |
| 1153 compiler.internalError(message, node: node); | 1164 compiler.internalError(message, node: node); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1293 } | 1304 } |
| 1294 } | 1305 } |
| 1295 } | 1306 } |
| 1296 | 1307 |
| 1297 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean | 1308 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean |
| 1298 // flags instead of closures. | 1309 // flags instead of closures. |
| 1299 DartType resolveTypeAnnotation( | 1310 DartType resolveTypeAnnotation( |
| 1300 TypeAnnotation node, | 1311 TypeAnnotation node, |
| 1301 Scope scope, | 1312 Scope scope, |
| 1302 Element enclosingElement, | 1313 Element enclosingElement, |
| 1303 {onFailure(Node node, MessageKind kind, [List arguments]), | 1314 {onFailure(Node node, MessageKind kind, [Map arguments]), |
| 1304 whenResolved(Node node, DartType type)}) { | 1315 whenResolved(Node node, DartType type)}) { |
| 1305 if (onFailure == null) { | 1316 if (onFailure == null) { |
| 1306 onFailure = (n, k, [arguments]) {}; | 1317 onFailure = (n, k, [arguments]) {}; |
| 1307 } | 1318 } |
| 1308 if (whenResolved == null) { | 1319 if (whenResolved == null) { |
| 1309 whenResolved = (n, t) {}; | 1320 whenResolved = (n, t) {}; |
| 1310 } | 1321 } |
| 1311 if (scope == null) { | 1322 if (scope == null) { |
| 1312 compiler.internalError('resolveTypeAnnotation: no scope specified'); | 1323 compiler.internalError('resolveTypeAnnotation: no scope specified'); |
| 1313 } | 1324 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1326 prefixName = send.receiver.asIdentifier().source; | 1337 prefixName = send.receiver.asIdentifier().source; |
| 1327 typeName = send.selector.asIdentifier(); | 1338 typeName = send.selector.asIdentifier(); |
| 1328 } else { | 1339 } else { |
| 1329 typeName = node.typeName.asIdentifier(); | 1340 typeName = node.typeName.asIdentifier(); |
| 1330 } | 1341 } |
| 1331 | 1342 |
| 1332 Element element = resolveTypeName(scope, prefixName, typeName); | 1343 Element element = resolveTypeName(scope, prefixName, typeName); |
| 1333 DartType type; | 1344 DartType type; |
| 1334 | 1345 |
| 1335 DartType reportFailureAndCreateType(MessageKind messageKind, | 1346 DartType reportFailureAndCreateType(MessageKind messageKind, |
| 1336 List messageArguments) { | 1347 Map messageArguments) { |
| 1337 onFailure(node, messageKind, messageArguments); | 1348 onFailure(node, messageKind, messageArguments); |
| 1338 var erroneousElement = new ErroneousElementX( | 1349 var erroneousElement = new ErroneousElementX( |
| 1339 messageKind, messageArguments, typeName.source, enclosingElement); | 1350 messageKind, messageArguments, typeName.source, enclosingElement); |
| 1340 var arguments = new LinkBuilder<DartType>(); | 1351 var arguments = new LinkBuilder<DartType>(); |
| 1341 resolveTypeArguments( | 1352 resolveTypeArguments( |
| 1342 node, null, enclosingElement, | 1353 node, null, enclosingElement, |
| 1343 scope, onFailure, whenResolved, arguments); | 1354 scope, onFailure, whenResolved, arguments); |
| 1344 return new MalformedType(erroneousElement, null, arguments.toLink()); | 1355 return new MalformedType(erroneousElement, null, arguments.toLink()); |
| 1345 } | 1356 } |
| 1346 | 1357 |
| 1347 DartType checkNoTypeArguments(DartType type) { | 1358 DartType checkNoTypeArguments(DartType type) { |
| 1348 var arguments = new LinkBuilder<DartType>(); | 1359 var arguments = new LinkBuilder<DartType>(); |
| 1349 bool hashTypeArgumentMismatch = resolveTypeArguments( | 1360 bool hashTypeArgumentMismatch = resolveTypeArguments( |
| 1350 node, const Link<DartType>(), enclosingElement, | 1361 node, const Link<DartType>(), enclosingElement, |
| 1351 scope, onFailure, whenResolved, arguments); | 1362 scope, onFailure, whenResolved, arguments); |
| 1352 if (hashTypeArgumentMismatch) { | 1363 if (hashTypeArgumentMismatch) { |
| 1353 type = new MalformedType( | 1364 type = new MalformedType( |
| 1354 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1365 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
| 1355 [node], typeName.source, enclosingElement), | 1366 {'type': node}, typeName.source, enclosingElement), |
| 1356 type, arguments.toLink()); | 1367 type, arguments.toLink()); |
| 1357 } | 1368 } |
| 1358 return type; | 1369 return type; |
| 1359 } | 1370 } |
| 1360 | 1371 |
| 1361 if (element == null) { | 1372 if (element == null) { |
| 1362 type = reportFailureAndCreateType( | 1373 type = reportFailureAndCreateType( |
| 1363 MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); | 1374 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); |
| 1364 } else if (element.isAmbiguous()) { | 1375 } else if (element.isAmbiguous()) { |
| 1365 AmbiguousElement ambiguous = element; | 1376 AmbiguousElement ambiguous = element; |
| 1366 type = reportFailureAndCreateType( | 1377 type = reportFailureAndCreateType( |
| 1367 ambiguous.messageKind, ambiguous.messageArguments); | 1378 ambiguous.messageKind, ambiguous.messageArguments); |
| 1368 } else if (!element.impliesType()) { | 1379 } else if (!element.impliesType()) { |
| 1369 type = reportFailureAndCreateType( | 1380 type = reportFailureAndCreateType( |
| 1370 MessageKind.NOT_A_TYPE, [node.typeName]); | 1381 MessageKind.NOT_A_TYPE, {'node': node.typeName}); |
| 1371 } else { | 1382 } else { |
| 1372 if (identical(element, compiler.types.voidType.element) || | 1383 if (identical(element, compiler.types.voidType.element) || |
| 1373 identical(element, compiler.types.dynamicType.element)) { | 1384 identical(element, compiler.types.dynamicType.element)) { |
| 1374 type = checkNoTypeArguments(element.computeType(compiler)); | 1385 type = checkNoTypeArguments(element.computeType(compiler)); |
| 1375 } else if (element.isClass()) { | 1386 } else if (element.isClass()) { |
| 1376 ClassElement cls = element; | 1387 ClassElement cls = element; |
| 1377 compiler.resolver._ensureClassWillBeResolved(cls); | 1388 compiler.resolver._ensureClassWillBeResolved(cls); |
| 1378 element.computeType(compiler); | 1389 element.computeType(compiler); |
| 1379 var arguments = new LinkBuilder<DartType>(); | 1390 var arguments = new LinkBuilder<DartType>(); |
| 1380 bool hashTypeArgumentMismatch = resolveTypeArguments( | 1391 bool hashTypeArgumentMismatch = resolveTypeArguments( |
| 1381 node, cls.typeVariables, enclosingElement, | 1392 node, cls.typeVariables, enclosingElement, |
| 1382 scope, onFailure, whenResolved, arguments); | 1393 scope, onFailure, whenResolved, arguments); |
| 1383 if (hashTypeArgumentMismatch) { | 1394 if (hashTypeArgumentMismatch) { |
| 1384 type = new MalformedType( | 1395 type = new MalformedType( |
| 1385 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1396 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
| 1386 [node], typeName.source, enclosingElement), | 1397 {'type': node}, typeName.source, enclosingElement), |
| 1387 new InterfaceType(cls.declaration, arguments.toLink())); | 1398 new InterfaceType(cls.declaration, arguments.toLink())); |
| 1388 } else { | 1399 } else { |
| 1389 if (arguments.isEmpty) { | 1400 if (arguments.isEmpty) { |
| 1390 type = cls.rawType; | 1401 type = cls.rawType; |
| 1391 } else { | 1402 } else { |
| 1392 type = new InterfaceType(cls.declaration, arguments.toLink()); | 1403 type = new InterfaceType(cls.declaration, arguments.toLink()); |
| 1393 } | 1404 } |
| 1394 } | 1405 } |
| 1395 } else if (element.isTypedef()) { | 1406 } else if (element.isTypedef()) { |
| 1396 TypedefElement typdef = element; | 1407 TypedefElement typdef = element; |
| 1397 // TODO(ahe): Should be [ensureResolved]. | 1408 // TODO(ahe): Should be [ensureResolved]. |
| 1398 compiler.resolveTypedef(typdef); | 1409 compiler.resolveTypedef(typdef); |
| 1399 var arguments = new LinkBuilder<DartType>(); | 1410 var arguments = new LinkBuilder<DartType>(); |
| 1400 bool hashTypeArgumentMismatch = resolveTypeArguments( | 1411 bool hashTypeArgumentMismatch = resolveTypeArguments( |
| 1401 node, typdef.typeVariables, enclosingElement, | 1412 node, typdef.typeVariables, enclosingElement, |
| 1402 scope, onFailure, whenResolved, arguments); | 1413 scope, onFailure, whenResolved, arguments); |
| 1403 if (hashTypeArgumentMismatch) { | 1414 if (hashTypeArgumentMismatch) { |
| 1404 type = new MalformedType( | 1415 type = new MalformedType( |
| 1405 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1416 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
| 1406 [node], typeName.source, enclosingElement), | 1417 {'type': node}, typeName.source, enclosingElement), |
| 1407 new TypedefType(typdef, arguments.toLink())); | 1418 new TypedefType(typdef, arguments.toLink())); |
| 1408 } else { | 1419 } else { |
| 1409 if (arguments.isEmpty) { | 1420 if (arguments.isEmpty) { |
| 1410 type = typdef.rawType; | 1421 type = typdef.rawType; |
| 1411 } else { | 1422 } else { |
| 1412 type = new TypedefType(typdef, arguments.toLink()); | 1423 type = new TypedefType(typdef, arguments.toLink()); |
| 1413 } | 1424 } |
| 1414 } | 1425 } |
| 1415 } else if (element.isTypeVariable()) { | 1426 } else if (element.isTypeVariable()) { |
| 1416 if (enclosingElement.isInStaticMember()) { | 1427 if (enclosingElement.isInStaticMember()) { |
| 1417 compiler.reportWarning(node, | 1428 compiler.reportWarning(node, |
| 1418 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message( | 1429 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message( |
| 1419 [node])); | 1430 {'typeVariableName': node})); |
| 1420 type = new MalformedType( | 1431 type = new MalformedType( |
| 1421 new ErroneousElementX( | 1432 new ErroneousElementX( |
| 1422 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 1433 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
| 1423 [node], typeName.source, enclosingElement), | 1434 {'typeVariableName': node}, |
| 1435 typeName.source, enclosingElement), |
| 1424 element.computeType(compiler)); | 1436 element.computeType(compiler)); |
| 1425 } else { | 1437 } else { |
| 1426 type = element.computeType(compiler); | 1438 type = element.computeType(compiler); |
| 1427 } | 1439 } |
| 1428 type = checkNoTypeArguments(type); | 1440 type = checkNoTypeArguments(type); |
| 1429 } else { | 1441 } else { |
| 1430 compiler.cancel("unexpected element kind ${element.kind}", | 1442 compiler.cancel("unexpected element kind ${element.kind}", |
| 1431 node: node); | 1443 node: node); |
| 1432 } | 1444 } |
| 1433 } | 1445 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 inCatchBlock = false, | 1526 inCatchBlock = false, |
| 1515 super(compiler); | 1527 super(compiler); |
| 1516 | 1528 |
| 1517 ResolutionEnqueuer get world => compiler.enqueuer.resolution; | 1529 ResolutionEnqueuer get world => compiler.enqueuer.resolution; |
| 1518 | 1530 |
| 1519 Element lookup(Node node, SourceString name) { | 1531 Element lookup(Node node, SourceString name) { |
| 1520 Element result = scope.lookup(name); | 1532 Element result = scope.lookup(name); |
| 1521 if (!Elements.isUnresolved(result)) { | 1533 if (!Elements.isUnresolved(result)) { |
| 1522 if (!inInstanceContext && result.isInstanceMember()) { | 1534 if (!inInstanceContext && result.isInstanceMember()) { |
| 1523 compiler.reportMessage(compiler.spanFromSpannable(node), | 1535 compiler.reportMessage(compiler.spanFromSpannable(node), |
| 1524 MessageKind.NO_INSTANCE_AVAILABLE.error([name]), | 1536 MessageKind.NO_INSTANCE_AVAILABLE.error({'name': name}), |
| 1525 Diagnostic.ERROR); | 1537 Diagnostic.ERROR); |
| 1526 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, | 1538 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, |
| 1527 [name], | 1539 {'name': name}, |
| 1528 name, enclosingElement); | 1540 name, enclosingElement); |
| 1529 } else if (result.isAmbiguous()) { | 1541 } else if (result.isAmbiguous()) { |
| 1530 AmbiguousElement ambiguous = result; | 1542 AmbiguousElement ambiguous = result; |
| 1531 compiler.reportMessage(compiler.spanFromSpannable(node), | 1543 compiler.reportMessage(compiler.spanFromSpannable(node), |
| 1532 ambiguous.messageKind.error(ambiguous.messageArguments), | 1544 ambiguous.messageKind.error(ambiguous.messageArguments), |
| 1533 Diagnostic.ERROR); | 1545 Diagnostic.ERROR); |
| 1534 return new ErroneousElementX(ambiguous.messageKind, | 1546 return new ErroneousElementX(ambiguous.messageKind, |
| 1535 ambiguous.messageArguments, | 1547 ambiguous.messageArguments, |
| 1536 name, enclosingElement); | 1548 name, enclosingElement); |
| 1537 } | 1549 } |
| 1538 } | 1550 } |
| 1539 return result; | 1551 return result; |
| 1540 } | 1552 } |
| 1541 | 1553 |
| 1542 // Create, or reuse an already created, statement element for a statement. | 1554 // Create, or reuse an already created, statement element for a statement. |
| 1543 TargetElement getOrCreateTargetElement(Node statement) { | 1555 TargetElement getOrCreateTargetElement(Node statement) { |
| 1544 TargetElement element = mapping[statement]; | 1556 TargetElement element = mapping[statement]; |
| 1545 if (element == null) { | 1557 if (element == null) { |
| 1546 element = new TargetElementX(statement, | 1558 element = new TargetElementX(statement, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1567 return result; | 1579 return result; |
| 1568 } | 1580 } |
| 1569 | 1581 |
| 1570 visitInStaticContext(Node node) { | 1582 visitInStaticContext(Node node) { |
| 1571 inStaticContext(() => visit(node)); | 1583 inStaticContext(() => visit(node)); |
| 1572 } | 1584 } |
| 1573 | 1585 |
| 1574 ErroneousElement warnAndCreateErroneousElement(Node node, | 1586 ErroneousElement warnAndCreateErroneousElement(Node node, |
| 1575 SourceString name, | 1587 SourceString name, |
| 1576 MessageKind kind, | 1588 MessageKind kind, |
| 1577 List<Node> arguments) { | 1589 [Map arguments = const {}]) { |
| 1578 ResolutionWarning warning = new ResolutionWarning(kind, arguments); | 1590 ResolutionWarning warning = new ResolutionWarning(kind, arguments); |
| 1579 compiler.reportWarning(node, warning); | 1591 compiler.reportWarning(node, warning); |
| 1580 return new ErroneousElementX(kind, arguments, name, enclosingElement); | 1592 return new ErroneousElementX(kind, arguments, name, enclosingElement); |
| 1581 } | 1593 } |
| 1582 | 1594 |
| 1583 Element visitIdentifier(Identifier node) { | 1595 Element visitIdentifier(Identifier node) { |
| 1584 if (node.isThis()) { | 1596 if (node.isThis()) { |
| 1585 if (!inInstanceContext) { | 1597 if (!inInstanceContext) { |
| 1586 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); | 1598 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); |
| 1587 } | 1599 } |
| 1588 return null; | 1600 return null; |
| 1589 } else if (node.isSuper()) { | 1601 } else if (node.isSuper()) { |
| 1590 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC); | 1602 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC); |
| 1591 if ((ElementCategory.SUPER & allowedCategory) == 0) { | 1603 if ((ElementCategory.SUPER & allowedCategory) == 0) { |
| 1592 error(node, MessageKind.INVALID_USE_OF_SUPER); | 1604 error(node, MessageKind.INVALID_USE_OF_SUPER); |
| 1593 } | 1605 } |
| 1594 return null; | 1606 return null; |
| 1595 } else { | 1607 } else { |
| 1596 Element element = lookup(node, node.source); | 1608 Element element = lookup(node, node.source); |
| 1597 if (element == null) { | 1609 if (element == null) { |
| 1598 if (!inInstanceContext) { | 1610 if (!inInstanceContext) { |
| 1599 element = warnAndCreateErroneousElement(node, node.source, | 1611 element = warnAndCreateErroneousElement(node, node.source, |
| 1600 MessageKind.CANNOT_RESOLVE, | 1612 MessageKind.CANNOT_RESOLVE, |
| 1601 [node]); | 1613 {'name': node}); |
| 1602 } | 1614 } |
| 1603 } else if (element.isErroneous()) { | 1615 } else if (element.isErroneous()) { |
| 1604 // Use the erroneous element. | 1616 // Use the erroneous element. |
| 1605 } else { | 1617 } else { |
| 1606 if ((element.kind.category & allowedCategory) == 0) { | 1618 if ((element.kind.category & allowedCategory) == 0) { |
| 1607 // TODO(ahe): Improve error message. Need UX input. | 1619 // TODO(ahe): Improve error message. Need UX input. |
| 1608 error(node, MessageKind.GENERIC, ["is not an expression $element"]); | 1620 error(node, MessageKind.GENERIC, |
| 1621 {'text': "is not an expression $element"}); |
| 1609 } | 1622 } |
| 1610 } | 1623 } |
| 1611 if (!Elements.isUnresolved(element) | 1624 if (!Elements.isUnresolved(element) |
| 1612 && element.kind == ElementKind.CLASS) { | 1625 && element.kind == ElementKind.CLASS) { |
| 1613 ClassElement classElement = element; | 1626 ClassElement classElement = element; |
| 1614 classElement.ensureResolved(compiler); | 1627 classElement.ensureResolved(compiler); |
| 1615 } | 1628 } |
| 1616 return useElement(node, element); | 1629 return useElement(node, element); |
| 1617 } | 1630 } |
| 1618 } | 1631 } |
| 1619 | 1632 |
| 1620 Element visitTypeAnnotation(TypeAnnotation node) { | 1633 Element visitTypeAnnotation(TypeAnnotation node) { |
| 1621 DartType type = resolveTypeAnnotation(node); | 1634 DartType type = resolveTypeAnnotation(node); |
| 1622 if (type != null) { | 1635 if (type != null) { |
| 1623 if (inCheckContext) { | 1636 if (inCheckContext) { |
| 1624 compiler.enqueuer.resolution.registerIsCheck(type); | 1637 compiler.enqueuer.resolution.registerIsCheck(type); |
| 1625 } | 1638 } |
| 1626 return type.element; | 1639 return type.element; |
| 1627 } | 1640 } |
| 1628 return null; | 1641 return null; |
| 1629 } | 1642 } |
| 1630 | 1643 |
| 1631 Element defineElement(Node node, Element element, | 1644 Element defineElement(Node node, Element element, |
| 1632 {bool doAddToScope: true}) { | 1645 {bool doAddToScope: true}) { |
| 1633 compiler.ensure(element != null); | 1646 compiler.ensure(element != null); |
| 1634 mapping[node] = element; | 1647 mapping[node] = element; |
| 1635 if (doAddToScope) { | 1648 if (doAddToScope) { |
| 1636 Element existing = scope.add(element); | 1649 Element existing = scope.add(element); |
| 1637 if (existing != element) { | 1650 if (existing != element) { |
| 1638 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); | 1651 error(node, MessageKind.DUPLICATE_DEFINITION, {'name': node}); |
| 1639 } | 1652 } |
| 1640 } | 1653 } |
| 1641 return element; | 1654 return element; |
| 1642 } | 1655 } |
| 1643 | 1656 |
| 1644 Element useElement(Node node, Element element) { | 1657 Element useElement(Node node, Element element) { |
| 1645 if (element == null) return null; | 1658 if (element == null) return null; |
| 1646 return mapping[node] = element; | 1659 return mapping[node] = element; |
| 1647 } | 1660 } |
| 1648 | 1661 |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1826 Selector selector = resolveSelector(node); | 1839 Selector selector = resolveSelector(node); |
| 1827 if (node.isSuperCall) mapping.superUses.add(node); | 1840 if (node.isSuperCall) mapping.superUses.add(node); |
| 1828 | 1841 |
| 1829 if (node.receiver == null) { | 1842 if (node.receiver == null) { |
| 1830 // If this send is of the form "assert(expr);", then | 1843 // If this send is of the form "assert(expr);", then |
| 1831 // this is an assertion. | 1844 // this is an assertion. |
| 1832 if (selector.isAssert()) { | 1845 if (selector.isAssert()) { |
| 1833 if (selector.argumentCount != 1) { | 1846 if (selector.argumentCount != 1) { |
| 1834 error(node.selector, | 1847 error(node.selector, |
| 1835 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT, | 1848 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT, |
| 1836 [selector.argumentCount]); | 1849 {'argumentCount': selector.argumentCount}); |
| 1837 } else if (selector.namedArgumentCount != 0) { | 1850 } else if (selector.namedArgumentCount != 0) { |
| 1838 error(node.selector, | 1851 error(node.selector, |
| 1839 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS, | 1852 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS, |
| 1840 [selector.namedArgumentCount]); | 1853 {'argumentCount': selector.namedArgumentCount}); |
| 1841 } | 1854 } |
| 1842 return compiler.assertMethod; | 1855 return compiler.assertMethod; |
| 1843 } | 1856 } |
| 1844 | 1857 |
| 1845 return node.selector.accept(this); | 1858 return node.selector.accept(this); |
| 1846 } | 1859 } |
| 1847 | 1860 |
| 1848 var oldCategory = allowedCategory; | 1861 var oldCategory = allowedCategory; |
| 1849 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER; | 1862 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER; |
| 1850 Element resolvedReceiver = visit(node.receiver); | 1863 Element resolvedReceiver = visit(node.receiver); |
| 1851 allowedCategory = oldCategory; | 1864 allowedCategory = oldCategory; |
| 1852 | 1865 |
| 1853 Element target; | 1866 Element target; |
| 1854 SourceString name = node.selector.asIdentifier().source; | 1867 SourceString name = node.selector.asIdentifier().source; |
| 1855 if (identical(name.stringValue, 'this')) { | 1868 if (identical(name.stringValue, 'this')) { |
| 1856 error(node.selector, MessageKind.GENERIC, ["expected an identifier"]); | 1869 error(node.selector, MessageKind.GENERIC, |
| 1870 {'text': "expected an identifier"}); |
| 1857 } else if (node.isSuperCall) { | 1871 } else if (node.isSuperCall) { |
| 1858 if (node.isOperator) { | 1872 if (node.isOperator) { |
| 1859 if (isUserDefinableOperator(name.stringValue)) { | 1873 if (isUserDefinableOperator(name.stringValue)) { |
| 1860 name = selector.name; | 1874 name = selector.name; |
| 1861 } else { | 1875 } else { |
| 1862 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, [name]); | 1876 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name}); |
| 1863 } | 1877 } |
| 1864 } | 1878 } |
| 1865 if (!inInstanceContext) { | 1879 if (!inInstanceContext) { |
| 1866 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, [name]); | 1880 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
| 1867 return null; | 1881 return null; |
| 1868 } | 1882 } |
| 1869 if (currentClass.supertype == null) { | 1883 if (currentClass.supertype == null) { |
| 1870 // This is just to guard against internal errors, so no need | 1884 // This is just to guard against internal errors, so no need |
| 1871 // for a real error message. | 1885 // for a real error message. |
| 1872 error(node.receiver, MessageKind.GENERIC, ["Object has no superclass"]); | 1886 error(node.receiver, MessageKind.GENERIC, |
| 1887 {'text': "Object has no superclass"}); |
| 1873 } | 1888 } |
| 1874 // TODO(johnniwinther): Ensure correct behavior if currentClass is a | 1889 // TODO(johnniwinther): Ensure correct behavior if currentClass is a |
| 1875 // patch. | 1890 // patch. |
| 1876 target = currentClass.lookupSuperMember(name); | 1891 target = currentClass.lookupSuperMember(name); |
| 1877 // [target] may be null which means invoking noSuchMethod on | 1892 // [target] may be null which means invoking noSuchMethod on |
| 1878 // super. | 1893 // super. |
| 1879 } else if (Elements.isUnresolved(resolvedReceiver)) { | 1894 } else if (Elements.isUnresolved(resolvedReceiver)) { |
| 1880 return null; | 1895 return null; |
| 1881 } else if (identical(resolvedReceiver.kind, ElementKind.CLASS)) { | 1896 } else if (identical(resolvedReceiver.kind, ElementKind.CLASS)) { |
| 1882 ClassElement receiverClass = resolvedReceiver; | 1897 ClassElement receiverClass = resolvedReceiver; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1894 if (target == null) { | 1909 if (target == null) { |
| 1895 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1910 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| 1896 // try to resolve injected elements if [currentClass] is in the patch | 1911 // try to resolve injected elements if [currentClass] is in the patch |
| 1897 // library of [receiverClass]. | 1912 // library of [receiverClass]. |
| 1898 | 1913 |
| 1899 // TODO(karlklose): this should be reported by the caller of | 1914 // TODO(karlklose): this should be reported by the caller of |
| 1900 // [resolveSend] to select better warning messages for getters and | 1915 // [resolveSend] to select better warning messages for getters and |
| 1901 // setters. | 1916 // setters. |
| 1902 return warnAndCreateErroneousElement(node, name, | 1917 return warnAndCreateErroneousElement(node, name, |
| 1903 MessageKind.METHOD_NOT_FOUND, | 1918 MessageKind.METHOD_NOT_FOUND, |
| 1904 [receiverClass.name, name]); | 1919 {'className': receiverClass.name, |
| 1920 'methodName': name}); |
| 1905 } else if (target.isInstanceMember()) { | 1921 } else if (target.isInstanceMember()) { |
| 1906 error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]); | 1922 error(node, MessageKind.MEMBER_NOT_STATIC, |
| 1923 {'className': receiverClass.name, |
| 1924 'memberName': name}); |
| 1907 } | 1925 } |
| 1908 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { | 1926 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { |
| 1909 PrefixElement prefix = resolvedReceiver; | 1927 PrefixElement prefix = resolvedReceiver; |
| 1910 target = prefix.lookupLocalMember(name); | 1928 target = prefix.lookupLocalMember(name); |
| 1911 if (Elements.isUnresolved(target)) { | 1929 if (Elements.isUnresolved(target)) { |
| 1912 return warnAndCreateErroneousElement( | 1930 return warnAndCreateErroneousElement( |
| 1913 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 1931 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
| 1914 [prefix.name, name]); | 1932 {'libraryName': prefix.name, 'memberName': name}); |
| 1915 } else if (target.kind == ElementKind.CLASS) { | 1933 } else if (target.kind == ElementKind.CLASS) { |
| 1916 ClassElement classElement = target; | 1934 ClassElement classElement = target; |
| 1917 classElement.ensureResolved(compiler); | 1935 classElement.ensureResolved(compiler); |
| 1918 } | 1936 } |
| 1919 } | 1937 } |
| 1920 return target; | 1938 return target; |
| 1921 } | 1939 } |
| 1922 | 1940 |
| 1923 DartType resolveTypeTest(Node argument) { | 1941 DartType resolveTypeTest(Node argument) { |
| 1924 TypeAnnotation node = argument.asTypeAnnotation(); | 1942 TypeAnnotation node = argument.asTypeAnnotation(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1996 if (list == null) return; | 2014 if (list == null) return; |
| 1997 List<SourceString> seenNamedArguments = <SourceString>[]; | 2015 List<SourceString> seenNamedArguments = <SourceString>[]; |
| 1998 for (Link<Node> link = list.nodes; !link.isEmpty; link = link.tail) { | 2016 for (Link<Node> link = list.nodes; !link.isEmpty; link = link.tail) { |
| 1999 Expression argument = link.head; | 2017 Expression argument = link.head; |
| 2000 visit(argument); | 2018 visit(argument); |
| 2001 NamedArgument namedArgument = argument.asNamedArgument(); | 2019 NamedArgument namedArgument = argument.asNamedArgument(); |
| 2002 if (namedArgument != null) { | 2020 if (namedArgument != null) { |
| 2003 SourceString source = namedArgument.name.source; | 2021 SourceString source = namedArgument.name.source; |
| 2004 if (seenNamedArguments.contains(source)) { | 2022 if (seenNamedArguments.contains(source)) { |
| 2005 error(argument, MessageKind.DUPLICATE_DEFINITION, | 2023 error(argument, MessageKind.DUPLICATE_DEFINITION, |
| 2006 [source.slowToString()]); | 2024 {'name': source}); |
| 2007 } | 2025 } |
| 2008 seenNamedArguments.add(source); | 2026 seenNamedArguments.add(source); |
| 2009 } else if (!seenNamedArguments.isEmpty) { | 2027 } else if (!seenNamedArguments.isEmpty) { |
| 2010 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); | 2028 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); |
| 2011 } | 2029 } |
| 2012 } | 2030 } |
| 2013 } | 2031 } |
| 2014 | 2032 |
| 2015 visitSend(Send node) { | 2033 visitSend(Send node) { |
| 2016 Element target = resolveSend(node); | 2034 Element target = resolveSend(node); |
| 2017 if (!Elements.isUnresolved(target) | 2035 if (!Elements.isUnresolved(target) |
| 2018 && target.kind == ElementKind.ABSTRACT_FIELD) { | 2036 && target.kind == ElementKind.ABSTRACT_FIELD) { |
| 2019 AbstractFieldElement field = target; | 2037 AbstractFieldElement field = target; |
| 2020 target = field.getter; | 2038 target = field.getter; |
| 2021 if (target == null && !inInstanceContext) { | 2039 if (target == null && !inInstanceContext) { |
| 2022 target = | 2040 target = |
| 2023 warnAndCreateErroneousElement(node.selector, field.name, | 2041 warnAndCreateErroneousElement(node.selector, field.name, |
| 2024 MessageKind.CANNOT_RESOLVE_GETTER, | 2042 MessageKind.CANNOT_RESOLVE_GETTER); |
| 2025 [node.selector]); | |
| 2026 } | 2043 } |
| 2027 } | 2044 } |
| 2028 | 2045 |
| 2029 bool resolvedArguments = false; | 2046 bool resolvedArguments = false; |
| 2030 if (node.isOperator) { | 2047 if (node.isOperator) { |
| 2031 String operatorString = node.selector.asOperator().source.stringValue; | 2048 String operatorString = node.selector.asOperator().source.stringValue; |
| 2032 if (identical(operatorString, 'is') || identical(operatorString, 'as')) { | 2049 if (identical(operatorString, 'is') || identical(operatorString, 'as')) { |
| 2033 assert(node.arguments.tail.isEmpty); | 2050 assert(node.arguments.tail.isEmpty); |
| 2034 DartType type = resolveTypeTest(node.arguments.head); | 2051 DartType type = resolveTypeTest(node.arguments.head); |
| 2035 if (type != null) { | 2052 if (type != null) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 // It might be the closurization of a method. | 2105 // It might be the closurization of a method. |
| 2089 world.registerInstantiatedClass(compiler.functionClass); | 2106 world.registerInstantiatedClass(compiler.functionClass); |
| 2090 } | 2107 } |
| 2091 return node.isPropertyAccess ? target : null; | 2108 return node.isPropertyAccess ? target : null; |
| 2092 } | 2109 } |
| 2093 | 2110 |
| 2094 void warnArgumentMismatch(Send node, Element target) { | 2111 void warnArgumentMismatch(Send node, Element target) { |
| 2095 // TODO(karlklose): we can be more precise about the reason of the | 2112 // TODO(karlklose): we can be more precise about the reason of the |
| 2096 // mismatch. | 2113 // mismatch. |
| 2097 warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS, | 2114 warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS, |
| 2098 [target.name]); | 2115 {'methodName': target.name}); |
| 2099 } | 2116 } |
| 2100 | 2117 |
| 2101 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. | 2118 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. |
| 2102 DartType resolveTypeFromString(String typeName) { | 2119 DartType resolveTypeFromString(String typeName) { |
| 2103 Element element = scope.lookup(new SourceString(typeName)); | 2120 Element element = scope.lookup(new SourceString(typeName)); |
| 2104 if (element == null) return null; | 2121 if (element == null) return null; |
| 2105 if (element is! ClassElement) return null; | 2122 if (element is! ClassElement) return null; |
| 2106 element.ensureResolved(compiler); | 2123 element.ensureResolved(compiler); |
| 2107 return element.computeType(compiler); | 2124 return element.computeType(compiler); |
| 2108 } | 2125 } |
| 2109 | 2126 |
| 2110 visitSendSet(SendSet node) { | 2127 visitSendSet(SendSet node) { |
| 2111 Element target = resolveSend(node); | 2128 Element target = resolveSend(node); |
| 2112 Element setter = target; | 2129 Element setter = target; |
| 2113 Element getter = target; | 2130 Element getter = target; |
| 2114 SourceString operatorName = node.assignmentOperator.source; | 2131 SourceString operatorName = node.assignmentOperator.source; |
| 2115 String source = operatorName.stringValue; | 2132 String source = operatorName.stringValue; |
| 2116 bool isComplex = !identical(source, '='); | 2133 bool isComplex = !identical(source, '='); |
| 2117 if (!Elements.isUnresolved(target) | 2134 if (!Elements.isUnresolved(target) |
| 2118 && target.kind == ElementKind.ABSTRACT_FIELD) { | 2135 && target.kind == ElementKind.ABSTRACT_FIELD) { |
| 2119 AbstractFieldElement field = target; | 2136 AbstractFieldElement field = target; |
| 2120 setter = field.setter; | 2137 setter = field.setter; |
| 2121 getter = field.getter; | 2138 getter = field.getter; |
| 2122 if (setter == null && !inInstanceContext) { | 2139 if (setter == null && !inInstanceContext) { |
| 2123 setter = | 2140 setter = |
| 2124 warnAndCreateErroneousElement(node.selector, field.name, | 2141 warnAndCreateErroneousElement(node.selector, field.name, |
| 2125 MessageKind.CANNOT_RESOLVE_SETTER, | 2142 MessageKind.CANNOT_RESOLVE_SETTER); |
| 2126 [node.selector]); | |
| 2127 } | 2143 } |
| 2128 if (isComplex && getter == null && !inInstanceContext) { | 2144 if (isComplex && getter == null && !inInstanceContext) { |
| 2129 getter = | 2145 getter = |
| 2130 warnAndCreateErroneousElement(node.selector, field.name, | 2146 warnAndCreateErroneousElement(node.selector, field.name, |
| 2131 MessageKind.CANNOT_RESOLVE_GETTER, | 2147 MessageKind.CANNOT_RESOLVE_GETTER); |
| 2132 [node.selector]); | |
| 2133 } | 2148 } |
| 2134 } | 2149 } |
| 2135 | 2150 |
| 2136 visit(node.argumentsNode); | 2151 visit(node.argumentsNode); |
| 2137 | 2152 |
| 2138 // TODO(ngeoffray): Check if the target can be assigned. | 2153 // TODO(ngeoffray): Check if the target can be assigned. |
| 2139 // TODO(ngeoffray): Warn if target is null and the send is | 2154 // TODO(ngeoffray): Warn if target is null and the send is |
| 2140 // unqualified. | 2155 // unqualified. |
| 2141 | 2156 |
| 2142 Selector selector = mapping.getSelector(node); | 2157 Selector selector = mapping.getSelector(node); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2237 handleRedirectingFactoryBody(node); | 2252 handleRedirectingFactoryBody(node); |
| 2238 } else { | 2253 } else { |
| 2239 visit(node.expression); | 2254 visit(node.expression); |
| 2240 } | 2255 } |
| 2241 } | 2256 } |
| 2242 | 2257 |
| 2243 void handleRedirectingFactoryBody(Return node) { | 2258 void handleRedirectingFactoryBody(Return node) { |
| 2244 if (!enclosingElement.isFactoryConstructor()) { | 2259 if (!enclosingElement.isFactoryConstructor()) { |
| 2245 compiler.reportMessage( | 2260 compiler.reportMessage( |
| 2246 compiler.spanFromSpannable(node), | 2261 compiler.spanFromSpannable(node), |
| 2247 MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY.error([]), | 2262 MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY.error(), |
| 2248 Diagnostic.ERROR); | 2263 Diagnostic.ERROR); |
| 2249 compiler.reportMessage( | 2264 compiler.reportMessage( |
| 2250 compiler.spanFromSpannable(enclosingElement), | 2265 compiler.spanFromSpannable(enclosingElement), |
| 2251 MessageKind.MISSING_FACTORY_KEYWORD.error([]), | 2266 MessageKind.MISSING_FACTORY_KEYWORD.error(), |
| 2252 Diagnostic.INFO); | 2267 Diagnostic.INFO); |
| 2253 } | 2268 } |
| 2254 Element redirectionTarget = resolveRedirectingFactory(node); | 2269 Element redirectionTarget = resolveRedirectingFactory(node); |
| 2255 var type = mapping.getType(node.expression); | 2270 var type = mapping.getType(node.expression); |
| 2256 if (type is InterfaceType && !type.isRaw) { | 2271 if (type is InterfaceType && !type.isRaw) { |
| 2257 unimplemented(node.expression, 'type arguments on redirecting factory'); | 2272 unimplemented(node.expression, 'type arguments on redirecting factory'); |
| 2258 } | 2273 } |
| 2259 useElement(node.expression, redirectionTarget); | 2274 useElement(node.expression, redirectionTarget); |
| 2260 FunctionElement constructor = enclosingElement; | 2275 FunctionElement constructor = enclosingElement; |
| 2261 if (constructor.modifiers.isConst() && | 2276 if (constructor.modifiers.isConst() && |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2417 // TODO(ngeoffray): Implement this. | 2432 // TODO(ngeoffray): Implement this. |
| 2418 unimplemented(node, 'modifiers'); | 2433 unimplemented(node, 'modifiers'); |
| 2419 } | 2434 } |
| 2420 | 2435 |
| 2421 visitLiteralList(LiteralList node) { | 2436 visitLiteralList(LiteralList node) { |
| 2422 world.registerInstantiatedClass(compiler.listClass); | 2437 world.registerInstantiatedClass(compiler.listClass); |
| 2423 NodeList arguments = node.typeArguments; | 2438 NodeList arguments = node.typeArguments; |
| 2424 if (arguments != null) { | 2439 if (arguments != null) { |
| 2425 Link<Node> nodes = arguments.nodes; | 2440 Link<Node> nodes = arguments.nodes; |
| 2426 if (nodes.isEmpty) { | 2441 if (nodes.isEmpty) { |
| 2427 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT, []); | 2442 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
| 2428 } else { | 2443 } else { |
| 2429 resolveTypeRequired(nodes.head); | 2444 resolveTypeRequired(nodes.head); |
| 2430 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 2445 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
| 2431 error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT, []); | 2446 error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
| 2432 resolveTypeRequired(nodes.head); | 2447 resolveTypeRequired(nodes.head); |
| 2433 } | 2448 } |
| 2434 } | 2449 } |
| 2435 } | 2450 } |
| 2436 visit(node.elements); | 2451 visit(node.elements); |
| 2437 } | 2452 } |
| 2438 | 2453 |
| 2439 visitConditional(Conditional node) { | 2454 visitConditional(Conditional node) { |
| 2440 node.visitChildren(this); | 2455 node.visitChildren(this); |
| 2441 } | 2456 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2456 target = statementScope.currentBreakTarget(); | 2471 target = statementScope.currentBreakTarget(); |
| 2457 if (target == null) { | 2472 if (target == null) { |
| 2458 error(node, MessageKind.NO_BREAK_TARGET); | 2473 error(node, MessageKind.NO_BREAK_TARGET); |
| 2459 return; | 2474 return; |
| 2460 } | 2475 } |
| 2461 target.isBreakTarget = true; | 2476 target.isBreakTarget = true; |
| 2462 } else { | 2477 } else { |
| 2463 String labelName = node.target.source.slowToString(); | 2478 String labelName = node.target.source.slowToString(); |
| 2464 LabelElement label = statementScope.lookupLabel(labelName); | 2479 LabelElement label = statementScope.lookupLabel(labelName); |
| 2465 if (label == null) { | 2480 if (label == null) { |
| 2466 error(node.target, MessageKind.UNBOUND_LABEL, [labelName]); | 2481 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
| 2467 return; | 2482 return; |
| 2468 } | 2483 } |
| 2469 target = label.target; | 2484 target = label.target; |
| 2470 if (!target.statement.isValidBreakTarget()) { | 2485 if (!target.statement.isValidBreakTarget()) { |
| 2471 error(node.target, MessageKind.INVALID_BREAK, [labelName]); | 2486 error(node.target, MessageKind.INVALID_BREAK); |
| 2472 return; | 2487 return; |
| 2473 } | 2488 } |
| 2474 label.setBreakTarget(); | 2489 label.setBreakTarget(); |
| 2475 mapping[node.target] = label; | 2490 mapping[node.target] = label; |
| 2476 } | 2491 } |
| 2477 if (mapping[node] != null) { | 2492 if (mapping[node] != null) { |
| 2478 // TODO(ahe): I'm not sure why this node already has an element | 2493 // TODO(ahe): I'm not sure why this node already has an element |
| 2479 // that is different from target. I will talk to Lasse and | 2494 // that is different from target. I will talk to Lasse and |
| 2480 // figure out what is going on. | 2495 // figure out what is going on. |
| 2481 mapping.remove(node); | 2496 mapping.remove(node); |
| 2482 } | 2497 } |
| 2483 mapping[node] = target; | 2498 mapping[node] = target; |
| 2484 } | 2499 } |
| 2485 | 2500 |
| 2486 visitContinueStatement(ContinueStatement node) { | 2501 visitContinueStatement(ContinueStatement node) { |
| 2487 TargetElement target; | 2502 TargetElement target; |
| 2488 if (node.target == null) { | 2503 if (node.target == null) { |
| 2489 target = statementScope.currentContinueTarget(); | 2504 target = statementScope.currentContinueTarget(); |
| 2490 if (target == null) { | 2505 if (target == null) { |
| 2491 error(node, MessageKind.NO_CONTINUE_TARGET); | 2506 error(node, MessageKind.NO_CONTINUE_TARGET); |
| 2492 return; | 2507 return; |
| 2493 } | 2508 } |
| 2494 target.isContinueTarget = true; | 2509 target.isContinueTarget = true; |
| 2495 } else { | 2510 } else { |
| 2496 String labelName = node.target.source.slowToString(); | 2511 String labelName = node.target.source.slowToString(); |
| 2497 LabelElement label = statementScope.lookupLabel(labelName); | 2512 LabelElement label = statementScope.lookupLabel(labelName); |
| 2498 if (label == null) { | 2513 if (label == null) { |
| 2499 error(node.target, MessageKind.UNBOUND_LABEL, [labelName]); | 2514 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
| 2500 return; | 2515 return; |
| 2501 } | 2516 } |
| 2502 target = label.target; | 2517 target = label.target; |
| 2503 if (!target.statement.isValidContinueTarget()) { | 2518 if (!target.statement.isValidContinueTarget()) { |
| 2504 error(node.target, MessageKind.INVALID_CONTINUE, [labelName]); | 2519 error(node.target, MessageKind.INVALID_CONTINUE); |
| 2505 } | 2520 } |
| 2506 // TODO(lrn): Handle continues to switch cases. | 2521 // TODO(lrn): Handle continues to switch cases. |
| 2507 if (target.statement is SwitchCase) { | 2522 if (target.statement is SwitchCase) { |
| 2508 unimplemented(node, "continue to switch case"); | 2523 unimplemented(node, "continue to switch case"); |
| 2509 } | 2524 } |
| 2510 label.setContinueTarget(); | 2525 label.setContinueTarget(); |
| 2511 mapping[node.target] = label; | 2526 mapping[node.target] = label; |
| 2512 } | 2527 } |
| 2513 mapping[node] = target; | 2528 mapping[node] = target; |
| 2514 } | 2529 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2537 visitLoopBodyIn(node, node.body, blockScope); | 2552 visitLoopBodyIn(node, node.body, blockScope); |
| 2538 | 2553 |
| 2539 // TODO(lrn): Also allow a single identifier. | 2554 // TODO(lrn): Also allow a single identifier. |
| 2540 if ((declaration is !Send || declaration.asSend().selector is !Identifier | 2555 if ((declaration is !Send || declaration.asSend().selector is !Identifier |
| 2541 || declaration.asSend().receiver != null) | 2556 || declaration.asSend().receiver != null) |
| 2542 && (declaration is !VariableDefinitions || | 2557 && (declaration is !VariableDefinitions || |
| 2543 !declaration.asVariableDefinitions().definitions.nodes.tail.isEmpty)) | 2558 !declaration.asVariableDefinitions().definitions.nodes.tail.isEmpty)) |
| 2544 { | 2559 { |
| 2545 // The variable declaration is either not an identifier, not a | 2560 // The variable declaration is either not an identifier, not a |
| 2546 // declaration, or it's declaring more than one variable. | 2561 // declaration, or it's declaring more than one variable. |
| 2547 error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []); | 2562 error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN); |
| 2548 } | 2563 } |
| 2549 } | 2564 } |
| 2550 | 2565 |
| 2551 visitLabel(Label node) { | 2566 visitLabel(Label node) { |
| 2552 // Labels are handled by their containing statements/cases. | 2567 // Labels are handled by their containing statements/cases. |
| 2553 } | 2568 } |
| 2554 | 2569 |
| 2555 visitLabeledStatement(LabeledStatement node) { | 2570 visitLabeledStatement(LabeledStatement node) { |
| 2556 Statement body = node.statement; | 2571 Statement body = node.statement; |
| 2557 TargetElement targetElement = getOrCreateTargetElement(body); | 2572 TargetElement targetElement = getOrCreateTargetElement(body); |
| 2558 Map<String, LabelElement> labelElements = <String, LabelElement>{}; | 2573 Map<String, LabelElement> labelElements = <String, LabelElement>{}; |
| 2559 for (Label label in node.labels) { | 2574 for (Label label in node.labels) { |
| 2560 String labelName = label.slowToString(); | 2575 String labelName = label.slowToString(); |
| 2561 if (labelElements.containsKey(labelName)) continue; | 2576 if (labelElements.containsKey(labelName)) continue; |
| 2562 LabelElement element = targetElement.addLabel(label, labelName); | 2577 LabelElement element = targetElement.addLabel(label, labelName); |
| 2563 labelElements[labelName] = element; | 2578 labelElements[labelName] = element; |
| 2564 } | 2579 } |
| 2565 statementScope.enterLabelScope(labelElements); | 2580 statementScope.enterLabelScope(labelElements); |
| 2566 visit(node.statement); | 2581 visit(node.statement); |
| 2567 statementScope.exitLabelScope(); | 2582 statementScope.exitLabelScope(); |
| 2568 labelElements.forEach((String labelName, LabelElement element) { | 2583 labelElements.forEach((String labelName, LabelElement element) { |
| 2569 if (element.isTarget) { | 2584 if (element.isTarget) { |
| 2570 mapping[element.label] = element; | 2585 mapping[element.label] = element; |
| 2571 } else { | 2586 } else { |
| 2572 warning(element.label, MessageKind.UNUSED_LABEL, [labelName]); | 2587 warning(element.label, MessageKind.UNUSED_LABEL, |
| 2588 {'labelName': labelName}); |
| 2573 } | 2589 } |
| 2574 }); | 2590 }); |
| 2575 if (!targetElement.isTarget && identical(mapping[body], targetElement)) { | 2591 if (!targetElement.isTarget && identical(mapping[body], targetElement)) { |
| 2576 // If the body is itself a break or continue for another target, it | 2592 // If the body is itself a break or continue for another target, it |
| 2577 // might have updated its mapping to the target it actually does target. | 2593 // might have updated its mapping to the target it actually does target. |
| 2578 mapping.remove(body); | 2594 mapping.remove(body); |
| 2579 } | 2595 } |
| 2580 } | 2596 } |
| 2581 | 2597 |
| 2582 visitLiteralMap(LiteralMap node) { | 2598 visitLiteralMap(LiteralMap node) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2600 while (!cases.isEmpty) { | 2616 while (!cases.isEmpty) { |
| 2601 SwitchCase switchCase = cases.head; | 2617 SwitchCase switchCase = cases.head; |
| 2602 for (Node labelOrCase in switchCase.labelsAndCases) { | 2618 for (Node labelOrCase in switchCase.labelsAndCases) { |
| 2603 if (labelOrCase is! Label) continue; | 2619 if (labelOrCase is! Label) continue; |
| 2604 Label label = labelOrCase; | 2620 Label label = labelOrCase; |
| 2605 String labelName = label.slowToString(); | 2621 String labelName = label.slowToString(); |
| 2606 | 2622 |
| 2607 LabelElement existingElement = continueLabels[labelName]; | 2623 LabelElement existingElement = continueLabels[labelName]; |
| 2608 if (existingElement != null) { | 2624 if (existingElement != null) { |
| 2609 // It's an error if the same label occurs twice in the same switch. | 2625 // It's an error if the same label occurs twice in the same switch. |
| 2610 warning(label, MessageKind.DUPLICATE_LABEL, [labelName]); | 2626 warning(label, MessageKind.DUPLICATE_LABEL, {'labelName': labelName}); |
| 2611 error(existingElement.label, MessageKind.EXISTING_LABEL, [labelName]); | 2627 error(existingElement.label, MessageKind.EXISTING_LABEL, |
| 2628 {'labelName': labelName}); |
| 2612 } else { | 2629 } else { |
| 2613 // It's only a warning if it shadows another label. | 2630 // It's only a warning if it shadows another label. |
| 2614 existingElement = statementScope.lookupLabel(labelName); | 2631 existingElement = statementScope.lookupLabel(labelName); |
| 2615 if (existingElement != null) { | 2632 if (existingElement != null) { |
| 2616 warning(label, MessageKind.DUPLICATE_LABEL, [labelName]); | 2633 warning(label, MessageKind.DUPLICATE_LABEL, |
| 2634 {'labelName': labelName}); |
| 2617 warning(existingElement.label, | 2635 warning(existingElement.label, |
| 2618 MessageKind.EXISTING_LABEL, [labelName]); | 2636 MessageKind.EXISTING_LABEL, {'labelName': labelName}); |
| 2619 } | 2637 } |
| 2620 } | 2638 } |
| 2621 | 2639 |
| 2622 TargetElement targetElement = | 2640 TargetElement targetElement = |
| 2623 new TargetElementX(switchCase, | 2641 new TargetElementX(switchCase, |
| 2624 statementScope.nestingLevel, | 2642 statementScope.nestingLevel, |
| 2625 enclosingElement); | 2643 enclosingElement); |
| 2626 if (mapping[switchCase] != null) { | 2644 if (mapping[switchCase] != null) { |
| 2627 // TODO(ahe): Talk to Lasse about this. | 2645 // TODO(ahe): Talk to Lasse about this. |
| 2628 mapping.remove(switchCase); | 2646 mapping.remove(switchCase); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2747 | 2765 |
| 2748 var nameSet = new Set<SourceString>(); | 2766 var nameSet = new Set<SourceString>(); |
| 2749 // Resolve the bounds of type variables. | 2767 // Resolve the bounds of type variables. |
| 2750 Link<DartType> typeLink = element.typeVariables; | 2768 Link<DartType> typeLink = element.typeVariables; |
| 2751 Link<Node> nodeLink = node.nodes; | 2769 Link<Node> nodeLink = node.nodes; |
| 2752 while (!nodeLink.isEmpty) { | 2770 while (!nodeLink.isEmpty) { |
| 2753 TypeVariableType typeVariable = typeLink.head; | 2771 TypeVariableType typeVariable = typeLink.head; |
| 2754 SourceString typeName = typeVariable.name; | 2772 SourceString typeName = typeVariable.name; |
| 2755 TypeVariable typeNode = nodeLink.head; | 2773 TypeVariable typeNode = nodeLink.head; |
| 2756 if (nameSet.contains(typeName)) { | 2774 if (nameSet.contains(typeName)) { |
| 2757 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]); | 2775 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, |
| 2776 {'typeVariableName': typeName}); |
| 2758 } | 2777 } |
| 2759 nameSet.add(typeName); | 2778 nameSet.add(typeName); |
| 2760 | 2779 |
| 2761 TypeVariableElement variableElement = typeVariable.element; | 2780 TypeVariableElement variableElement = typeVariable.element; |
| 2762 if (typeNode.bound != null) { | 2781 if (typeNode.bound != null) { |
| 2763 DartType boundType = typeResolver.resolveTypeAnnotation( | 2782 DartType boundType = typeResolver.resolveTypeAnnotation( |
| 2764 typeNode.bound, scope, element, onFailure: warning); | 2783 typeNode.bound, scope, element, onFailure: warning); |
| 2765 if (boundType != null && boundType.element == variableElement) { | 2784 if (boundType != null && boundType.element == variableElement) { |
| 2766 // TODO(johnniwinther): Check for more general cycles, like | 2785 // TODO(johnniwinther): Check for more general cycles, like |
| 2767 // [: <A extends B, B extends C, C extends B> :]. | 2786 // [: <A extends B, B extends C, C extends B> :]. |
| 2768 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, | 2787 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, |
| 2769 [variableElement.name]); | 2788 {'typeVariableName': variableElement.name}); |
| 2770 } else if (boundType != null) { | 2789 } else if (boundType != null) { |
| 2771 variableElement.bound = boundType; | 2790 variableElement.bound = boundType; |
| 2772 } else { | 2791 } else { |
| 2773 // TODO(johnniwinther): Should be an erroneous type. | 2792 // TODO(johnniwinther): Should be an erroneous type. |
| 2774 variableElement.bound = compiler.objectClass.computeType(compiler); | 2793 variableElement.bound = compiler.objectClass.computeType(compiler); |
| 2775 } | 2794 } |
| 2776 } else { | 2795 } else { |
| 2777 variableElement.bound = compiler.objectClass.computeType(compiler); | 2796 variableElement.bound = compiler.objectClass.computeType(compiler); |
| 2778 } | 2797 } |
| 2779 nodeLink = nodeLink.tail; | 2798 nodeLink = nodeLink.tail; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2940 ClassElement mixin = mixinType.element; | 2959 ClassElement mixin = mixinType.element; |
| 2941 mixin.ensureResolved(compiler); | 2960 mixin.ensureResolved(compiler); |
| 2942 | 2961 |
| 2943 // Check for cycles in the mixin chain. | 2962 // Check for cycles in the mixin chain. |
| 2944 ClassElement previous = mixinApplication; // For better error messages. | 2963 ClassElement previous = mixinApplication; // For better error messages. |
| 2945 ClassElement current = mixin; | 2964 ClassElement current = mixin; |
| 2946 while (current != null && current.isMixinApplication) { | 2965 while (current != null && current.isMixinApplication) { |
| 2947 MixinApplicationElement currentMixinApplication = current; | 2966 MixinApplicationElement currentMixinApplication = current; |
| 2948 if (currentMixinApplication == mixinApplication) { | 2967 if (currentMixinApplication == mixinApplication) { |
| 2949 CompilationError error = MessageKind.ILLEGAL_MIXIN_CYCLE.error( | 2968 CompilationError error = MessageKind.ILLEGAL_MIXIN_CYCLE.error( |
| 2950 [current.name, previous.name]); | 2969 {'mixinName1': current.name, 'mixinName2': previous.name}); |
| 2951 compiler.reportMessage(compiler.spanFromElement(mixinApplication), | 2970 compiler.reportMessage(compiler.spanFromElement(mixinApplication), |
| 2952 error, Diagnostic.ERROR); | 2971 error, Diagnostic.ERROR); |
| 2953 // We have found a cycle in the mixin chain. Return null as | 2972 // We have found a cycle in the mixin chain. Return null as |
| 2954 // the mixin for this application to avoid getting into | 2973 // the mixin for this application to avoid getting into |
| 2955 // infinite recursion when traversing members. | 2974 // infinite recursion when traversing members. |
| 2956 return null; | 2975 return null; |
| 2957 } | 2976 } |
| 2958 previous = current; | 2977 previous = current; |
| 2959 current = currentMixinApplication.mixin; | 2978 current = currentMixinApplication.mixin; |
| 2960 } | 2979 } |
| 2961 compiler.world.registerMixinUse(mixinApplication, mixin); | 2980 compiler.world.registerMixinUse(mixinApplication, mixin); |
| 2962 return mixin; | 2981 return mixin; |
| 2963 } | 2982 } |
| 2964 | 2983 |
| 2965 // TODO(johnniwinther): Remove when default class is no longer supported. | 2984 // TODO(johnniwinther): Remove when default class is no longer supported. |
| 2966 DartType visitTypeAnnotation(TypeAnnotation node) { | 2985 DartType visitTypeAnnotation(TypeAnnotation node) { |
| 2967 return visit(node.typeName); | 2986 return visit(node.typeName); |
| 2968 } | 2987 } |
| 2969 | 2988 |
| 2970 // TODO(johnniwinther): Remove when default class is no longer supported. | 2989 // TODO(johnniwinther): Remove when default class is no longer supported. |
| 2971 DartType visitIdentifier(Identifier node) { | 2990 DartType visitIdentifier(Identifier node) { |
| 2972 Element element = scope.lookup(node.source); | 2991 Element element = scope.lookup(node.source); |
| 2973 if (element == null) { | 2992 if (element == null) { |
| 2974 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); | 2993 error(node, MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node}); |
| 2975 return null; | 2994 return null; |
| 2976 } else if (!element.impliesType() && !element.isTypeVariable()) { | 2995 } else if (!element.impliesType() && !element.isTypeVariable()) { |
| 2977 error(node, MessageKind.NOT_A_TYPE, [node]); | 2996 error(node, MessageKind.NOT_A_TYPE, {'node': node}); |
| 2978 return null; | 2997 return null; |
| 2979 } else { | 2998 } else { |
| 2980 if (element.isTypeVariable()) { | 2999 if (element.isTypeVariable()) { |
| 2981 TypeVariableElement variableElement = element; | 3000 TypeVariableElement variableElement = element; |
| 2982 return variableElement.type; | 3001 return variableElement.type; |
| 2983 } else if (element.isTypedef()) { | 3002 } else if (element.isTypedef()) { |
| 2984 compiler.unimplemented('visitIdentifier for typedefs', node: node); | 3003 compiler.unimplemented('visitIdentifier for typedefs', node: node); |
| 2985 } else { | 3004 } else { |
| 2986 // TODO(ngeoffray): Use type variables. | 3005 // TODO(ngeoffray): Use type variables. |
| 2987 return element.computeType(compiler); | 3006 return element.computeType(compiler); |
| 2988 } | 3007 } |
| 2989 } | 3008 } |
| 2990 return null; | 3009 return null; |
| 2991 } | 3010 } |
| 2992 | 3011 |
| 2993 // TODO(johnniwinther): Remove when default class is no longer supported. | 3012 // TODO(johnniwinther): Remove when default class is no longer supported. |
| 2994 DartType visitSend(Send node) { | 3013 DartType visitSend(Send node) { |
| 2995 Identifier prefix = node.receiver.asIdentifier(); | 3014 Identifier prefix = node.receiver.asIdentifier(); |
| 2996 if (prefix == null) { | 3015 if (prefix == null) { |
| 2997 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | 3016 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
| 2998 return null; | 3017 return null; |
| 2999 } | 3018 } |
| 3000 Element element = scope.lookup(prefix.source); | 3019 Element element = scope.lookup(prefix.source); |
| 3001 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { | 3020 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { |
| 3002 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | 3021 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
| 3003 return null; | 3022 return null; |
| 3004 } | 3023 } |
| 3005 PrefixElement prefixElement = element; | 3024 PrefixElement prefixElement = element; |
| 3006 Identifier selector = node.selector.asIdentifier(); | 3025 Identifier selector = node.selector.asIdentifier(); |
| 3007 var e = prefixElement.lookupLocalMember(selector.source); | 3026 var e = prefixElement.lookupLocalMember(selector.source); |
| 3008 if (e == null || !e.impliesType()) { | 3027 if (e == null || !e.impliesType()) { |
| 3009 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); | 3028 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, |
| 3029 {'typeName': node.selector}); |
| 3010 return null; | 3030 return null; |
| 3011 } | 3031 } |
| 3012 return e.computeType(compiler); | 3032 return e.computeType(compiler); |
| 3013 } | 3033 } |
| 3014 | 3034 |
| 3015 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { | 3035 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { |
| 3016 DartType supertype = typeResolver.resolveTypeAnnotation( | 3036 DartType supertype = typeResolver.resolveTypeAnnotation( |
| 3017 superclass, scope, cls, onFailure: error); | 3037 superclass, scope, cls, onFailure: error); |
| 3018 if (supertype != null) { | 3038 if (supertype != null) { |
| 3019 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { | 3039 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { |
| 3020 // Error has already been reported. | 3040 // Error has already been reported. |
| 3021 return null; | 3041 return null; |
| 3022 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { | 3042 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { |
| 3023 // TODO(johnniwinther): Handle dynamic. | 3043 // TODO(johnniwinther): Handle dynamic. |
| 3024 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED, []); | 3044 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED); |
| 3025 return null; | 3045 return null; |
| 3026 } else if (isBlackListed(supertype)) { | 3046 } else if (isBlackListed(supertype)) { |
| 3027 error(superclass, MessageKind.CANNOT_EXTEND, [supertype]); | 3047 error(superclass, MessageKind.CANNOT_EXTEND, {'type': supertype}); |
| 3028 return null; | 3048 return null; |
| 3029 } | 3049 } |
| 3030 } | 3050 } |
| 3031 return supertype; | 3051 return supertype; |
| 3032 } | 3052 } |
| 3033 | 3053 |
| 3034 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { | 3054 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { |
| 3035 Link<DartType> result = const Link<DartType>(); | 3055 Link<DartType> result = const Link<DartType>(); |
| 3036 if (interfaces == null) return result; | 3056 if (interfaces == null) return result; |
| 3037 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { | 3057 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { |
| 3038 DartType interfaceType = typeResolver.resolveTypeAnnotation( | 3058 DartType interfaceType = typeResolver.resolveTypeAnnotation( |
| 3039 link.head, scope, element, onFailure: error); | 3059 link.head, scope, element, onFailure: error); |
| 3040 if (interfaceType != null) { | 3060 if (interfaceType != null) { |
| 3041 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { | 3061 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { |
| 3042 // Error has already been reported. | 3062 // Error has already been reported. |
| 3043 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { | 3063 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { |
| 3044 // TODO(johnniwinther): Handle dynamic. | 3064 // TODO(johnniwinther): Handle dynamic. |
| 3045 TypeAnnotation typeAnnotation = link.head; | 3065 TypeAnnotation typeAnnotation = link.head; |
| 3046 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED, []); | 3066 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); |
| 3047 } else { | 3067 } else { |
| 3048 if (interfaceType == element.supertype) { | 3068 if (interfaceType == element.supertype) { |
| 3049 compiler.reportMessage( | 3069 compiler.reportMessage( |
| 3050 compiler.spanFromSpannable(superclass), | 3070 compiler.spanFromSpannable(superclass), |
| 3051 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS.error([interfaceType]), | 3071 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS.error( |
| 3072 {'type': interfaceType}), |
| 3052 Diagnostic.ERROR); | 3073 Diagnostic.ERROR); |
| 3053 compiler.reportMessage( | 3074 compiler.reportMessage( |
| 3054 compiler.spanFromSpannable(link.head), | 3075 compiler.spanFromSpannable(link.head), |
| 3055 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS.error([interfaceType]), | 3076 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS.error( |
| 3077 {'type': interfaceType}), |
| 3056 Diagnostic.ERROR); | 3078 Diagnostic.ERROR); |
| 3057 } | 3079 } |
| 3058 if (result.contains(interfaceType)) { | 3080 if (result.contains(interfaceType)) { |
| 3059 compiler.reportMessage( | 3081 compiler.reportMessage( |
| 3060 compiler.spanFromSpannable(link.head), | 3082 compiler.spanFromSpannable(link.head), |
| 3061 MessageKind.DUPLICATE_IMPLEMENTS.error([interfaceType]), | 3083 MessageKind.DUPLICATE_IMPLEMENTS.error({'type': interfaceType}), |
| 3062 Diagnostic.ERROR); | 3084 Diagnostic.ERROR); |
| 3063 } | 3085 } |
| 3064 result = result.prepend(interfaceType); | 3086 result = result.prepend(interfaceType); |
| 3065 if (isBlackListed(interfaceType)) { | 3087 if (isBlackListed(interfaceType)) { |
| 3066 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]); | 3088 error(link.head, MessageKind.CANNOT_IMPLEMENT, |
| 3089 {'type': interfaceType}); |
| 3067 } | 3090 } |
| 3068 } | 3091 } |
| 3069 } | 3092 } |
| 3070 } | 3093 } |
| 3071 return result; | 3094 return result; |
| 3072 } | 3095 } |
| 3073 | 3096 |
| 3074 void calculateAllSupertypes(ClassElement cls) { | 3097 void calculateAllSupertypes(ClassElement cls) { |
| 3075 // TODO(karlklose): Check if type arguments match, if a class | 3098 // TODO(karlklose): Check if type arguments match, if a class |
| 3076 // element occurs more than once in the supertypes. | 3099 // element occurs more than once in the supertypes. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3164 visitNodeList(node.mixins); | 3187 visitNodeList(node.mixins); |
| 3165 } | 3188 } |
| 3166 | 3189 |
| 3167 void visitTypeAnnotation(TypeAnnotation node) { | 3190 void visitTypeAnnotation(TypeAnnotation node) { |
| 3168 node.typeName.accept(this); | 3191 node.typeName.accept(this); |
| 3169 } | 3192 } |
| 3170 | 3193 |
| 3171 void visitIdentifier(Identifier node) { | 3194 void visitIdentifier(Identifier node) { |
| 3172 Element element = context.lookup(node.source); | 3195 Element element = context.lookup(node.source); |
| 3173 if (element == null) { | 3196 if (element == null) { |
| 3174 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); | 3197 error(node, MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node}); |
| 3175 } else if (!element.impliesType()) { | 3198 } else if (!element.impliesType()) { |
| 3176 error(node, MessageKind.NOT_A_TYPE, [node]); | 3199 error(node, MessageKind.NOT_A_TYPE, {'node': node}); |
| 3177 } else { | 3200 } else { |
| 3178 if (element.isClass()) { | 3201 if (element.isClass()) { |
| 3179 loadSupertype(element, node); | 3202 loadSupertype(element, node); |
| 3180 } else { | 3203 } else { |
| 3181 compiler.reportMessage( | 3204 compiler.reportMessage( |
| 3182 compiler.spanFromSpannable(node), | 3205 compiler.spanFromSpannable(node), |
| 3183 MessageKind.CLASS_NAME_EXPECTED.error([]), | 3206 MessageKind.CLASS_NAME_EXPECTED.error(), |
| 3184 Diagnostic.ERROR); | 3207 Diagnostic.ERROR); |
| 3185 } | 3208 } |
| 3186 } | 3209 } |
| 3187 } | 3210 } |
| 3188 | 3211 |
| 3189 void visitSend(Send node) { | 3212 void visitSend(Send node) { |
| 3190 Identifier prefix = node.receiver.asIdentifier(); | 3213 Identifier prefix = node.receiver.asIdentifier(); |
| 3191 if (prefix == null) { | 3214 if (prefix == null) { |
| 3192 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | 3215 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
| 3193 return; | 3216 return; |
| 3194 } | 3217 } |
| 3195 Element element = context.lookup(prefix.source); | 3218 Element element = context.lookup(prefix.source); |
| 3196 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { | 3219 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { |
| 3197 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | 3220 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
| 3198 return; | 3221 return; |
| 3199 } | 3222 } |
| 3200 PrefixElement prefixElement = element; | 3223 PrefixElement prefixElement = element; |
| 3201 Identifier selector = node.selector.asIdentifier(); | 3224 Identifier selector = node.selector.asIdentifier(); |
| 3202 var e = prefixElement.lookupLocalMember(selector.source); | 3225 var e = prefixElement.lookupLocalMember(selector.source); |
| 3203 if (e == null || !e.impliesType()) { | 3226 if (e == null || !e.impliesType()) { |
| 3204 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); | 3227 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, |
| 3228 {'typeName': node.selector}); |
| 3205 return; | 3229 return; |
| 3206 } | 3230 } |
| 3207 loadSupertype(e, node); | 3231 loadSupertype(e, node); |
| 3208 } | 3232 } |
| 3209 } | 3233 } |
| 3210 | 3234 |
| 3211 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { | 3235 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { |
| 3212 VariableDefinitions definitions; | 3236 VariableDefinitions definitions; |
| 3213 ResolverVisitor resolver; | 3237 ResolverVisitor resolver; |
| 3214 ElementKind kind; | 3238 ElementKind kind; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3318 } | 3342 } |
| 3319 } | 3343 } |
| 3320 } | 3344 } |
| 3321 | 3345 |
| 3322 // The only valid [Send] can be in constructors and must be of the form | 3346 // The only valid [Send] can be in constructors and must be of the form |
| 3323 // [:this.x:] (where [:x:] represents an instance field). | 3347 // [:this.x:] (where [:x:] represents an instance field). |
| 3324 FieldParameterElement visitSend(Send node) { | 3348 FieldParameterElement visitSend(Send node) { |
| 3325 FieldParameterElement element; | 3349 FieldParameterElement element; |
| 3326 if (node.receiver.asIdentifier() == null || | 3350 if (node.receiver.asIdentifier() == null || |
| 3327 !node.receiver.asIdentifier().isThis()) { | 3351 !node.receiver.asIdentifier().isThis()) { |
| 3328 error(node, MessageKind.INVALID_PARAMETER, []); | 3352 error(node, MessageKind.INVALID_PARAMETER); |
| 3329 } else if (!identical(enclosingElement.kind, ElementKind.GENERATIVE_CONSTRUC
TOR)) { | 3353 } else if (!identical(enclosingElement.kind, |
| 3330 error(node, MessageKind.FIELD_PARAMETER_NOT_ALLOWED, []); | 3354 ElementKind.GENERATIVE_CONSTRUCTOR)) { |
| 3355 error(node, MessageKind.FIELD_PARAMETER_NOT_ALLOWED); |
| 3331 } else { | 3356 } else { |
| 3332 SourceString name = getParameterName(node); | 3357 SourceString name = getParameterName(node); |
| 3333 Element fieldElement = currentClass.lookupLocalMember(name); | 3358 Element fieldElement = currentClass.lookupLocalMember(name); |
| 3334 if (fieldElement == null || !identical(fieldElement.kind, ElementKind.FIEL
D)) { | 3359 if (fieldElement == null || |
| 3335 error(node, MessageKind.NOT_A_FIELD, [name]); | 3360 !identical(fieldElement.kind, ElementKind.FIELD)) { |
| 3361 error(node, MessageKind.NOT_A_FIELD, {'fieldName': name}); |
| 3336 } else if (!fieldElement.isInstanceMember()) { | 3362 } else if (!fieldElement.isInstanceMember()) { |
| 3337 error(node, MessageKind.NOT_INSTANCE_FIELD, [name]); | 3363 error(node, MessageKind.NOT_INSTANCE_FIELD, {'fieldName': name}); |
| 3338 } | 3364 } |
| 3339 Element variables = new VariableListElementX.node(currentDefinitions, | 3365 Element variables = new VariableListElementX.node(currentDefinitions, |
| 3340 ElementKind.VARIABLE_LIST, enclosingElement); | 3366 ElementKind.VARIABLE_LIST, enclosingElement); |
| 3341 element = new FieldParameterElementX(name, fieldElement, variables, node); | 3367 element = new FieldParameterElementX(name, fieldElement, variables, node); |
| 3342 } | 3368 } |
| 3343 return element; | 3369 return element; |
| 3344 } | 3370 } |
| 3345 | 3371 |
| 3346 Element visitSendSet(SendSet node) { | 3372 Element visitSendSet(SendSet node) { |
| 3347 Element element; | 3373 Element element; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3388 static FunctionSignature analyze(Compiler compiler, | 3414 static FunctionSignature analyze(Compiler compiler, |
| 3389 NodeList formalParameters, | 3415 NodeList formalParameters, |
| 3390 Node returnNode, | 3416 Node returnNode, |
| 3391 Element element) { | 3417 Element element) { |
| 3392 SignatureResolver visitor = new SignatureResolver(compiler, element); | 3418 SignatureResolver visitor = new SignatureResolver(compiler, element); |
| 3393 Link<Element> parameters = const Link<Element>(); | 3419 Link<Element> parameters = const Link<Element>(); |
| 3394 int requiredParameterCount = 0; | 3420 int requiredParameterCount = 0; |
| 3395 if (formalParameters == null) { | 3421 if (formalParameters == null) { |
| 3396 if (!element.isGetter()) { | 3422 if (!element.isGetter()) { |
| 3397 compiler.reportMessage(compiler.spanFromElement(element), | 3423 compiler.reportMessage(compiler.spanFromElement(element), |
| 3398 MessageKind.MISSING_FORMALS.error([]), | 3424 MessageKind.MISSING_FORMALS.error(), |
| 3399 Diagnostic.ERROR); | 3425 Diagnostic.ERROR); |
| 3400 } | 3426 } |
| 3401 } else { | 3427 } else { |
| 3402 if (element.isGetter()) { | 3428 if (element.isGetter()) { |
| 3403 if (!identical(formalParameters.getEndToken().next.stringValue, | 3429 if (!identical(formalParameters.getEndToken().next.stringValue, |
| 3404 // TODO(ahe): Remove the check for native keyword. | 3430 // TODO(ahe): Remove the check for native keyword. |
| 3405 'native')) { | 3431 'native')) { |
| 3406 if (compiler.rejectDeprecatedFeatures && | 3432 if (compiler.rejectDeprecatedFeatures && |
| 3407 // TODO(ahe): Remove isPlatformLibrary check. | 3433 // TODO(ahe): Remove isPlatformLibrary check. |
| 3408 !element.getLibrary().isPlatformLibrary) { | 3434 !element.getLibrary().isPlatformLibrary) { |
| 3409 compiler.reportMessage(compiler.spanFromSpannable(formalParameters), | 3435 compiler.reportMessage(compiler.spanFromSpannable(formalParameters), |
| 3410 MessageKind.EXTRA_FORMALS.error([]), | 3436 MessageKind.EXTRA_FORMALS.error(), |
| 3411 Diagnostic.ERROR); | 3437 Diagnostic.ERROR); |
| 3412 } else { | 3438 } else { |
| 3413 compiler.onDeprecatedFeature(formalParameters, 'getter parameters'); | 3439 compiler.onDeprecatedFeature(formalParameters, 'getter parameters'); |
| 3414 } | 3440 } |
| 3415 } | 3441 } |
| 3416 } | 3442 } |
| 3417 LinkBuilder<Element> parametersBuilder = | 3443 LinkBuilder<Element> parametersBuilder = |
| 3418 visitor.analyzeNodes(formalParameters.nodes); | 3444 visitor.analyzeNodes(formalParameters.nodes); |
| 3419 requiredParameterCount = parametersBuilder.length; | 3445 requiredParameterCount = parametersBuilder.length; |
| 3420 parameters = parametersBuilder.toLink(); | 3446 parameters = parametersBuilder.toLink(); |
| 3421 } | 3447 } |
| 3422 DartType returnType = compiler.resolveReturnType(element, returnNode); | 3448 DartType returnType = compiler.resolveReturnType(element, returnNode); |
| 3423 if (element.isSetter() && (requiredParameterCount != 1 || | 3449 if (element.isSetter() && (requiredParameterCount != 1 || |
| 3424 visitor.optionalParameterCount != 0)) { | 3450 visitor.optionalParameterCount != 0)) { |
| 3425 // If there are no formal parameters, we already reported an error above. | 3451 // If there are no formal parameters, we already reported an error above. |
| 3426 if (formalParameters != null) { | 3452 if (formalParameters != null) { |
| 3427 compiler.reportMessage(compiler.spanFromSpannable(formalParameters), | 3453 compiler.reportMessage(compiler.spanFromSpannable(formalParameters), |
| 3428 MessageKind.ILLEGAL_SETTER_FORMALS.error([]), | 3454 MessageKind.ILLEGAL_SETTER_FORMALS.error(), |
| 3429 Diagnostic.ERROR); | 3455 Diagnostic.ERROR); |
| 3430 } | 3456 } |
| 3431 } | 3457 } |
| 3432 if (element.isGetter() && (requiredParameterCount != 0 | 3458 if (element.isGetter() && (requiredParameterCount != 0 |
| 3433 || visitor.optionalParameterCount != 0)) { | 3459 || visitor.optionalParameterCount != 0)) { |
| 3434 compiler.reportMessage(compiler.spanFromSpannable(formalParameters), | 3460 compiler.reportMessage(compiler.spanFromSpannable(formalParameters), |
| 3435 MessageKind.EXTRA_FORMALS.error([]), | 3461 MessageKind.EXTRA_FORMALS.error(), |
| 3436 Diagnostic.ERROR); | 3462 Diagnostic.ERROR); |
| 3437 } | 3463 } |
| 3438 return new FunctionSignatureX(parameters, | 3464 return new FunctionSignatureX(parameters, |
| 3439 visitor.optionalParameters, | 3465 visitor.optionalParameters, |
| 3440 requiredParameterCount, | 3466 requiredParameterCount, |
| 3441 visitor.optionalParameterCount, | 3467 visitor.optionalParameterCount, |
| 3442 visitor.optionalParametersAreNamed, | 3468 visitor.optionalParametersAreNamed, |
| 3443 returnType); | 3469 returnType); |
| 3444 } | 3470 } |
| 3445 | 3471 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3463 DartType type; | 3489 DartType type; |
| 3464 | 3490 |
| 3465 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); | 3491 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); |
| 3466 | 3492 |
| 3467 visitNode(Node node) { | 3493 visitNode(Node node) { |
| 3468 throw 'not supported'; | 3494 throw 'not supported'; |
| 3469 } | 3495 } |
| 3470 | 3496 |
| 3471 failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, | 3497 failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, |
| 3472 SourceString targetName, MessageKind kind, | 3498 SourceString targetName, MessageKind kind, |
| 3473 List arguments) { | 3499 Map arguments) { |
| 3474 if (inConstContext) { | 3500 if (inConstContext) { |
| 3475 error(diagnosticNode, kind, arguments); | 3501 error(diagnosticNode, kind, arguments); |
| 3476 } else { | 3502 } else { |
| 3477 ResolutionWarning warning = new ResolutionWarning(kind, arguments); | 3503 ResolutionWarning warning = new ResolutionWarning(kind, arguments); |
| 3478 compiler.reportWarning(diagnosticNode, warning); | 3504 compiler.reportWarning(diagnosticNode, warning); |
| 3479 return new ErroneousElementX(kind, arguments, targetName, enclosing); | 3505 return new ErroneousElementX(kind, arguments, targetName, enclosing); |
| 3480 } | 3506 } |
| 3481 } | 3507 } |
| 3482 | 3508 |
| 3483 Selector createConstructorSelector(SourceString constructorName) { | 3509 Selector createConstructorSelector(SourceString constructorName) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3499 if (result == null) { | 3525 if (result == null) { |
| 3500 String fullConstructorName = | 3526 String fullConstructorName = |
| 3501 resolver.compiler.resolver.constructorNameForDiagnostics( | 3527 resolver.compiler.resolver.constructorNameForDiagnostics( |
| 3502 cls.name, | 3528 cls.name, |
| 3503 constructorName); | 3529 constructorName); |
| 3504 return failOrReturnErroneousElement( | 3530 return failOrReturnErroneousElement( |
| 3505 cls, | 3531 cls, |
| 3506 diagnosticNode, | 3532 diagnosticNode, |
| 3507 new SourceString(fullConstructorName), | 3533 new SourceString(fullConstructorName), |
| 3508 MessageKind.CANNOT_FIND_CONSTRUCTOR, | 3534 MessageKind.CANNOT_FIND_CONSTRUCTOR, |
| 3509 [fullConstructorName]); | 3535 {'constructorName': fullConstructorName}); |
| 3510 } else if (inConstContext && !result.modifiers.isConst()) { | 3536 } else if (inConstContext && !result.modifiers.isConst()) { |
| 3511 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 3537 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 3512 } | 3538 } |
| 3513 return result; | 3539 return result; |
| 3514 } | 3540 } |
| 3515 | 3541 |
| 3516 visitNewExpression(NewExpression node) { | 3542 visitNewExpression(NewExpression node) { |
| 3517 inConstContext = node.isConst(); | 3543 inConstContext = node.isConst(); |
| 3518 Node selector = node.send.selector; | 3544 Node selector = node.send.selector; |
| 3519 Element e = visit(selector); | 3545 Element e = visit(selector); |
| 3520 return finishConstructorReference(e, node.send.selector, node); | 3546 return finishConstructorReference(e, node.send.selector, node); |
| 3521 } | 3547 } |
| 3522 | 3548 |
| 3523 /// Finishes resolution of a constructor reference and records the | 3549 /// Finishes resolution of a constructor reference and records the |
| 3524 /// type of the constructed instance on [expression]. | 3550 /// type of the constructed instance on [expression]. |
| 3525 FunctionElement finishConstructorReference(Element e, | 3551 FunctionElement finishConstructorReference(Element e, |
| 3526 Node diagnosticNode, | 3552 Node diagnosticNode, |
| 3527 Node expression) { | 3553 Node expression) { |
| 3528 // Find the unnamed constructor if the reference resolved to a | 3554 // Find the unnamed constructor if the reference resolved to a |
| 3529 // class. | 3555 // class. |
| 3530 if (!Elements.isUnresolved(e) && e.isClass()) { | 3556 if (!Elements.isUnresolved(e) && e.isClass()) { |
| 3531 ClassElement cls = e; | 3557 ClassElement cls = e; |
| 3532 cls.ensureResolved(compiler); | 3558 cls.ensureResolved(compiler); |
| 3533 if (cls.isInterface() && (cls.defaultClass == null)) { | 3559 if (cls.isInterface() && (cls.defaultClass == null)) { |
| 3534 // TODO(ahe): Remove this check and error message when we | 3560 // TODO(ahe): Remove this check and error message when we |
| 3535 // don't have interfaces anymore. | 3561 // don't have interfaces anymore. |
| 3536 error(diagnosticNode, | 3562 error(diagnosticNode, |
| 3537 MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); | 3563 MessageKind.CANNOT_INSTANTIATE_INTERFACE, |
| 3564 {'interfaceName': cls.name}); |
| 3538 } | 3565 } |
| 3539 // The unnamed constructor may not exist, so [e] may become unresolved. | 3566 // The unnamed constructor may not exist, so [e] may become unresolved. |
| 3540 e = lookupConstructor(cls, diagnosticNode, const SourceString('')); | 3567 e = lookupConstructor(cls, diagnosticNode, const SourceString('')); |
| 3541 } | 3568 } |
| 3542 if (type == null) { | 3569 if (type == null) { |
| 3543 if (Elements.isUnresolved(e)) { | 3570 if (Elements.isUnresolved(e)) { |
| 3544 type = compiler.dynamicClass.computeType(compiler); | 3571 type = compiler.dynamicClass.computeType(compiler); |
| 3545 } else { | 3572 } else { |
| 3546 type = e.getEnclosingClass().computeType(compiler).asRaw(); | 3573 type = e.getEnclosingClass().computeType(compiler).asRaw(); |
| 3547 } | 3574 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3559 visitSend(Send node) { | 3586 visitSend(Send node) { |
| 3560 Element e = visit(node.receiver); | 3587 Element e = visit(node.receiver); |
| 3561 if (Elements.isUnresolved(e)) return e; | 3588 if (Elements.isUnresolved(e)) return e; |
| 3562 Identifier name = node.selector.asIdentifier(); | 3589 Identifier name = node.selector.asIdentifier(); |
| 3563 if (name == null) internalError(node.selector, 'unexpected node'); | 3590 if (name == null) internalError(node.selector, 'unexpected node'); |
| 3564 | 3591 |
| 3565 if (identical(e.kind, ElementKind.CLASS)) { | 3592 if (identical(e.kind, ElementKind.CLASS)) { |
| 3566 ClassElement cls = e; | 3593 ClassElement cls = e; |
| 3567 cls.ensureResolved(compiler); | 3594 cls.ensureResolved(compiler); |
| 3568 if (cls.isInterface() && (cls.defaultClass == null)) { | 3595 if (cls.isInterface() && (cls.defaultClass == null)) { |
| 3569 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE, | 3596 error(node.receiver, |
| 3570 [cls.name]); | 3597 MessageKind.CANNOT_INSTANTIATE_INTERFACE, |
| 3598 {'interfaceName': cls.name}); |
| 3571 } | 3599 } |
| 3572 return lookupConstructor(cls, name, name.source); | 3600 return lookupConstructor(cls, name, name.source); |
| 3573 } else if (identical(e.kind, ElementKind.PREFIX)) { | 3601 } else if (identical(e.kind, ElementKind.PREFIX)) { |
| 3574 PrefixElement prefix = e; | 3602 PrefixElement prefix = e; |
| 3575 e = prefix.lookupLocalMember(name.source); | 3603 e = prefix.lookupLocalMember(name.source); |
| 3576 if (e == null) { | 3604 if (e == null) { |
| 3577 return failOrReturnErroneousElement(resolver.enclosingElement, name, | 3605 return failOrReturnErroneousElement(resolver.enclosingElement, name, |
| 3578 name.source, | 3606 name.source, |
| 3579 MessageKind.CANNOT_RESOLVE, | 3607 MessageKind.CANNOT_RESOLVE, |
| 3580 [name]); | 3608 {'name': name}); |
| 3581 } else if (!identical(e.kind, ElementKind.CLASS)) { | 3609 } else if (!identical(e.kind, ElementKind.CLASS)) { |
| 3582 error(node, MessageKind.NOT_A_TYPE, [name]); | 3610 error(node, MessageKind.NOT_A_TYPE, {'node': name}); |
| 3583 } | 3611 } |
| 3584 } else { | 3612 } else { |
| 3585 internalError(node.receiver, 'unexpected element $e'); | 3613 internalError(node.receiver, 'unexpected element $e'); |
| 3586 } | 3614 } |
| 3587 return e; | 3615 return e; |
| 3588 } | 3616 } |
| 3589 | 3617 |
| 3590 Element visitIdentifier(Identifier node) { | 3618 Element visitIdentifier(Identifier node) { |
| 3591 SourceString name = node.source; | 3619 SourceString name = node.source; |
| 3592 Element e = resolver.lookup(node, name); | 3620 Element e = resolver.lookup(node, name); |
| 3593 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1. | 3621 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1. |
| 3594 if (e == null) { | 3622 if (e == null) { |
| 3595 return failOrReturnErroneousElement(resolver.enclosingElement, node, name, | 3623 return failOrReturnErroneousElement(resolver.enclosingElement, node, name, |
| 3596 MessageKind.CANNOT_RESOLVE, [name]); | 3624 MessageKind.CANNOT_RESOLVE, |
| 3625 {'name': name}); |
| 3597 } else if (e.isErroneous()) { | 3626 } else if (e.isErroneous()) { |
| 3598 return e; | 3627 return e; |
| 3599 } else if (identical(e.kind, ElementKind.TYPEDEF)) { | 3628 } else if (identical(e.kind, ElementKind.TYPEDEF)) { |
| 3600 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]); | 3629 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, |
| 3630 {'typedefName': name}); |
| 3601 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) { | 3631 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) { |
| 3602 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, [name]); | 3632 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, |
| 3633 {'typeVariableName': name}); |
| 3603 } else if (!identical(e.kind, ElementKind.CLASS) | 3634 } else if (!identical(e.kind, ElementKind.CLASS) |
| 3604 && !identical(e.kind, ElementKind.PREFIX)) { | 3635 && !identical(e.kind, ElementKind.PREFIX)) { |
| 3605 error(node, MessageKind.NOT_A_TYPE, [name]); | 3636 error(node, MessageKind.NOT_A_TYPE, {'node': name}); |
| 3606 } | 3637 } |
| 3607 return e; | 3638 return e; |
| 3608 } | 3639 } |
| 3609 | 3640 |
| 3610 /// Assumed to be called by [resolveRedirectingFactory]. | 3641 /// Assumed to be called by [resolveRedirectingFactory]. |
| 3611 Element visitReturn(Return node) { | 3642 Element visitReturn(Return node) { |
| 3612 Node expression = node.expression; | 3643 Node expression = node.expression; |
| 3613 return finishConstructorReference(visit(expression), | 3644 return finishConstructorReference(visit(expression), |
| 3614 expression, expression); | 3645 expression, expression); |
| 3615 } | 3646 } |
| 3616 } | 3647 } |
| OLD | NEW |