| 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 get currentElement; | 8 Element get currentElement; |
| 9 Set<Node> get superUses; | 9 Set<Node> get superUses; |
| 10 | 10 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 element.computeType(compiler); | 177 element.computeType(compiler); |
| 178 return null; | 178 return null; |
| 179 } | 179 } |
| 180 | 180 |
| 181 compiler.unimplemented("resolve($element)", | 181 compiler.unimplemented("resolve($element)", |
| 182 node: element.parseNode(compiler)); | 182 node: element.parseNode(compiler)); |
| 183 }); | 183 }); |
| 184 } | 184 } |
| 185 | 185 |
| 186 String constructorNameForDiagnostics(SourceString className, | 186 String constructorNameForDiagnostics(SourceString className, |
| 187 SourceString constructorName) { | 187 SourceString constructorName) { |
| 188 String classNameString = className.slowToString(); | 188 String classNameString = className.slowToString(); |
| 189 String constructorNameString = constructorName.slowToString(); | 189 String constructorNameString = constructorName.slowToString(); |
| 190 return (constructorName == const SourceString('')) | 190 return (constructorName == const SourceString('')) |
| 191 ? classNameString | 191 ? classNameString |
| 192 : "$classNameString.$constructorNameString"; | 192 : "$classNameString.$constructorNameString"; |
| 193 } | 193 } |
| 194 | 194 |
| 195 void resolveRedirectingConstructor(InitializerResolver resolver, | 195 void resolveRedirectingConstructor(InitializerResolver resolver, |
| 196 Node node, | 196 Node node, |
| 197 FunctionElement constructor, | 197 FunctionElement constructor, |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 member.modifiers.flags & | 665 member.modifiers.flags & |
| 666 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); | 666 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); |
| 667 if (mismatchedFlagsBits != 0) { | 667 if (mismatchedFlagsBits != 0) { |
| 668 final mismatchedFlags = | 668 final mismatchedFlags = |
| 669 new Modifiers.withFlags(null, mismatchedFlagsBits); | 669 new Modifiers.withFlags(null, mismatchedFlagsBits); |
| 670 compiler.reportErrorCode( | 670 compiler.reportErrorCode( |
| 671 member, | 671 member, |
| 672 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS, | 672 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS, |
| 673 {'modifiers': mismatchedFlags}); | 673 {'modifiers': mismatchedFlags}); |
| 674 } | 674 } |
| 675 checkConstructorNameHack(holder, member); | |
| 676 } | 675 } |
| 677 checkAbstractField(member); | 676 checkAbstractField(member); |
| 678 checkValidOverride(member, cls.lookupSuperMember(member.name)); | 677 checkValidOverride(member, cls.lookupSuperMember(member.name)); |
| 679 checkUserDefinableOperator(member); | 678 checkUserDefinableOperator(member); |
| 680 }); | 679 }); |
| 681 }); | 680 }); |
| 682 } | 681 } |
| 683 | 682 |
| 684 // TODO(ahe): Remove this method. It is only needed while we store | |
| 685 // constructor names as ClassName$id. Once we start storing | |
| 686 // constructors as just id, this will be caught by the general | |
| 687 // mechanism for duplicate members. | |
| 688 /// Check that a constructor name does not conflict with a member. | |
| 689 void checkConstructorNameHack(ClassElement holder, FunctionElement member) { | |
| 690 // If the name of the constructor is the same as the name of the | |
| 691 // class, there cannot be a problem. | |
| 692 if (member.name == holder.name) return; | |
| 693 | |
| 694 SourceString name = | |
| 695 Elements.deconstructConstructorName(member.name, holder); | |
| 696 | |
| 697 // If the name could not be deconstructed, this is is from a | |
| 698 // factory method from a deprecated interface implementation. | |
| 699 if (name == null) return; | |
| 700 | |
| 701 Element otherMember = holder.lookupLocalMember(name); | |
| 702 if (otherMember != null) { | |
| 703 if (compiler.onDeprecatedFeature(member, 'conflicting constructor')) { | |
| 704 compiler.reportMessage( | |
| 705 compiler.spanFromElement(otherMember), | |
| 706 // Using GENERIC as this message is temporary. | |
| 707 MessageKind.GENERIC.error({'text': 'This member conflicts with a' | |
| 708 ' constructor.'}), | |
| 709 Diagnostic.INFO); | |
| 710 } | |
| 711 } | |
| 712 } | |
| 713 | |
| 714 void checkAbstractField(Element member) { | 683 void checkAbstractField(Element member) { |
| 715 // Only check for getters. The test can only fail if there is both a setter | 684 // Only check for getters. The test can only fail if there is both a setter |
| 716 // and a getter with the same name, and we only need to check each abstract | 685 // and a getter with the same name, and we only need to check each abstract |
| 717 // field once, so we just ignore setters. | 686 // field once, so we just ignore setters. |
| 718 if (!member.isGetter()) return; | 687 if (!member.isGetter()) return; |
| 719 | 688 |
| 720 // Find the associated abstract field. | 689 // Find the associated abstract field. |
| 721 ClassElement classElement = member.getEnclosingClass(); | 690 ClassElement classElement = member.getEnclosingClass(); |
| 722 Element lookupElement = classElement.lookupLocalMember(member.name); | 691 Element lookupElement = classElement.lookupLocalMember(member.name); |
| 723 if (lookupElement == null) { | 692 if (lookupElement == null) { |
| (...skipping 2612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3336 compiler.getNextFreeClassId(), | 3305 compiler.getNextFreeClassId(), |
| 3337 element.parseNode(compiler), | 3306 element.parseNode(compiler), |
| 3338 Modifiers.EMPTY); // TODO(kasperl): Should this be abstract? | 3307 Modifiers.EMPTY); // TODO(kasperl): Should this be abstract? |
| 3339 doApplyMixinTo(mixinApplication, supertype, mixinType); | 3308 doApplyMixinTo(mixinApplication, supertype, mixinType); |
| 3340 mixinApplication.resolutionState = STATE_DONE; | 3309 mixinApplication.resolutionState = STATE_DONE; |
| 3341 mixinApplication.supertypeLoadState = STATE_DONE; | 3310 mixinApplication.supertypeLoadState = STATE_DONE; |
| 3342 return mixinApplication.computeType(compiler); | 3311 return mixinApplication.computeType(compiler); |
| 3343 } | 3312 } |
| 3344 | 3313 |
| 3345 bool isDefaultConstructor(FunctionElement constructor) { | 3314 bool isDefaultConstructor(FunctionElement constructor) { |
| 3346 return constructor.name == constructor.getEnclosingClass().name && | 3315 return constructor.name == const SourceString('') && |
| 3347 constructor.computeSignature(compiler).parameterCount == 0; | 3316 constructor.computeSignature(compiler).parameterCount == 0; |
| 3348 } | 3317 } |
| 3349 | 3318 |
| 3350 FunctionElement createForwardingConstructor(FunctionElement constructor, | 3319 FunctionElement createForwardingConstructor(FunctionElement constructor, |
| 3351 ClassElement target) { | 3320 ClassElement target) { |
| 3352 ClassElement cls = constructor.getEnclosingClass(); | 3321 return new SynthesizedConstructorElementX.forwarding(constructor.name, |
| 3353 SourceString constructorName; | |
| 3354 if (constructor.name == cls.name) { | |
| 3355 constructorName = target.name; | |
| 3356 } else { | |
| 3357 SourceString selector = | |
| 3358 Elements.deconstructConstructorName(constructor.name, cls); | |
| 3359 constructorName = | |
| 3360 Elements.constructConstructorName(target.name, selector); | |
| 3361 } | |
| 3362 return new SynthesizedConstructorElementX.forwarding(constructorName, | |
| 3363 constructor, | 3322 constructor, |
| 3364 target); | 3323 target); |
| 3365 } | 3324 } |
| 3366 | 3325 |
| 3367 void doApplyMixinTo(MixinApplicationElement mixinApplication, | 3326 void doApplyMixinTo(MixinApplicationElement mixinApplication, |
| 3368 DartType supertype, | 3327 DartType supertype, |
| 3369 DartType mixinType) { | 3328 DartType mixinType) { |
| 3370 Node node = mixinApplication.parseNode(compiler); | 3329 Node node = mixinApplication.parseNode(compiler); |
| 3371 | 3330 |
| 3372 if (mixinApplication.supertype != null) { | 3331 if (mixinApplication.supertype != null) { |
| (...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4061 return e; | 4020 return e; |
| 4062 } | 4021 } |
| 4063 | 4022 |
| 4064 /// Assumed to be called by [resolveRedirectingFactory]. | 4023 /// Assumed to be called by [resolveRedirectingFactory]. |
| 4065 Element visitReturn(Return node) { | 4024 Element visitReturn(Return node) { |
| 4066 Node expression = node.expression; | 4025 Node expression = node.expression; |
| 4067 return finishConstructorReference(visit(expression), | 4026 return finishConstructorReference(visit(expression), |
| 4068 expression, expression); | 4027 expression, expression); |
| 4069 } | 4028 } |
| 4070 } | 4029 } |
| OLD | NEW |