| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 import com.google.dart.compiler.ast.Modifiers; | 65 import com.google.dart.compiler.ast.Modifiers; |
| 66 import com.google.dart.compiler.common.HasSourceInfo; | 66 import com.google.dart.compiler.common.HasSourceInfo; |
| 67 import com.google.dart.compiler.common.SourceInfo; | 67 import com.google.dart.compiler.common.SourceInfo; |
| 68 import com.google.dart.compiler.type.InterfaceType; | 68 import com.google.dart.compiler.type.InterfaceType; |
| 69 import com.google.dart.compiler.type.InterfaceType.Member; | 69 import com.google.dart.compiler.type.InterfaceType.Member; |
| 70 import com.google.dart.compiler.type.Type; | 70 import com.google.dart.compiler.type.Type; |
| 71 import com.google.dart.compiler.type.TypeVariable; | 71 import com.google.dart.compiler.type.TypeVariable; |
| 72 import com.google.dart.compiler.util.StringUtils; | 72 import com.google.dart.compiler.util.StringUtils; |
| 73 | 73 |
| 74 import java.util.EnumSet; | 74 import java.util.EnumSet; |
| 75 import java.util.HashSet; | |
| 76 import java.util.Iterator; | 75 import java.util.Iterator; |
| 77 import java.util.List; | 76 import java.util.List; |
| 78 import java.util.Set; | 77 import java.util.Set; |
| 79 | 78 |
| 80 /** | 79 /** |
| 81 * Resolves unqualified elements in a compilation unit. | 80 * Resolves unqualified elements in a compilation unit. |
| 82 */ | 81 */ |
| 83 public class Resolver { | 82 public class Resolver { |
| 84 | 83 |
| 85 private final ResolutionContext topLevelContext; | 84 private final ResolutionContext topLevelContext; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 public Element visitFunctionTypeAlias(DartFunctionTypeAlias alias) { | 221 public Element visitFunctionTypeAlias(DartFunctionTypeAlias alias) { |
| 223 getContext().pushFunctionAliasScope(alias); | 222 getContext().pushFunctionAliasScope(alias); |
| 224 resolveFunctionAlias(alias); | 223 resolveFunctionAlias(alias); |
| 225 getContext().popScope(); | 224 getContext().popScope(); |
| 226 return null; | 225 return null; |
| 227 } | 226 } |
| 228 | 227 |
| 229 @Override | 228 @Override |
| 230 public Element visitClass(DartClass cls) { | 229 public Element visitClass(DartClass cls) { |
| 231 assert currentMethod == null : "nested class?"; | 230 assert currentMethod == null : "nested class?"; |
| 232 ClassElement classElement = cls.getElement(); | 231 ClassNodeElement classElement = cls.getElement(); |
| 233 try { | 232 try { |
| 234 classElement.getAllSupertypes(); | 233 classElement.getAllSupertypes(); |
| 235 } catch (CyclicDeclarationException e) { | 234 } catch (CyclicDeclarationException e) { |
| 236 HasSourceInfo errorTarget = e.getElement(); | 235 HasSourceInfo errorTarget = e.getElement(); |
| 237 if (errorTarget == null) { | 236 if (errorTarget == null) { |
| 238 errorTarget = cls; | 237 errorTarget = cls; |
| 239 } | 238 } |
| 240 onError(errorTarget, ResolverErrorCode.CYCLIC_CLASS, e.getElement().getN
ame()); | 239 onError(errorTarget, ResolverErrorCode.CYCLIC_CLASS, e.getElement().getN
ame()); |
| 241 } catch (DuplicatedInterfaceException e) { | 240 } catch (DuplicatedInterfaceException e) { |
| 242 onError(cls, ResolverErrorCode.DUPLICATED_INTERFACE, | 241 onError(cls, ResolverErrorCode.DUPLICATED_INTERFACE, |
| 243 e.getFirst(), e.getSecond()); | 242 e.getFirst(), e.getSecond()); |
| 244 } | 243 } |
| 245 | 244 |
| 246 checkClassTypeVariables(classElement); | 245 checkClassTypeVariables(classElement); |
| 247 | 246 |
| 248 // Push new resolution context. | 247 // Push new resolution context. |
| 249 ResolutionContext previousContext = context; | 248 ResolutionContext previousContext = context; |
| 250 EnclosingElement previousHolder = currentHolder; | 249 EnclosingElement previousHolder = currentHolder; |
| 251 EnclosingElement previousEnclosingElement = enclosingElement; | 250 EnclosingElement previousEnclosingElement = enclosingElement; |
| 252 currentHolder = classElement; | 251 currentHolder = classElement; |
| 253 enclosingElement = classElement; | 252 enclosingElement = classElement; |
| 254 context = topLevelContext.extend(classElement); | 253 context = topLevelContext.extend(classElement); |
| 255 | 254 |
| 256 this.finalsNeedingInitializing.clear(); | 255 this.finalsNeedingInitializing.clear(); |
| 257 for (Element element : classElement.getMembers()) { | 256 for (NodeElement member : classElement.getMembers()) { |
| 258 element.getNode().accept(this); | 257 member.getNode().accept(this); |
| 259 } | 258 } |
| 260 | 259 |
| 261 boolean testForAllConstantFields = false; | 260 boolean testForAllConstantFields = false; |
| 262 for (DartNode member : cls.getMembers()) { | 261 for (DartNode member : cls.getMembers()) { |
| 263 if (member instanceof DartMethodDefinition) { | 262 if (member instanceof DartMethodDefinition) { |
| 264 DartMethodDefinition method = (DartMethodDefinition) member; | 263 DartMethodDefinition method = (DartMethodDefinition) member; |
| 265 if (method.getElement().isConstructor()) { | 264 if (method.getElement().isConstructor()) { |
| 266 method.accept(this); | 265 method.accept(this); |
| 267 if (method.getModifiers().isConstant()) { | 266 if (method.getModifiers().isConstant()) { |
| 268 testForAllConstantFields = true; | 267 testForAllConstantFields = true; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 ResolverErrorCode.ILLEGAL_CONSTRUCTOR_NO_DEFAULT_IN_INTERFACE)
; | 313 ResolverErrorCode.ILLEGAL_CONSTRUCTOR_NO_DEFAULT_IN_INTERFACE)
; |
| 315 } | 314 } |
| 316 } | 315 } |
| 317 | 316 |
| 318 context = previousContext; | 317 context = previousContext; |
| 319 currentHolder = previousHolder; | 318 currentHolder = previousHolder; |
| 320 enclosingElement = previousEnclosingElement; | 319 enclosingElement = previousEnclosingElement; |
| 321 return classElement; | 320 return classElement; |
| 322 } | 321 } |
| 323 | 322 |
| 324 private void constVerifyMembers(Iterable<Element> members, ClassElement orig
inalClass, | 323 private void constVerifyMembers(Iterable<? extends Element> members, ClassEl
ement originalClass, |
| 325 ClassElement currentClass) { | 324 ClassElement currentClass) { |
| 326 for (Element element : members) { | 325 for (Element element : members) { |
| 327 Modifiers modifiers = element.getModifiers(); | 326 Modifiers modifiers = element.getModifiers(); |
| 328 if (ElementKind.of(element).equals(ElementKind.FIELD) && !modifiers.isFi
nal() | 327 if (ElementKind.of(element).equals(ElementKind.FIELD) && !modifiers.isFi
nal() |
| 329 && !modifiers.isAbstractField()) { | 328 && !modifiers.isAbstractField()) { |
| 330 FieldElement field = (FieldElement) element; | 329 FieldElement field = (FieldElement) element; |
| 331 HasSourceInfo errorNode = field.getSetter() == null ? element : field.
getSetter(); | 330 HasSourceInfo errorNode = field.getSetter() == null ? element : field.
getSetter(); |
| 332 onError(errorNode, currentClass == originalClass | 331 onError(errorNode, currentClass == originalClass |
| 333 ? ResolverErrorCode.CONST_CLASS_WITH_NONFINAL_FIELDS | 332 ? ResolverErrorCode.CONST_CLASS_WITH_NONFINAL_FIELDS |
| 334 : ResolverErrorCode.CONST_CLASS_WITH_INHERITED_NONFINAL_FIELDS, | 333 : ResolverErrorCode.CONST_CLASS_WITH_INHERITED_NONFINAL_FIELDS, |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 if (isStatic) { | 645 if (isStatic) { |
| 647 onError(node, ResolverErrorCode.STATIC_FINAL_REQUIRES_VALUE); | 646 onError(node, ResolverErrorCode.STATIC_FINAL_REQUIRES_VALUE); |
| 648 } else { | 647 } else { |
| 649 // If a final instance field wasn't initialized at declaration, we mus
t check | 648 // If a final instance field wasn't initialized at declaration, we mus
t check |
| 650 // at construction time. | 649 // at construction time. |
| 651 this.finalsNeedingInitializing.add(node.getElement()); | 650 this.finalsNeedingInitializing.add(node.getElement()); |
| 652 } | 651 } |
| 653 } | 652 } |
| 654 | 653 |
| 655 // If field is an accessor, both getter and setter need to be visited (if
present). | 654 // If field is an accessor, both getter and setter need to be visited (if
present). |
| 656 FieldElement field = node.getElement(); | 655 FieldNodeElement field = node.getElement(); |
| 657 if (field.getGetter() != null) { | 656 if (field.getGetter() != null) { |
| 658 resolve(field.getGetter().getNode()); | 657 resolve(field.getGetter().getNode()); |
| 659 } | 658 } |
| 660 if (field.getSetter() != null) { | 659 if (field.getSetter() != null) { |
| 661 resolve(field.getSetter().getNode()); | 660 resolve(field.getSetter().getNode()); |
| 662 } | 661 } |
| 663 return null; | 662 return null; |
| 664 } | 663 } |
| 665 | 664 |
| 666 @Override | 665 @Override |
| (...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1801 * (not <code>null</code>) | 1800 * (not <code>null</code>) |
| 1802 */ | 1801 */ |
| 1803 @Override | 1802 @Override |
| 1804 public DartUnit exec(DartUnit unit, DartCompilerContext context, | 1803 public DartUnit exec(DartUnit unit, DartCompilerContext context, |
| 1805 CoreTypeProvider typeProvider) { | 1804 CoreTypeProvider typeProvider) { |
| 1806 Scope unitScope = unit.getLibrary().getElement().getScope(); | 1805 Scope unitScope = unit.getLibrary().getElement().getScope(); |
| 1807 return new Resolver(context, unitScope, typeProvider).exec(unit); | 1806 return new Resolver(context, unitScope, typeProvider).exec(unit); |
| 1808 } | 1807 } |
| 1809 } | 1808 } |
| 1810 | 1809 |
| 1811 private void checkRedirectConstructorCycle(List<ConstructorElement> constructo
rs, | 1810 private void checkRedirectConstructorCycle(List<ConstructorNodeElement> constr
uctors, |
| 1812 ResolutionContext context) { | 1811 ResolutionContext context) { |
| 1813 for (ConstructorElement element : constructors) { | 1812 for (ConstructorNodeElement element : constructors) { |
| 1814 if (hasRedirectedConstructorCycle(element)) { | 1813 if (hasRedirectedConstructorCycle(element)) { |
| 1815 context.onError(element, ResolverErrorCode.REDIRECTED_CONSTRUCTOR_CYCLE)
; | 1814 context.onError(element, ResolverErrorCode.REDIRECTED_CONSTRUCTOR_CYCLE)
; |
| 1816 } | 1815 } |
| 1817 } | 1816 } |
| 1818 } | 1817 } |
| 1819 | 1818 |
| 1820 private boolean hasRedirectedConstructorCycle(ConstructorElement constructorEl
ement) { | 1819 private boolean hasRedirectedConstructorCycle(ConstructorNodeElement construct
orElement) { |
| 1821 HashSet<ConstructorElement> visited = new HashSet<ConstructorElement>(); | 1820 Set<ConstructorNodeElement> visited = Sets.newHashSet(); |
| 1822 ConstructorElement next = getNextConstructorInvocation(constructorElement); | 1821 ConstructorNodeElement next = getNextConstructorInvocation(constructorElemen
t); |
| 1823 while (next != null) { | 1822 while (next != null) { |
| 1824 if (visited.contains(next)) { | 1823 if (visited.contains(next)) { |
| 1825 return true; | 1824 return true; |
| 1826 } | 1825 } |
| 1827 if (constructorElement.getName().equals(next.getName())) { | 1826 if (constructorElement.getName().equals(next.getName())) { |
| 1828 return true; | 1827 return true; |
| 1829 } | 1828 } |
| 1830 visited.add(next); | 1829 visited.add(next); |
| 1831 next = getNextConstructorInvocation(next); | 1830 next = getNextConstructorInvocation(next); |
| 1832 } | 1831 } |
| 1833 return false; | 1832 return false; |
| 1834 } | 1833 } |
| 1835 | 1834 |
| 1836 private ConstructorElement getNextConstructorInvocation(ConstructorElement con
structor) { | 1835 private ConstructorNodeElement getNextConstructorInvocation(ConstructorNodeEle
ment constructor) { |
| 1837 List<DartInitializer> inits = ((DartMethodDefinition) constructor.getNode())
.getInitializers(); | 1836 List<DartInitializer> inits = ((DartMethodDefinition) constructor.getNode())
.getInitializers(); |
| 1838 // The parser ensures that redirected constructors can be the only item in t
he initialization | 1837 // Parser ensures that redirected constructors can be the only item in the i
nitialization list. |
| 1839 // list. | |
| 1840 if (inits.size() == 1) { | 1838 if (inits.size() == 1) { |
| 1841 Element element = (Element) inits.get(0).getValue().getElement(); | 1839 Element element = (Element) inits.get(0).getValue().getElement(); |
| 1842 if (ElementKind.of(element).equals(ElementKind.CONSTRUCTOR)) { | 1840 if (ElementKind.of(element).equals(ElementKind.CONSTRUCTOR)) { |
| 1843 ConstructorElement nextConstructorElement = (ConstructorElement) element
; | 1841 ConstructorElement nextConstructorElement = (ConstructorElement) element
; |
| 1844 ClassElement nextClass = (ClassElement) nextConstructorElement.getEnclos
ingElement(); | 1842 ClassElement nextClass = (ClassElement) nextConstructorElement.getEnclos
ingElement(); |
| 1845 ClassElement currentClass = (ClassElement) constructor.getEnclosingEleme
nt(); | 1843 ClassElement currentClass = (ClassElement) constructor.getEnclosingEleme
nt(); |
| 1846 if (nextClass == currentClass) { | 1844 if (nextClass == currentClass) { |
| 1847 return nextConstructorElement; | 1845 return (ConstructorNodeElement) nextConstructorElement; |
| 1848 } | 1846 } |
| 1849 } | 1847 } |
| 1850 } | 1848 } |
| 1851 return null; | 1849 return null; |
| 1852 } | 1850 } |
| 1853 } | 1851 } |
| OLD | NEW |