| 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 processMetadata([result]) { | 262 for (MetadataAnnotation metadata in element.metadata) { |
| 263 for (MetadataAnnotation metadata in element.metadata) { | 263 metadata.ensureResolved(compiler); |
| 264 metadata.ensureResolved(compiler); | |
| 265 } | |
| 266 return result; | |
| 267 } | 264 } |
| 268 | 265 |
| 269 ElementKind kind = element.kind; | 266 ElementKind kind = element.kind; |
| 270 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || | 267 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || |
| 271 identical(kind, ElementKind.FUNCTION) || | 268 identical(kind, ElementKind.FUNCTION) || |
| 272 identical(kind, ElementKind.GETTER) || | 269 identical(kind, ElementKind.GETTER) || |
| 273 identical(kind, ElementKind.SETTER)) { | 270 identical(kind, ElementKind.SETTER)) { |
| 274 return processMetadata(resolveMethodElement(element)); | 271 return resolveMethodElement(element); |
| 275 } | 272 } |
| 276 | 273 |
| 277 if (identical(kind, ElementKind.FIELD)) { | 274 if (identical(kind, ElementKind.FIELD)) return resolveField(element); |
| 278 return processMetadata(resolveField(element)); | 275 |
| 279 } | |
| 280 if (element.isClass) { | 276 if (element.isClass) { |
| 281 ClassElement cls = element; | 277 ClassElement cls = element; |
| 282 cls.ensureResolved(compiler); | 278 cls.ensureResolved(compiler); |
| 283 return processMetadata(); | 279 return null; |
| 284 } else if (element.isTypedef) { | 280 } else if (element.isTypedef) { |
| 285 TypedefElement typdef = element; | 281 TypedefElement typdef = element; |
| 286 return processMetadata(resolveTypedef(typdef)); | 282 return resolveTypedef(typdef); |
| 287 } | 283 } |
| 288 | 284 |
| 289 compiler.unimplemented(element, "resolve($element)"); | 285 compiler.unimplemented(element, "resolve($element)"); |
| 290 }); | 286 }); |
| 291 } | 287 } |
| 292 | 288 |
| 293 String constructorNameForDiagnostics(String className, | 289 String constructorNameForDiagnostics(String className, |
| 294 String constructorName) { | 290 String constructorName) { |
| 295 String classNameString = className; | 291 String classNameString = className; |
| 296 String constructorNameString = constructorName; | 292 String constructorNameString = constructorName; |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 for (MixinApplicationElement mixinApplication in mixinUses) { | 536 for (MixinApplicationElement mixinApplication in mixinUses) { |
| 541 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); | 537 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); |
| 542 } | 538 } |
| 543 } | 539 } |
| 544 } | 540 } |
| 545 return resolutionTree; | 541 return resolutionTree; |
| 546 }); | 542 }); |
| 547 }); | 543 }); |
| 548 } | 544 } |
| 549 | 545 |
| 550 /// Creates a [ResolverVisitor] for resolving an AST in context of [element]. | |
| 551 /// If [useEnclosingScope] is `true` then the initial scope of the visitor | |
| 552 /// does not include inner scope of [element]. | |
| 553 /// | |
| 554 /// This method should only be used by this library (or tests of | 546 /// This method should only be used by this library (or tests of |
| 555 /// this library). | 547 /// this library). |
| 556 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { | 548 ResolverVisitor visitorFor(Element element) { |
| 557 return new ResolverVisitor(compiler, element, | 549 return new ResolverVisitor(compiler, element, _ensureTreeElements(element)); |
| 558 _ensureTreeElements(element), useEnclosingScope: useEnclosingScope); | |
| 559 } | 550 } |
| 560 | 551 |
| 561 TreeElements resolveField(VariableElementX element) { | 552 TreeElements resolveField(VariableElementX element) { |
| 562 VariableDefinitions tree = element.parseNode(compiler); | 553 VariableDefinitions tree = element.parseNode(compiler); |
| 563 if(element.modifiers.isStatic && element.isTopLevel) { | 554 if(element.modifiers.isStatic && element.isTopLevel) { |
| 564 error(element.modifiers.getStatic(), | 555 error(element.modifiers.getStatic(), |
| 565 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 556 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
| 566 } | 557 } |
| 567 ResolverVisitor visitor = visitorFor(element); | 558 ResolverVisitor visitor = visitorFor(element); |
| 568 // TODO(johnniwinther): Share the resolved type between all variables | 559 // TODO(johnniwinther): Share the resolved type between all variables |
| (...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 }); | 1178 }); |
| 1188 }); | 1179 }); |
| 1189 } | 1180 } |
| 1190 | 1181 |
| 1191 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { | 1182 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { |
| 1192 compiler.withCurrentElement(annotation.annotatedElement, () => measure(() { | 1183 compiler.withCurrentElement(annotation.annotatedElement, () => measure(() { |
| 1193 assert(annotation.resolutionState == STATE_NOT_STARTED); | 1184 assert(annotation.resolutionState == STATE_NOT_STARTED); |
| 1194 annotation.resolutionState = STATE_STARTED; | 1185 annotation.resolutionState = STATE_STARTED; |
| 1195 | 1186 |
| 1196 Node node = annotation.parseNode(compiler); | 1187 Node node = annotation.parseNode(compiler); |
| 1188 // TODO(johnniwinther): Find the right analyzable element to hold the |
| 1189 // [TreeElements] for the annotation. |
| 1197 Element annotatedElement = annotation.annotatedElement; | 1190 Element annotatedElement = annotation.annotatedElement; |
| 1198 AnalyzableElement context = annotatedElement.analyzableElement; | 1191 Element context = annotatedElement.enclosingElement; |
| 1199 assert(invariant(node, context != null, | 1192 if (context == null) { |
| 1200 message: "No context found for metadata annotation " | 1193 context = annotatedElement; |
| 1201 "on $annotatedElement.")); | 1194 } |
| 1202 ResolverVisitor visitor = visitorFor(context, useEnclosingScope: true); | 1195 ResolverVisitor visitor = visitorFor(context); |
| 1203 node.accept(visitor); | 1196 node.accept(visitor); |
| 1204 annotation.value = | 1197 annotation.value = |
| 1205 constantCompiler.compileMetadata(annotation, node, visitor.mapping); | 1198 constantCompiler.compileMetadata(annotation, node, visitor.mapping); |
| 1206 // TODO(johnniwinther): Register the relation between the annotation | 1199 // TODO(johnniwinther): Register the relation between the annotation |
| 1207 // and the annotated element instead. This will allow the backend to | 1200 // and the annotated element instead. This will allow the backed to |
| 1208 // retrieve the backend constant and only register metadata on the | 1201 // retrieve the backend constant and only registered metadata on the |
| 1209 // elements for which it is needed. (Issue 17732). | 1202 // elements for which it is needed. (Issue 17732). |
| 1210 compiler.backend.registerMetadataConstant( | 1203 compiler.backend.registerMetadataConstant( |
| 1211 annotation.value, visitor.mapping); | 1204 annotation.value, visitor.mapping); |
| 1212 annotation.resolutionState = STATE_DONE; | 1205 annotation.resolutionState = STATE_DONE; |
| 1213 })); | 1206 })); |
| 1214 } | 1207 } |
| 1215 | 1208 |
| 1216 error(Spannable node, MessageKind kind, [arguments = const {}]) { | 1209 error(Spannable node, MessageKind kind, [arguments = const {}]) { |
| 1217 // TODO(ahe): Make non-fatal. | 1210 // TODO(ahe): Make non-fatal. |
| 1218 compiler.reportFatalError(node, kind, arguments); | 1211 compiler.reportFatalError(node, kind, arguments); |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2003 r'>|' | 1996 r'>|' |
| 2004 r'<=|' | 1997 r'<=|' |
| 2005 r'<|' | 1998 r'<|' |
| 2006 r'&|' | 1999 r'&|' |
| 2007 r'\^|' | 2000 r'\^|' |
| 2008 r'\|' | 2001 r'\|' |
| 2009 r')$'); | 2002 r')$'); |
| 2010 | 2003 |
| 2011 ResolverVisitor(Compiler compiler, | 2004 ResolverVisitor(Compiler compiler, |
| 2012 Element element, | 2005 Element element, |
| 2013 TreeElementMapping mapping, | 2006 TreeElementMapping mapping) |
| 2014 {bool useEnclosingScope: false}) | |
| 2015 : this.enclosingElement = element, | 2007 : this.enclosingElement = element, |
| 2016 // When the element is a field, we are actually resolving its | 2008 // When the element is a field, we are actually resolving its |
| 2017 // initial value, which should not have access to instance | 2009 // initial value, which should not have access to instance |
| 2018 // fields. | 2010 // fields. |
| 2019 inInstanceContext = (element.isInstanceMember && !element.isField) | 2011 inInstanceContext = (element.isInstanceMember && !element.isField) |
| 2020 || element.isGenerativeConstructor, | 2012 || element.isGenerativeConstructor, |
| 2021 this.currentClass = element.isMember ? element.enclosingClass | 2013 this.currentClass = element.isMember ? element.enclosingClass |
| 2022 : null, | 2014 : null, |
| 2023 this.statementScope = new StatementScope(), | 2015 this.statementScope = new StatementScope(), |
| 2024 scope = useEnclosingScope | 2016 scope = element.buildScope(), |
| 2025 ? Scope.buildEnclosingScope(element) : element.buildScope(), | |
| 2026 // The type annotations on a typedef do not imply type checks. | 2017 // The type annotations on a typedef do not imply type checks. |
| 2027 // TODO(karlklose): clean this up (dartbug.com/8870). | 2018 // TODO(karlklose): clean this up (dartbug.com/8870). |
| 2028 inCheckContext = compiler.enableTypeAssertions && | 2019 inCheckContext = compiler.enableTypeAssertions && |
| 2029 !element.isLibrary && | 2020 !element.isLibrary && |
| 2030 !element.isTypedef && | 2021 !element.isTypedef && |
| 2031 !element.enclosingElement.isTypedef, | 2022 !element.enclosingElement.isTypedef, |
| 2032 inCatchBlock = false, | 2023 inCatchBlock = false, |
| 2033 super(compiler, mapping); | 2024 super(compiler, mapping); |
| 2034 | 2025 |
| 2035 ResolutionEnqueuer get world => compiler.enqueuer.resolution; | 2026 ResolutionEnqueuer get world => compiler.enqueuer.resolution; |
| (...skipping 2623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4659 expression, expression); | 4650 expression, expression); |
| 4660 } | 4651 } |
| 4661 } | 4652 } |
| 4662 | 4653 |
| 4663 /// Looks up [name] in [scope] and unwraps the result. | 4654 /// Looks up [name] in [scope] and unwraps the result. |
| 4664 Element lookupInScope(Compiler compiler, Node node, | 4655 Element lookupInScope(Compiler compiler, Node node, |
| 4665 Scope scope, String name) { | 4656 Scope scope, String name) { |
| 4666 return Elements.unwrap(scope.lookup(name), compiler, node); | 4657 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4667 } | 4658 } |
| 4668 | 4659 |
| 4669 TreeElements _ensureTreeElements(AnalyzableElementX element) { | 4660 TreeElements _ensureTreeElements(AnalyzableElement element) { |
| 4670 if (element._treeElements == null) { | 4661 if (element._treeElements == null) { |
| 4671 element._treeElements = new TreeElementMapping(element); | 4662 element._treeElements = new TreeElementMapping(element); |
| 4672 } | 4663 } |
| 4673 return element._treeElements; | 4664 return element._treeElements; |
| 4674 } | 4665 } |
| 4675 | 4666 |
| 4676 abstract class AnalyzableElementX implements AnalyzableElement { | 4667 abstract class AnalyzableElement implements Element { |
| 4677 TreeElements _treeElements; | 4668 TreeElements _treeElements; |
| 4678 | 4669 |
| 4679 bool get hasTreeElements => _treeElements != null; | 4670 bool get hasTreeElements => _treeElements != null; |
| 4680 | 4671 |
| 4681 TreeElements get treeElements { | 4672 TreeElements get treeElements { |
| 4682 assert(invariant(this, _treeElements !=null, | 4673 assert(invariant(this, _treeElements !=null, |
| 4683 message: "TreeElements have not been computed for $this.")); | 4674 message: "TreeElements have not been computed for $this.")); |
| 4684 return _treeElements; | 4675 return _treeElements; |
| 4685 } | 4676 } |
| 4686 } | 4677 } |
| OLD | NEW |