| 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 Setlet<Node> get superUses; | 9 Setlet<Node> get superUses; |
| 10 | 10 |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 final ConstantCompiler constantCompiler; | 252 final ConstantCompiler constantCompiler; |
| 253 | 253 |
| 254 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler); | 254 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler); |
| 255 | 255 |
| 256 String get name => 'Resolver'; | 256 String get name => 'Resolver'; |
| 257 | 257 |
| 258 TreeElements resolve(Element element) { | 258 TreeElements resolve(Element element) { |
| 259 return measure(() { | 259 return measure(() { |
| 260 if (Elements.isErroneousElement(element)) return null; | 260 if (Elements.isErroneousElement(element)) return null; |
| 261 | 261 |
| 262 for (MetadataAnnotation metadata in element.metadata) { | 262 processMetadata([result]) { |
| 263 metadata.ensureResolved(compiler); | 263 for (MetadataAnnotation metadata in element.metadata) { |
| 264 metadata.ensureResolved(compiler); |
| 265 } |
| 266 return result; |
| 264 } | 267 } |
| 265 | 268 |
| 266 ElementKind kind = element.kind; | 269 ElementKind kind = element.kind; |
| 267 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || | 270 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || |
| 268 identical(kind, ElementKind.FUNCTION) || | 271 identical(kind, ElementKind.FUNCTION) || |
| 269 identical(kind, ElementKind.GETTER) || | 272 identical(kind, ElementKind.GETTER) || |
| 270 identical(kind, ElementKind.SETTER)) { | 273 identical(kind, ElementKind.SETTER)) { |
| 271 return resolveMethodElement(element); | 274 return processMetadata(resolveMethodElement(element)); |
| 272 } | 275 } |
| 273 | 276 |
| 274 if (identical(kind, ElementKind.FIELD)) return resolveField(element); | 277 if (identical(kind, ElementKind.FIELD)) { |
| 275 | 278 return processMetadata(resolveField(element)); |
| 279 } |
| 276 if (element.isClass) { | 280 if (element.isClass) { |
| 277 ClassElement cls = element; | 281 ClassElement cls = element; |
| 278 cls.ensureResolved(compiler); | 282 cls.ensureResolved(compiler); |
| 279 return null; | 283 return processMetadata(); |
| 280 } else if (element.isTypedef) { | 284 } else if (element.isTypedef) { |
| 281 TypedefElement typdef = element; | 285 TypedefElement typdef = element; |
| 282 return resolveTypedef(typdef); | 286 return processMetadata(resolveTypedef(typdef)); |
| 283 } | 287 } |
| 284 | 288 |
| 285 compiler.unimplemented(element, "resolve($element)"); | 289 compiler.unimplemented(element, "resolve($element)"); |
| 286 }); | 290 }); |
| 287 } | 291 } |
| 288 | 292 |
| 289 String constructorNameForDiagnostics(String className, | 293 String constructorNameForDiagnostics(String className, |
| 290 String constructorName) { | 294 String constructorName) { |
| 291 String classNameString = className; | 295 String classNameString = className; |
| 292 String constructorNameString = constructorName; | 296 String constructorNameString = constructorName; |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 for (MixinApplicationElement mixinApplication in mixinUses) { | 543 for (MixinApplicationElement mixinApplication in mixinUses) { |
| 540 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); | 544 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); |
| 541 } | 545 } |
| 542 } | 546 } |
| 543 } | 547 } |
| 544 return resolutionTree; | 548 return resolutionTree; |
| 545 }); | 549 }); |
| 546 }); | 550 }); |
| 547 } | 551 } |
| 548 | 552 |
| 553 /// Creates a [ResolverVisitor] for resolving an AST in context of [element]. |
| 554 /// If [useEnclosingScope] is `true` then the initial scope of the visitor |
| 555 /// does not include inner scope of [element]. |
| 556 /// |
| 549 /// This method should only be used by this library (or tests of | 557 /// This method should only be used by this library (or tests of |
| 550 /// this library). | 558 /// this library). |
| 551 ResolverVisitor visitorFor(Element element) { | 559 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { |
| 552 return new ResolverVisitor(compiler, element, | 560 return new ResolverVisitor(compiler, element, |
| 553 new ResolutionRegistry(compiler, element)); | 561 new ResolutionRegistry(compiler, element), |
| 562 useEnclosingScope: useEnclosingScope); |
| 554 } | 563 } |
| 555 | 564 |
| 556 TreeElements resolveField(VariableElementX element) { | 565 TreeElements resolveField(VariableElementX element) { |
| 557 VariableDefinitions tree = element.parseNode(compiler); | 566 VariableDefinitions tree = element.parseNode(compiler); |
| 558 if(element.modifiers.isStatic && element.isTopLevel) { | 567 if(element.modifiers.isStatic && element.isTopLevel) { |
| 559 error(element.modifiers.getStatic(), | 568 error(element.modifiers.getStatic(), |
| 560 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 569 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
| 561 } | 570 } |
| 562 ResolverVisitor visitor = visitorFor(element); | 571 ResolverVisitor visitor = visitorFor(element); |
| 563 ResolutionRegistry registry = visitor.registry; | 572 ResolutionRegistry registry = visitor.registry; |
| (...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 defaultValuesError: defaultValuesError)); | 1177 defaultValuesError: defaultValuesError)); |
| 1169 }); | 1178 }); |
| 1170 } | 1179 } |
| 1171 | 1180 |
| 1172 TreeElements resolveTypedef(TypedefElementX element) { | 1181 TreeElements resolveTypedef(TypedefElementX element) { |
| 1173 if (element.isResolved) return element.treeElements; | 1182 if (element.isResolved) return element.treeElements; |
| 1174 return _resolveTypeDeclaration(element, () { | 1183 return _resolveTypeDeclaration(element, () { |
| 1175 ResolutionRegistry registry = new ResolutionRegistry(compiler, element); | 1184 ResolutionRegistry registry = new ResolutionRegistry(compiler, element); |
| 1176 return compiler.withCurrentElement(element, () { | 1185 return compiler.withCurrentElement(element, () { |
| 1177 return measure(() { | 1186 return measure(() { |
| 1187 assert(element.resolutionState == STATE_NOT_STARTED); |
| 1188 element.resolutionState = STATE_STARTED; |
| 1178 Typedef node = | 1189 Typedef node = |
| 1179 compiler.parser.measure(() => element.parseNode(compiler)); | 1190 compiler.parser.measure(() => element.parseNode(compiler)); |
| 1180 TypedefResolverVisitor visitor = | 1191 TypedefResolverVisitor visitor = |
| 1181 new TypedefResolverVisitor(compiler, element, registry); | 1192 new TypedefResolverVisitor(compiler, element, registry); |
| 1182 visitor.visit(node); | 1193 visitor.visit(node); |
| 1183 | 1194 element.resolutionState = STATE_DONE; |
| 1184 return registry.mapping; | 1195 return registry.mapping; |
| 1185 }); | 1196 }); |
| 1186 }); | 1197 }); |
| 1187 }); | 1198 }); |
| 1188 } | 1199 } |
| 1189 | 1200 |
| 1190 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { | 1201 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { |
| 1191 compiler.withCurrentElement(annotation.annotatedElement, () => measure(() { | 1202 compiler.withCurrentElement(annotation.annotatedElement, () => measure(() { |
| 1192 assert(annotation.resolutionState == STATE_NOT_STARTED); | 1203 assert(annotation.resolutionState == STATE_NOT_STARTED); |
| 1193 annotation.resolutionState = STATE_STARTED; | 1204 annotation.resolutionState = STATE_STARTED; |
| 1194 | 1205 |
| 1195 Node node = annotation.parseNode(compiler); | 1206 Node node = annotation.parseNode(compiler); |
| 1196 // TODO(johnniwinther): Find the right analyzable element to hold the | |
| 1197 // [TreeElements] for the annotation. | |
| 1198 Element annotatedElement = annotation.annotatedElement; | 1207 Element annotatedElement = annotation.annotatedElement; |
| 1199 Element context = annotatedElement.enclosingElement; | 1208 AnalyzableElement context = annotatedElement.analyzableElement; |
| 1200 if (context == null) { | 1209 assert(invariant(node, context != null, |
| 1201 context = annotatedElement; | 1210 message: "No context found for metadata annotation " |
| 1202 } | 1211 "on $annotatedElement.")); |
| 1203 ResolverVisitor visitor = visitorFor(context); | 1212 ResolverVisitor visitor = visitorFor(context, useEnclosingScope: true); |
| 1204 ResolutionRegistry registry = visitor.registry; | 1213 ResolutionRegistry registry = visitor.registry; |
| 1205 node.accept(visitor); | 1214 node.accept(visitor); |
| 1206 // TODO(johnniwinther): Avoid passing the [TreeElements] to | 1215 // TODO(johnniwinther): Avoid passing the [TreeElements] to |
| 1207 // [compileMetadata]. | 1216 // [compileMetadata]. |
| 1208 annotation.value = | 1217 annotation.value = |
| 1209 constantCompiler.compileMetadata(annotation, node, registry.mapping); | 1218 constantCompiler.compileMetadata(annotation, node, registry.mapping); |
| 1210 // TODO(johnniwinther): Register the relation between the annotation | 1219 // TODO(johnniwinther): Register the relation between the annotation |
| 1211 // and the annotated element instead. This will allow the backed to | 1220 // and the annotated element instead. This will allow the backend to |
| 1212 // retrieve the backend constant and only registered metadata on the | 1221 // retrieve the backend constant and only register metadata on the |
| 1213 // elements for which it is needed. (Issue 17732). | 1222 // elements for which it is needed. (Issue 17732). |
| 1214 registry.registerMetadataConstant(annotation.value); | 1223 registry.registerMetadataConstant(annotation.value); |
| 1215 annotation.resolutionState = STATE_DONE; | 1224 annotation.resolutionState = STATE_DONE; |
| 1216 })); | 1225 })); |
| 1217 } | 1226 } |
| 1218 | 1227 |
| 1219 error(Spannable node, MessageKind kind, [arguments = const {}]) { | 1228 error(Spannable node, MessageKind kind, [arguments = const {}]) { |
| 1220 // TODO(ahe): Make non-fatal. | 1229 // TODO(ahe): Make non-fatal. |
| 1221 compiler.reportFatalError(node, kind, arguments); | 1230 compiler.reportFatalError(node, kind, arguments); |
| 1222 } | 1231 } |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1759 erroneousElement: erroneousElement); | 1768 erroneousElement: erroneousElement); |
| 1760 } else if (!element.impliesType) { | 1769 } else if (!element.impliesType) { |
| 1761 type = reportFailureAndCreateType( | 1770 type = reportFailureAndCreateType( |
| 1762 MessageKind.NOT_A_TYPE, {'node': node.typeName}); | 1771 MessageKind.NOT_A_TYPE, {'node': node.typeName}); |
| 1763 } else { | 1772 } else { |
| 1764 bool addTypeVariableBoundsCheck = false; | 1773 bool addTypeVariableBoundsCheck = false; |
| 1765 if (identical(element, compiler.dynamicClass)) { | 1774 if (identical(element, compiler.dynamicClass)) { |
| 1766 type = checkNoTypeArguments(element.computeType(compiler)); | 1775 type = checkNoTypeArguments(element.computeType(compiler)); |
| 1767 } else if (element.isClass) { | 1776 } else if (element.isClass) { |
| 1768 ClassElement cls = element; | 1777 ClassElement cls = element; |
| 1778 // TODO(johnniwinther): [_ensureClassWillBeResolved] should imply |
| 1779 // [computeType]. |
| 1769 compiler.resolver._ensureClassWillBeResolved(cls); | 1780 compiler.resolver._ensureClassWillBeResolved(cls); |
| 1770 element.computeType(compiler); | 1781 element.computeType(compiler); |
| 1771 var arguments = new LinkBuilder<DartType>(); | 1782 var arguments = new LinkBuilder<DartType>(); |
| 1772 bool hasTypeArgumentMismatch = resolveTypeArguments( | 1783 bool hasTypeArgumentMismatch = resolveTypeArguments( |
| 1773 visitor, node, cls.typeVariables, arguments); | 1784 visitor, node, cls.typeVariables, arguments); |
| 1774 if (hasTypeArgumentMismatch) { | 1785 if (hasTypeArgumentMismatch) { |
| 1775 type = new BadInterfaceType(cls.declaration, | 1786 type = new BadInterfaceType(cls.declaration, |
| 1776 new InterfaceType.forUserProvidedBadType(cls.declaration, | 1787 new InterfaceType.forUserProvidedBadType(cls.declaration, |
| 1777 arguments.toLink())); | 1788 arguments.toLink())); |
| 1778 } else { | 1789 } else { |
| 1779 if (arguments.isEmpty) { | 1790 if (arguments.isEmpty) { |
| 1780 type = cls.rawType; | 1791 type = cls.rawType; |
| 1781 } else { | 1792 } else { |
| 1782 type = new InterfaceType(cls.declaration, arguments.toLink()); | 1793 type = new InterfaceType(cls.declaration, arguments.toLink()); |
| 1783 addTypeVariableBoundsCheck = true; | 1794 addTypeVariableBoundsCheck = true; |
| 1784 } | 1795 } |
| 1785 } | 1796 } |
| 1786 } else if (element.isTypedef) { | 1797 } else if (element.isTypedef) { |
| 1787 TypedefElement typdef = element; | 1798 TypedefElement typdef = element; |
| 1788 // TODO(ahe): Should be [ensureResolved]. | 1799 // TODO(johnniwinther): [ensureResolved] should imply [computeType]. |
| 1789 compiler.resolveTypedef(typdef); | 1800 typdef.ensureResolved(compiler); |
| 1801 element.computeType(compiler); |
| 1790 var arguments = new LinkBuilder<DartType>(); | 1802 var arguments = new LinkBuilder<DartType>(); |
| 1791 bool hasTypeArgumentMismatch = resolveTypeArguments( | 1803 bool hasTypeArgumentMismatch = resolveTypeArguments( |
| 1792 visitor, node, typdef.typeVariables, arguments); | 1804 visitor, node, typdef.typeVariables, arguments); |
| 1793 if (hasTypeArgumentMismatch) { | 1805 if (hasTypeArgumentMismatch) { |
| 1794 type = new BadTypedefType(typdef, | 1806 type = new BadTypedefType(typdef, |
| 1795 new TypedefType.forUserProvidedBadType(typdef, | 1807 new TypedefType.forUserProvidedBadType(typdef, |
| 1796 arguments.toLink())); | 1808 arguments.toLink())); |
| 1797 } else { | 1809 } else { |
| 1798 if (arguments.isEmpty) { | 1810 if (arguments.isEmpty) { |
| 1799 type = typdef.rawType; | 1811 type = typdef.rawType; |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1995 r'>|' | 2007 r'>|' |
| 1996 r'<=|' | 2008 r'<=|' |
| 1997 r'<|' | 2009 r'<|' |
| 1998 r'&|' | 2010 r'&|' |
| 1999 r'\^|' | 2011 r'\^|' |
| 2000 r'\|' | 2012 r'\|' |
| 2001 r')$'); | 2013 r')$'); |
| 2002 | 2014 |
| 2003 ResolverVisitor(Compiler compiler, | 2015 ResolverVisitor(Compiler compiler, |
| 2004 Element element, | 2016 Element element, |
| 2005 ResolutionRegistry registry) | 2017 ResolutionRegistry registry, |
| 2018 {bool useEnclosingScope: false}) |
| 2006 : this.enclosingElement = element, | 2019 : this.enclosingElement = element, |
| 2007 // When the element is a field, we are actually resolving its | 2020 // When the element is a field, we are actually resolving its |
| 2008 // initial value, which should not have access to instance | 2021 // initial value, which should not have access to instance |
| 2009 // fields. | 2022 // fields. |
| 2010 inInstanceContext = (element.isInstanceMember && !element.isField) | 2023 inInstanceContext = (element.isInstanceMember && !element.isField) |
| 2011 || element.isGenerativeConstructor, | 2024 || element.isGenerativeConstructor, |
| 2012 this.currentClass = element.isMember ? element.enclosingClass | 2025 this.currentClass = element.isMember ? element.enclosingClass |
| 2013 : null, | 2026 : null, |
| 2014 this.statementScope = new StatementScope(), | 2027 this.statementScope = new StatementScope(), |
| 2015 scope = element.buildScope(), | 2028 scope = useEnclosingScope |
| 2029 ? Scope.buildEnclosingScope(element) : element.buildScope(), |
| 2016 // The type annotations on a typedef do not imply type checks. | 2030 // The type annotations on a typedef do not imply type checks. |
| 2017 // TODO(karlklose): clean this up (dartbug.com/8870). | 2031 // TODO(karlklose): clean this up (dartbug.com/8870). |
| 2018 inCheckContext = compiler.enableTypeAssertions && | 2032 inCheckContext = compiler.enableTypeAssertions && |
| 2019 !element.isLibrary && | 2033 !element.isLibrary && |
| 2020 !element.isTypedef && | 2034 !element.isTypedef && |
| 2021 !element.enclosingElement.isTypedef, | 2035 !element.enclosingElement.isTypedef, |
| 2022 inCatchBlock = false, | 2036 inCatchBlock = false, |
| 2023 super(compiler, registry); | 2037 super(compiler, registry); |
| 2024 | 2038 |
| 2025 Element reportLookupErrorIfAny(Element result, Node node, String name) { | 2039 Element reportLookupErrorIfAny(Element result, Node node, String name) { |
| (...skipping 1892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3918 * This visitor has to be extra careful as it is building the basic | 3932 * This visitor has to be extra careful as it is building the basic |
| 3919 * element information, and cannot safely look at other elements as | 3933 * element information, and cannot safely look at other elements as |
| 3920 * this may lead to cycles. | 3934 * this may lead to cycles. |
| 3921 * | 3935 * |
| 3922 * This visitor can assume that the supertypes have already been | 3936 * This visitor can assume that the supertypes have already been |
| 3923 * resolved, but it cannot call [ResolverTask.resolveClass] directly | 3937 * resolved, but it cannot call [ResolverTask.resolveClass] directly |
| 3924 * or indirectly (through [ClassElement.ensureResolved]) for any other | 3938 * or indirectly (through [ClassElement.ensureResolved]) for any other |
| 3925 * types. | 3939 * types. |
| 3926 */ | 3940 */ |
| 3927 class ClassResolverVisitor extends TypeDefinitionVisitor { | 3941 class ClassResolverVisitor extends TypeDefinitionVisitor { |
| 3928 ClassElement get element => enclosingElement; | 3942 BaseClassElementX get element => enclosingElement; |
| 3929 | 3943 |
| 3930 ClassResolverVisitor(Compiler compiler, | 3944 ClassResolverVisitor(Compiler compiler, |
| 3931 ClassElement classElement, | 3945 ClassElement classElement, |
| 3932 ResolutionRegistry registry) | 3946 ResolutionRegistry registry) |
| 3933 : super(compiler, classElement, registry); | 3947 : super(compiler, classElement, registry); |
| 3934 | 3948 |
| 3935 DartType visitClassNode(ClassNode node) { | 3949 DartType visitClassNode(ClassNode node) { |
| 3936 invariant(node, element != null); | 3950 invariant(node, element != null); |
| 3937 invariant(element, element.resolutionState == STATE_STARTED, | 3951 invariant(element, element.resolutionState == STATE_STARTED, |
| 3938 message: () => 'cyclic resolution of class $element'); | 3952 message: () => 'cyclic resolution of class $element'); |
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4649 expression, expression); | 4663 expression, expression); |
| 4650 } | 4664 } |
| 4651 } | 4665 } |
| 4652 | 4666 |
| 4653 /// Looks up [name] in [scope] and unwraps the result. | 4667 /// Looks up [name] in [scope] and unwraps the result. |
| 4654 Element lookupInScope(Compiler compiler, Node node, | 4668 Element lookupInScope(Compiler compiler, Node node, |
| 4655 Scope scope, String name) { | 4669 Scope scope, String name) { |
| 4656 return Elements.unwrap(scope.lookup(name), compiler, node); | 4670 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4657 } | 4671 } |
| 4658 | 4672 |
| 4659 TreeElements _ensureTreeElements(AnalyzableElement element) { | 4673 TreeElements _ensureTreeElements(AnalyzableElementX element) { |
| 4660 if (element._treeElements == null) { | 4674 if (element._treeElements == null) { |
| 4661 element._treeElements = new TreeElementMapping(element); | 4675 element._treeElements = new TreeElementMapping(element); |
| 4662 } | 4676 } |
| 4663 return element._treeElements; | 4677 return element._treeElements; |
| 4664 } | 4678 } |
| 4665 | 4679 |
| 4666 abstract class AnalyzableElement implements Element { | 4680 abstract class AnalyzableElementX implements AnalyzableElement { |
| 4667 TreeElements _treeElements; | 4681 TreeElements _treeElements; |
| 4668 | 4682 |
| 4669 bool get hasTreeElements => _treeElements != null; | 4683 bool get hasTreeElements => _treeElements != null; |
| 4670 | 4684 |
| 4671 TreeElements get treeElements { | 4685 TreeElements get treeElements { |
| 4672 assert(invariant(this, _treeElements !=null, | 4686 assert(invariant(this, _treeElements !=null, |
| 4673 message: "TreeElements have not been computed for $this.")); | 4687 message: "TreeElements have not been computed for $this.")); |
| 4674 return _treeElements; | 4688 return _treeElements; |
| 4675 } | 4689 } |
| 4676 } | 4690 } |
| OLD | NEW |