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 package com.google.dart.compiler.resolver; | 5 package com.google.dart.compiler.resolver; |
6 | 6 |
7 import com.google.common.annotations.VisibleForTesting; | 7 import com.google.common.annotations.VisibleForTesting; |
8 import com.google.common.collect.Lists; | 8 import com.google.common.collect.Lists; |
9 import com.google.common.collect.Sets; | 9 import com.google.common.collect.Sets; |
10 import com.google.dart.compiler.DartCompilationPhase; | 10 import com.google.dart.compiler.DartCompilationPhase; |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 @Override | 227 @Override |
228 public Element visitUnit(DartUnit unit) { | 228 public Element visitUnit(DartUnit unit) { |
229 for (DartDirective directive : unit.getDirectives()) { | 229 for (DartDirective directive : unit.getDirectives()) { |
230 if (directive instanceof DartPartOfDirective) { | 230 if (directive instanceof DartPartOfDirective) { |
231 directive.accept(this); | 231 directive.accept(this); |
232 } | 232 } |
233 } | 233 } |
234 for (DartNode node : unit.getTopLevelNodes()) { | 234 for (DartNode node : unit.getTopLevelNodes()) { |
235 node.accept(this); | 235 node.accept(this); |
236 } | 236 } |
| 237 checkRedirectingFactoryConstructorsCycle(unit); |
237 return null; | 238 return null; |
238 } | 239 } |
239 | 240 |
| 241 private void checkRedirectingFactoryConstructorsCycle(DartUnit unit) { |
| 242 unit.accept(new ASTVisitor<Void>() { |
| 243 @Override |
| 244 public Void visitMethodDefinition(DartMethodDefinition node) { |
| 245 MethodNodeElement element = node.getElement(); |
| 246 if (ElementKind.of(element) == ElementKind.CONSTRUCTOR) { |
| 247 ConstructorElement constructor = (ConstructorElement) element; |
| 248 if (hasRedirectingFactoryConstructorCycle(constructor)) { |
| 249 onError(constructor.getNameLocation(), |
| 250 ResolverErrorCode.REDIRECTION_CONSTRUCTOR_CYCLE); |
| 251 } |
| 252 } |
| 253 return super.visitMethodDefinition(node); |
| 254 } |
| 255 }); |
| 256 } |
| 257 |
| 258 private boolean hasRedirectingFactoryConstructorCycle(ConstructorElement ele
ment) { |
| 259 Set<ConstructorElement> constructors = Sets.newHashSet(); |
| 260 while (element != null) { |
| 261 if (constructors.contains(element)) { |
| 262 return true; |
| 263 } |
| 264 constructors.add(element); |
| 265 element = element.getRedirectingFactoryConstructor(); |
| 266 } |
| 267 return false; |
| 268 } |
| 269 |
240 @Override | 270 @Override |
241 public Element visitFunctionTypeAlias(DartFunctionTypeAlias alias) { | 271 public Element visitFunctionTypeAlias(DartFunctionTypeAlias alias) { |
242 alias.getMetadata().accept(this); | 272 alias.getMetadata().accept(this); |
243 getContext().pushFunctionAliasScope(alias); | 273 getContext().pushFunctionAliasScope(alias); |
244 resolveFunctionAlias(alias); | 274 resolveFunctionAlias(alias); |
245 | 275 |
246 getContext().pushScope("<parameters>"); | 276 getContext().pushScope("<parameters>"); |
247 try { | 277 try { |
248 List<DartParameter> parameters = alias.getParameters(); | 278 List<DartParameter> parameters = alias.getParameters(); |
249 for (DartParameter parameter : parameters) { | 279 for (DartParameter parameter : parameters) { |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 } | 722 } |
693 | 723 |
694 // resolve redirecting factory constructor | 724 // resolve redirecting factory constructor |
695 { | 725 { |
696 DartTypeNode rcTypeName = node.getRedirectedTypeName(); | 726 DartTypeNode rcTypeName = node.getRedirectedTypeName(); |
697 if (rcTypeName != null) { | 727 if (rcTypeName != null) { |
698 Type rcType = resolveType(rcTypeName, true, true, false, | 728 Type rcType = resolveType(rcTypeName, true, true, false, |
699 TypeErrorCode.NO_SUCH_TYPE, ResolverErrorCode.WRONG_NUMBER_OF_TYPE
_ARGUMENTS); | 729 TypeErrorCode.NO_SUCH_TYPE, ResolverErrorCode.WRONG_NUMBER_OF_TYPE
_ARGUMENTS); |
700 switch (TypeKind.of(rcType)) { | 730 switch (TypeKind.of(rcType)) { |
701 case INTERFACE: | 731 case INTERFACE: |
| 732 ConstructorElement targetConstructor = null; |
702 Element element = recordType(rcTypeName, rcType); | 733 Element element = recordType(rcTypeName, rcType); |
703 DartIdentifier rcName = node.getRedirectedConstructorName(); | 734 DartIdentifier rcName = node.getRedirectedConstructorName(); |
704 if (rcName != null) { | 735 if (rcName != null) { |
705 element = ((ClassElement) element).lookupConstructor(rcName.getN
ame()); | 736 element = ((ClassElement) element).lookupConstructor(rcName.getN
ame()); |
706 switch (ElementKind.of(element)) { | 737 switch (ElementKind.of(element)) { |
707 case CONSTRUCTOR: | 738 case CONSTRUCTOR: |
| 739 targetConstructor = (ConstructorElement) element; |
708 recordElement(rcName, element); | 740 recordElement(rcName, element); |
709 if (member.getModifiers().isConstant() && !element.getModifi
ers().isConstant()) { | 741 if (member.getModifiers().isConstant() && !element.getModifi
ers().isConstant()) { |
710 onError(rcName, | 742 onError(rcName, |
711 ResolverErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_MUST_
BE_CONST); | 743 ResolverErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_MUST_
BE_CONST); |
712 } | 744 } |
713 break; | 745 break; |
714 } | 746 } |
| 747 } else { |
| 748 targetConstructor = ((ClassElement) element).lookupConstructor(e
lement.getName()); |
715 } | 749 } |
| 750 Elements.setRedirectingFactoryConstructor(((ConstructorElement) me
mber), |
| 751 targetConstructor); |
716 break; | 752 break; |
717 default: | 753 default: |
718 onError(rcTypeName, ResolverErrorCode.REDIRECTION_CONSTRUCTOR_TARG
ET_TYPE); | 754 onError(rcTypeName, ResolverErrorCode.REDIRECTION_CONSTRUCTOR_TARG
ET_TYPE); |
719 } | 755 } |
720 } | 756 } |
721 } | 757 } |
722 | 758 |
723 context = previousContext; | 759 context = previousContext; |
724 innermostFunction = currentMethod = null; | 760 innermostFunction = currentMethod = null; |
725 enclosingElement = previousEnclosingElement; | 761 enclosingElement = previousEnclosingElement; |
(...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2383 ClassElement currentClass = (ClassElement) constructor.getEnclosingEle
ment(); | 2419 ClassElement currentClass = (ClassElement) constructor.getEnclosingEle
ment(); |
2384 if (nextClass == currentClass) { | 2420 if (nextClass == currentClass) { |
2385 return (ConstructorNodeElement) nextConstructorElement; | 2421 return (ConstructorNodeElement) nextConstructorElement; |
2386 } | 2422 } |
2387 } | 2423 } |
2388 } | 2424 } |
2389 } | 2425 } |
2390 return null; | 2426 return null; |
2391 } | 2427 } |
2392 } | 2428 } |
OLD | NEW |