| 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 |
| 11 /// Iterables of the dependencies that this [TreeElement] records of | 11 /// Iterables of the dependencies that this [TreeElement] records of |
| 12 /// [currentElement]. | 12 /// [currentElement]. |
| 13 Iterable<Element> get allElements; | 13 Iterable<Element> get allElements; |
| 14 void forEachConstantNode(f(Node n, Constant c)); | 14 void forEachConstantNode(f(Node n, Constant c)); |
| 15 | 15 |
| 16 /// A set of additional dependencies. See [registerDependency] below. | 16 /// A set of additional dependencies. See [registerDependency] below. |
| 17 Setlet<Element> get otherDependencies; | 17 Setlet<Element> get otherDependencies; |
| 18 | 18 |
| 19 Element operator[](Node node); | 19 Element operator[](Node node); |
| 20 Selector getSelector(Send send); | 20 |
| 21 // TODO(johnniwinther): Investigate whether [Node] could be a [Send]. |
| 22 Selector getSelector(Node node); |
| 21 Selector getGetterSelectorInComplexSendSet(SendSet node); | 23 Selector getGetterSelectorInComplexSendSet(SendSet node); |
| 22 Selector getOperatorSelectorInComplexSendSet(SendSet node); | 24 Selector getOperatorSelectorInComplexSendSet(SendSet node); |
| 23 DartType getType(Node node); | 25 DartType getType(Node node); |
| 24 void setSelector(Node node, Selector selector); | 26 void setSelector(Node node, Selector selector); |
| 25 void setGetterSelectorInComplexSendSet(SendSet node, Selector selector); | 27 void setGetterSelectorInComplexSendSet(SendSet node, Selector selector); |
| 26 void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector); | 28 void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector); |
| 29 |
| 30 /// Returns the for-in loop variable for [node]. |
| 31 Element getForInVariable(ForIn node); |
| 27 Selector getIteratorSelector(ForIn node); | 32 Selector getIteratorSelector(ForIn node); |
| 28 Selector getMoveNextSelector(ForIn node); | 33 Selector getMoveNextSelector(ForIn node); |
| 29 Selector getCurrentSelector(ForIn node); | 34 Selector getCurrentSelector(ForIn node); |
| 30 void setIteratorSelector(ForIn node, Selector selector); | 35 void setIteratorSelector(ForIn node, Selector selector); |
| 31 void setMoveNextSelector(ForIn node, Selector selector); | 36 void setMoveNextSelector(ForIn node, Selector selector); |
| 32 void setCurrentSelector(ForIn node, Selector selector); | 37 void setCurrentSelector(ForIn node, Selector selector); |
| 33 void setConstant(Node node, Constant constant); | 38 void setConstant(Node node, Constant constant); |
| 34 Constant getConstant(Node node); | 39 Constant getConstant(Node node); |
| 35 bool isAssert(Send send); | 40 bool isAssert(Send send); |
| 36 | 41 |
| 42 /// Returns the [FunctionElement] defined by [node]. |
| 43 FunctionElement getFunctionDefinition(FunctionExpression node); |
| 44 |
| 45 /// Returns target constructor for the redirecting factory body [node]. |
| 46 ConstructorElement getRedirectingTargetConstructor( |
| 47 RedirectingFactoryBody node); |
| 48 |
| 37 /** | 49 /** |
| 38 * Returns [:true:] if [node] is a type literal. | 50 * Returns [:true:] if [node] is a type literal. |
| 39 * | 51 * |
| 40 * Resolution marks this by setting the type on the node to be the | 52 * Resolution marks this by setting the type on the node to be the |
| 41 * type that the literal refers to. | 53 * type that the literal refers to. |
| 42 */ | 54 */ |
| 43 bool isTypeLiteral(Send node); | 55 bool isTypeLiteral(Send node); |
| 44 | 56 |
| 45 /// Returns the type that the type literal [node] refers to. | 57 /// Returns the type that the type literal [node] refers to. |
| 46 DartType getTypeLiteralType(Send node); | 58 DartType getTypeLiteralType(Send node); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 } | 201 } |
| 190 | 202 |
| 191 void setCurrentSelector(ForIn node, Selector selector) { | 203 void setCurrentSelector(ForIn node, Selector selector) { |
| 192 selectors[node.inToken] = selector; | 204 selectors[node.inToken] = selector; |
| 193 } | 205 } |
| 194 | 206 |
| 195 Selector getCurrentSelector(ForIn node) { | 207 Selector getCurrentSelector(ForIn node) { |
| 196 return selectors[node.inToken]; | 208 return selectors[node.inToken]; |
| 197 } | 209 } |
| 198 | 210 |
| 211 Element getForInVariable(ForIn node) { |
| 212 return this[node]; |
| 213 } |
| 214 |
| 199 void setConstant(Node node, Constant constant) { | 215 void setConstant(Node node, Constant constant) { |
| 200 constants[node] = constant; | 216 constants[node] = constant; |
| 201 } | 217 } |
| 202 | 218 |
| 203 Constant getConstant(Node node) { | 219 Constant getConstant(Node node) { |
| 204 return constants[node]; | 220 return constants[node]; |
| 205 } | 221 } |
| 206 | 222 |
| 207 bool isTypeLiteral(Send node) { | 223 bool isTypeLiteral(Send node) { |
| 208 return getType(node) != null; | 224 return getType(node) != null; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 void forEachConstantNode(f(Node n, Constant c)) => constants.forEach(f); | 294 void forEachConstantNode(f(Node n, Constant c)) => constants.forEach(f); |
| 279 | 295 |
| 280 void setAssert(Send node) { | 296 void setAssert(Send node) { |
| 281 asserts.add(node); | 297 asserts.add(node); |
| 282 } | 298 } |
| 283 | 299 |
| 284 bool isAssert(Send node) { | 300 bool isAssert(Send node) { |
| 285 return asserts.contains(node); | 301 return asserts.contains(node); |
| 286 } | 302 } |
| 287 | 303 |
| 304 FunctionElement getFunctionDefinition(FunctionExpression node) { |
| 305 return this[node]; |
| 306 } |
| 307 |
| 308 ConstructorElement getRedirectingTargetConstructor( |
| 309 RedirectingFactoryBody node) { |
| 310 return this[node]; |
| 311 } |
| 312 |
| 288 void defineTarget(Node node, JumpTarget target) { | 313 void defineTarget(Node node, JumpTarget target) { |
| 289 if (definedTargets == null) { | 314 if (definedTargets == null) { |
| 290 // TODO(johnniwinther): Use [Maplet] when available. | 315 // TODO(johnniwinther): Use [Maplet] when available. |
| 291 definedTargets = <Node, JumpTarget>{}; | 316 definedTargets = <Node, JumpTarget>{}; |
| 292 } | 317 } |
| 293 definedTargets[node] = target; | 318 definedTargets[node] = target; |
| 294 } | 319 } |
| 295 | 320 |
| 296 void undefineTarget(Node node) { | 321 void undefineTarget(Node node) { |
| 297 if (definedTargets != null) { | 322 if (definedTargets != null) { |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 } | 616 } |
| 592 if (element.modifiers.isConst && | 617 if (element.modifiers.isConst && |
| 593 tree.hasBody() && | 618 tree.hasBody() && |
| 594 !tree.isRedirectingFactory) { | 619 !tree.isRedirectingFactory) { |
| 595 compiler.reportError(tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY); | 620 compiler.reportError(tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY); |
| 596 } | 621 } |
| 597 } | 622 } |
| 598 | 623 |
| 599 ResolverVisitor visitor = visitorFor(element); | 624 ResolverVisitor visitor = visitorFor(element); |
| 600 ResolutionRegistry registry = visitor.registry; | 625 ResolutionRegistry registry = visitor.registry; |
| 601 registry.useElement(tree, element); | 626 registry.defineFunction(tree, element); |
| 602 visitor.setupFunction(tree, element); | 627 visitor.setupFunction(tree, element); |
| 603 | 628 |
| 604 if (isConstructor && !element.isForwardingConstructor) { | 629 if (isConstructor && !element.isForwardingConstructor) { |
| 605 // Even if there is no initializer list we still have to do the | 630 // Even if there is no initializer list we still have to do the |
| 606 // resolution in case there is an implicit super constructor call. | 631 // resolution in case there is an implicit super constructor call. |
| 607 InitializerResolver resolver = new InitializerResolver(visitor); | 632 InitializerResolver resolver = new InitializerResolver(visitor); |
| 608 FunctionElement redirection = | 633 FunctionElement redirection = |
| 609 resolver.resolveInitializers(element, tree); | 634 resolver.resolveInitializers(element, tree); |
| 610 if (redirection != null) { | 635 if (redirection != null) { |
| 611 resolveRedirectingConstructor(resolver, tree, element, redirection); | 636 resolveRedirectingConstructor(resolver, tree, element, redirection); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 /// does not include inner scope of [element]. | 675 /// does not include inner scope of [element]. |
| 651 /// | 676 /// |
| 652 /// This method should only be used by this library (or tests of | 677 /// This method should only be used by this library (or tests of |
| 653 /// this library). | 678 /// this library). |
| 654 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { | 679 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { |
| 655 return new ResolverVisitor(compiler, element, | 680 return new ResolverVisitor(compiler, element, |
| 656 new ResolutionRegistry(compiler, element), | 681 new ResolutionRegistry(compiler, element), |
| 657 useEnclosingScope: useEnclosingScope); | 682 useEnclosingScope: useEnclosingScope); |
| 658 } | 683 } |
| 659 | 684 |
| 660 TreeElements resolveField(VariableElementX element) { | 685 TreeElements resolveField(FieldElementX element) { |
| 661 VariableDefinitions tree = element.parseNode(compiler); | 686 VariableDefinitions tree = element.parseNode(compiler); |
| 662 if(element.modifiers.isStatic && element.isTopLevel) { | 687 if(element.modifiers.isStatic && element.isTopLevel) { |
| 663 error(element.modifiers.getStatic(), | 688 error(element.modifiers.getStatic(), |
| 664 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 689 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
| 665 } | 690 } |
| 666 ResolverVisitor visitor = visitorFor(element); | 691 ResolverVisitor visitor = visitorFor(element); |
| 667 ResolutionRegistry registry = visitor.registry; | 692 ResolutionRegistry registry = visitor.registry; |
| 668 // TODO(johnniwinther): Share the resolved type between all variables | 693 // TODO(johnniwinther): Share the resolved type between all variables |
| 669 // declared in the same declaration. | 694 // declared in the same declaration. |
| 670 if (tree.type != null) { | 695 if (tree.type != null) { |
| 671 element.variables.type = visitor.resolveTypeAnnotation(tree.type); | 696 element.variables.type = visitor.resolveTypeAnnotation(tree.type); |
| 672 } else { | 697 } else { |
| 673 element.variables.type = const DynamicType(); | 698 element.variables.type = const DynamicType(); |
| 674 } | 699 } |
| 675 registry.useElement(tree, element); | |
| 676 | 700 |
| 677 Expression initializer = element.initializer; | 701 Expression initializer = element.initializer; |
| 678 Modifiers modifiers = element.modifiers; | 702 Modifiers modifiers = element.modifiers; |
| 679 if (initializer != null) { | 703 if (initializer != null) { |
| 680 // TODO(johnniwinther): Avoid analyzing initializers if | 704 // TODO(johnniwinther): Avoid analyzing initializers if |
| 681 // [Compiler.analyzeSignaturesOnly] is set. | 705 // [Compiler.analyzeSignaturesOnly] is set. |
| 682 visitor.visit(initializer); | 706 visitor.visit(initializer); |
| 683 } else if (modifiers.isConst) { | 707 } else if (modifiers.isConst) { |
| 684 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER); | 708 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER); |
| 685 } else if (modifiers.isFinal && !element.isInstanceMember) { | 709 } else if (modifiers.isFinal && !element.isInstanceMember) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 ConstructorElementX factory = seen.removeLast(); | 793 ConstructorElementX factory = seen.removeLast(); |
| 770 | 794 |
| 771 // [factory] must already be analyzed but the [TreeElements] might not | 795 // [factory] must already be analyzed but the [TreeElements] might not |
| 772 // have been stored in the enqueuer cache yet. | 796 // have been stored in the enqueuer cache yet. |
| 773 // TODO(johnniwinther): Store [TreeElements] in the cache before | 797 // TODO(johnniwinther): Store [TreeElements] in the cache before |
| 774 // resolution of the element. | 798 // resolution of the element. |
| 775 TreeElements treeElements = factory.treeElements; | 799 TreeElements treeElements = factory.treeElements; |
| 776 assert(invariant(node, treeElements != null, | 800 assert(invariant(node, treeElements != null, |
| 777 message: 'No TreeElements cached for $factory.')); | 801 message: 'No TreeElements cached for $factory.')); |
| 778 FunctionExpression functionNode = factory.parseNode(compiler); | 802 FunctionExpression functionNode = factory.parseNode(compiler); |
| 779 Return redirectionNode = functionNode.body; | 803 RedirectingFactoryBody redirectionNode = functionNode.body; |
| 780 InterfaceType factoryType = | 804 InterfaceType factoryType = treeElements.getType(redirectionNode); |
| 781 treeElements.getType(redirectionNode.expression); | |
| 782 | 805 |
| 783 targetType = targetType.substByContext(factoryType); | 806 targetType = targetType.substByContext(factoryType); |
| 784 factory.effectiveTarget = target; | 807 factory.effectiveTarget = target; |
| 785 factory.effectiveTargetType = targetType; | 808 factory.effectiveTargetType = targetType; |
| 786 } | 809 } |
| 787 } | 810 } |
| 788 | 811 |
| 789 /** | 812 /** |
| 790 * Load and resolve the supertypes of [cls]. | 813 * Load and resolve the supertypes of [cls]. |
| 791 * | 814 * |
| (...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2011 final TypeResolver typeResolver; | 2034 final TypeResolver typeResolver; |
| 2012 /// The current enclosing element for the visited AST nodes. | 2035 /// The current enclosing element for the visited AST nodes. |
| 2013 Element get enclosingElement; | 2036 Element get enclosingElement; |
| 2014 /// The current scope of the visitor. | 2037 /// The current scope of the visitor. |
| 2015 Scope get scope; | 2038 Scope get scope; |
| 2016 | 2039 |
| 2017 MappingVisitor(Compiler compiler, ResolutionRegistry this.registry) | 2040 MappingVisitor(Compiler compiler, ResolutionRegistry this.registry) |
| 2018 : typeResolver = new TypeResolver(compiler), | 2041 : typeResolver = new TypeResolver(compiler), |
| 2019 super(compiler); | 2042 super(compiler); |
| 2020 | 2043 |
| 2021 Element defineElement(Node node, Element element, | 2044 /// Add [element] to the current scope and check for duplicate definitions. |
| 2022 {bool doAddToScope: true}) { | 2045 void addToScope(Element element) { |
| 2046 Element existing = scope.add(element); |
| 2047 if (existing != element) { |
| 2048 reportDuplicateDefinition(element.name, element, existing); |
| 2049 } |
| 2050 } |
| 2051 |
| 2052 /// Register [node] as the definition of [element]. |
| 2053 void defineLocalVariable(Node node, LocalVariableElement element) { |
| 2023 invariant(node, element != null); | 2054 invariant(node, element != null); |
| 2024 registry.defineElement(node, element); | 2055 registry.defineElement(node, element); |
| 2025 if (doAddToScope) { | |
| 2026 Element existing = scope.add(element); | |
| 2027 if (existing != element) { | |
| 2028 reportDuplicateDefinition(node, element, existing); | |
| 2029 } | |
| 2030 } | |
| 2031 return element; | |
| 2032 } | 2056 } |
| 2033 | 2057 |
| 2034 void reportDuplicateDefinition(/*Node|String*/ name, | 2058 void reportDuplicateDefinition(String name, |
| 2035 Spannable definition, | 2059 Spannable definition, |
| 2036 Spannable existing) { | 2060 Spannable existing) { |
| 2037 compiler.reportError(definition, | 2061 compiler.reportError(definition, |
| 2038 MessageKind.DUPLICATE_DEFINITION, {'name': name}); | 2062 MessageKind.DUPLICATE_DEFINITION, {'name': name}); |
| 2039 compiler.reportInfo(existing, | 2063 compiler.reportInfo(existing, |
| 2040 MessageKind.EXISTING_DEFINITION, {'name': name}); | 2064 MessageKind.EXISTING_DEFINITION, {'name': name}); |
| 2041 } | 2065 } |
| 2042 } | 2066 } |
| 2043 | 2067 |
| 2044 /** | 2068 /** |
| 2045 * Core implementation of resolution. | 2069 * Core implementation of resolution. |
| 2046 * | 2070 * |
| 2047 * Do not subclass or instantiate this class outside this library | 2071 * Do not subclass or instantiate this class outside this library |
| 2048 * except for testing. | 2072 * except for testing. |
| 2049 */ | 2073 */ |
| 2050 class ResolverVisitor extends MappingVisitor<ResolutionResult> { | 2074 class ResolverVisitor extends MappingVisitor<ResolutionResult> { |
| 2051 /** | 2075 /** |
| 2052 * The current enclosing element for the visited AST nodes. | 2076 * The current enclosing element for the visited AST nodes. |
| 2053 * | 2077 * |
| 2054 * This field is updated when nested closures are visited. | 2078 * This field is updated when nested closures are visited. |
| 2055 */ | 2079 */ |
| 2056 Element enclosingElement; | 2080 Element enclosingElement; |
| 2057 bool inInstanceContext; | 2081 bool inInstanceContext; |
| 2058 bool inCheckContext; | 2082 bool inCheckContext; |
| 2059 bool inCatchBlock; | 2083 bool inCatchBlock; |
| 2084 |
| 2060 Scope scope; | 2085 Scope scope; |
| 2061 ClassElement currentClass; | 2086 ClassElement currentClass; |
| 2062 ExpressionStatement currentExpressionStatement; | 2087 ExpressionStatement currentExpressionStatement; |
| 2063 bool sendIsMemberAccess = false; | 2088 bool sendIsMemberAccess = false; |
| 2064 StatementScope statementScope; | 2089 StatementScope statementScope; |
| 2065 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION | 2090 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION |
| 2066 | ElementCategory.IMPLIES_TYPE; | 2091 | ElementCategory.IMPLIES_TYPE; |
| 2067 | 2092 |
| 2068 /** | 2093 /** |
| 2069 * Record of argument nodes to JS_INTERCEPTOR_CONSTANT for deferred | 2094 * Record of argument nodes to JS_INTERCEPTOR_CONSTANT for deferred |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2307 parameterNodes = nodes.nodes; | 2332 parameterNodes = nodes.nodes; |
| 2308 } | 2333 } |
| 2309 visit(element.initializer); | 2334 visit(element.initializer); |
| 2310 VariableDefinitions variableDefinitions = parameterNodes.head; | 2335 VariableDefinitions variableDefinitions = parameterNodes.head; |
| 2311 Node parameterNode = variableDefinitions.definitions.nodes.head; | 2336 Node parameterNode = variableDefinitions.definitions.nodes.head; |
| 2312 // Field parameters (this.x) are not visible inside the constructor. The | 2337 // Field parameters (this.x) are not visible inside the constructor. The |
| 2313 // fields they reference are visible, but must be resolved independently. | 2338 // fields they reference are visible, but must be resolved independently. |
| 2314 if (element.isInitializingFormal) { | 2339 if (element.isInitializingFormal) { |
| 2315 registry.useElement(parameterNode, element); | 2340 registry.useElement(parameterNode, element); |
| 2316 } else { | 2341 } else { |
| 2317 defineElement(parameterNode, element); | 2342 LocalParameterElement parameterElement = element; |
| 2343 defineLocalVariable(parameterNode, parameterElement); |
| 2344 addToScope(parameterElement); |
| 2318 } | 2345 } |
| 2319 parameterNodes = parameterNodes.tail; | 2346 parameterNodes = parameterNodes.tail; |
| 2320 }); | 2347 }); |
| 2321 addDeferredAction(enclosingElement, () { | 2348 addDeferredAction(enclosingElement, () { |
| 2322 functionParameters.forEachOptionalParameter((Element parameter) { | 2349 functionParameters.forEachOptionalParameter((Element parameter) { |
| 2323 compiler.resolver.constantCompiler.compileConstant(parameter); | 2350 compiler.resolver.constantCompiler.compileConstant(parameter); |
| 2324 }); | 2351 }); |
| 2325 }); | 2352 }); |
| 2326 if (inCheckContext) { | 2353 if (inCheckContext) { |
| 2327 functionParameters.forEachParameter((ParameterElement element) { | 2354 functionParameters.forEachParameter((ParameterElement element) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2385 visitFor(For node) { | 2412 visitFor(For node) { |
| 2386 Scope blockScope = new BlockScope(scope); | 2413 Scope blockScope = new BlockScope(scope); |
| 2387 visitIn(node.initializer, blockScope); | 2414 visitIn(node.initializer, blockScope); |
| 2388 visitIn(node.condition, blockScope); | 2415 visitIn(node.condition, blockScope); |
| 2389 visitIn(node.update, blockScope); | 2416 visitIn(node.update, blockScope); |
| 2390 visitLoopBodyIn(node, node.body, blockScope); | 2417 visitLoopBodyIn(node, node.body, blockScope); |
| 2391 } | 2418 } |
| 2392 | 2419 |
| 2393 visitFunctionDeclaration(FunctionDeclaration node) { | 2420 visitFunctionDeclaration(FunctionDeclaration node) { |
| 2394 assert(node.function.name != null); | 2421 assert(node.function.name != null); |
| 2395 visit(node.function); | 2422 visitFunctionExpression(node.function, inFunctionDeclaration: true); |
| 2396 FunctionElement functionElement = registry.getDefinition(node.function); | |
| 2397 // TODO(floitsch): this might lead to two errors complaining about | |
| 2398 // shadowing. | |
| 2399 defineElement(node, functionElement); | |
| 2400 } | 2423 } |
| 2401 | 2424 |
| 2402 visitFunctionExpression(FunctionExpression node) { | 2425 |
| 2426 /// Process a local function declaration or an anonymous function expression. |
| 2427 /// |
| 2428 /// [inFunctionDeclaration] is `true` when the current node is the immediate |
| 2429 /// child of a function declaration. |
| 2430 /// |
| 2431 /// This is used to distinguish local function declarations from anonymous |
| 2432 /// function expressions. |
| 2433 visitFunctionExpression(FunctionExpression node, |
| 2434 {bool inFunctionDeclaration: false}) { |
| 2435 bool doAddToScope = inFunctionDeclaration; |
| 2436 if (!inFunctionDeclaration && node.name != null) { |
| 2437 compiler.reportError( |
| 2438 node.name, |
| 2439 MessageKind.NAMED_FUNCTION_EXPRESSION, |
| 2440 {'name': node.name}); |
| 2441 } |
| 2403 visit(node.returnType); | 2442 visit(node.returnType); |
| 2404 String name; | 2443 String name; |
| 2405 if (node.name == null) { | 2444 if (node.name == null) { |
| 2406 name = ""; | 2445 name = ""; |
| 2407 } else { | 2446 } else { |
| 2408 name = node.name.asIdentifier().source; | 2447 name = node.name.asIdentifier().source; |
| 2409 } | 2448 } |
| 2410 LocalFunctionElementX function = new LocalFunctionElementX( | 2449 LocalFunctionElementX function = new LocalFunctionElementX( |
| 2411 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, | 2450 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, |
| 2412 enclosingElement); | 2451 enclosingElement); |
| 2413 function.functionSignatureCache = | 2452 function.functionSignatureCache = |
| 2414 SignatureResolver.analyze(compiler, node.parameters, node.returnType, | 2453 SignatureResolver.analyze(compiler, node.parameters, node.returnType, |
| 2415 function, registry, createRealParameters: true); | 2454 function, registry, createRealParameters: true); |
| 2455 registry.defineFunction(node, function); |
| 2456 if (doAddToScope) { |
| 2457 addToScope(function); |
| 2458 } |
| 2416 Scope oldScope = scope; // The scope is modified by [setupFunction]. | 2459 Scope oldScope = scope; // The scope is modified by [setupFunction]. |
| 2417 setupFunction(node, function); | 2460 setupFunction(node, function); |
| 2418 defineElement(node, function, doAddToScope: node.name != null); | |
| 2419 | 2461 |
| 2420 Element previousEnclosingElement = enclosingElement; | 2462 Element previousEnclosingElement = enclosingElement; |
| 2421 enclosingElement = function; | 2463 enclosingElement = function; |
| 2422 // Run the body in a fresh statement scope. | 2464 // Run the body in a fresh statement scope. |
| 2423 StatementScope oldStatementScope = statementScope; | 2465 StatementScope oldStatementScope = statementScope; |
| 2424 statementScope = new StatementScope(); | 2466 statementScope = new StatementScope(); |
| 2425 visit(node.body); | 2467 visit(node.body); |
| 2426 statementScope = oldStatementScope; | 2468 statementScope = oldStatementScope; |
| 2427 | 2469 |
| 2428 scope = oldScope; | 2470 scope = oldScope; |
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3006 internalError(node, 'operator'); | 3048 internalError(node, 'operator'); |
| 3007 } | 3049 } |
| 3008 | 3050 |
| 3009 visitRethrow(Rethrow node) { | 3051 visitRethrow(Rethrow node) { |
| 3010 if (!inCatchBlock) { | 3052 if (!inCatchBlock) { |
| 3011 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); | 3053 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); |
| 3012 } | 3054 } |
| 3013 } | 3055 } |
| 3014 | 3056 |
| 3015 visitReturn(Return node) { | 3057 visitReturn(Return node) { |
| 3016 if (node.isRedirectingFactoryBody) { | 3058 Node expression = node.expression; |
| 3017 handleRedirectingFactoryBody(node); | 3059 if (expression != null && |
| 3018 } else { | 3060 enclosingElement.isGenerativeConstructor) { |
| 3019 Node expression = node.expression; | 3061 // It is a compile-time error if a return statement of the form |
| 3020 if (expression != null && | 3062 // `return e;` appears in a generative constructor. (Dart Language |
| 3021 enclosingElement.isGenerativeConstructor) { | 3063 // Specification 13.12.) |
| 3022 // It is a compile-time error if a return statement of the form | 3064 compiler.reportError(expression, |
| 3023 // `return e;` appears in a generative constructor. (Dart Language | 3065 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); |
| 3024 // Specification 13.12.) | |
| 3025 compiler.reportError(expression, | |
| 3026 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); | |
| 3027 } | |
| 3028 visit(node.expression); | |
| 3029 } | 3066 } |
| 3067 visit(node.expression); |
| 3030 } | 3068 } |
| 3031 | 3069 |
| 3032 void handleRedirectingFactoryBody(Return node) { | 3070 visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
| 3033 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; | 3071 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; |
| 3034 if (!enclosingElement.isFactoryConstructor) { | 3072 if (!enclosingElement.isFactoryConstructor) { |
| 3035 compiler.reportError( | 3073 compiler.reportError( |
| 3036 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 3074 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
| 3037 compiler.reportHint( | 3075 compiler.reportHint( |
| 3038 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); | 3076 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
| 3039 } | 3077 } |
| 3040 ConstructorElementX constructor = enclosingElement; | 3078 ConstructorElementX constructor = enclosingElement; |
| 3041 bool isConstConstructor = constructor.isConst; | 3079 bool isConstConstructor = constructor.isConst; |
| 3042 ConstructorElement redirectionTarget = resolveRedirectingFactory( | 3080 ConstructorElement redirectionTarget = resolveRedirectingFactory( |
| 3043 node, inConstContext: isConstConstructor); | 3081 node, inConstContext: isConstConstructor); |
| 3044 constructor.immediateRedirectionTarget = redirectionTarget; | 3082 constructor.immediateRedirectionTarget = redirectionTarget; |
| 3045 registry.useElement(node.expression, redirectionTarget); | 3083 registry.setRedirectingTargetConstructor(node, redirectionTarget); |
| 3046 if (Elements.isUnresolved(redirectionTarget)) { | 3084 if (Elements.isUnresolved(redirectionTarget)) { |
| 3047 registry.registerThrowNoSuchMethod(); | 3085 registry.registerThrowNoSuchMethod(); |
| 3048 return; | 3086 return; |
| 3049 } else { | 3087 } else { |
| 3050 if (isConstConstructor && | 3088 if (isConstConstructor && |
| 3051 !redirectionTarget.isConst) { | 3089 !redirectionTarget.isConst) { |
| 3052 compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 3090 compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 3053 } | 3091 } |
| 3054 if (redirectionTarget == constructor) { | 3092 if (redirectionTarget == constructor) { |
| 3055 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); | 3093 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); |
| 3056 return; | 3094 return; |
| 3057 } | 3095 } |
| 3058 } | 3096 } |
| 3059 | 3097 |
| 3060 // Check that the target constructor is type compatible with the | 3098 // Check that the target constructor is type compatible with the |
| 3061 // redirecting constructor. | 3099 // redirecting constructor. |
| 3062 ClassElement targetClass = redirectionTarget.enclosingClass; | 3100 ClassElement targetClass = redirectionTarget.enclosingClass; |
| 3063 InterfaceType type = registry.getType(node.expression); | 3101 InterfaceType type = registry.getType(node); |
| 3064 FunctionType targetType = redirectionTarget.computeType(compiler) | 3102 FunctionType targetType = redirectionTarget.computeType(compiler) |
| 3065 .subst(type.typeArguments, targetClass.typeVariables); | 3103 .subst(type.typeArguments, targetClass.typeVariables); |
| 3066 FunctionType constructorType = constructor.computeType(compiler); | 3104 FunctionType constructorType = constructor.computeType(compiler); |
| 3067 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); | 3105 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); |
| 3068 if (!isSubtype) { | 3106 if (!isSubtype) { |
| 3069 warning(node, MessageKind.NOT_ASSIGNABLE, | 3107 warning(node, MessageKind.NOT_ASSIGNABLE, |
| 3070 {'fromType': targetType, 'toType': constructorType}); | 3108 {'fromType': targetType, 'toType': constructorType}); |
| 3071 } | 3109 } |
| 3072 | 3110 |
| 3073 FunctionSignature targetSignature = | 3111 FunctionSignature targetSignature = |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3294 | 3332 |
| 3295 /** | 3333 /** |
| 3296 * Try to resolve the constructor that is referred to by [node]. | 3334 * Try to resolve the constructor that is referred to by [node]. |
| 3297 * Note: this function may return an ErroneousFunctionElement instead of | 3335 * Note: this function may return an ErroneousFunctionElement instead of |
| 3298 * [:null:], if there is no corresponding constructor, class or library. | 3336 * [:null:], if there is no corresponding constructor, class or library. |
| 3299 */ | 3337 */ |
| 3300 ConstructorElement resolveConstructor(NewExpression node) { | 3338 ConstructorElement resolveConstructor(NewExpression node) { |
| 3301 return node.accept(new ConstructorResolver(compiler, this)); | 3339 return node.accept(new ConstructorResolver(compiler, this)); |
| 3302 } | 3340 } |
| 3303 | 3341 |
| 3304 ConstructorElement resolveRedirectingFactory(Return node, | 3342 ConstructorElement resolveRedirectingFactory(RedirectingFactoryBody node, |
| 3305 {bool inConstContext: false}) { | 3343 {bool inConstContext: false}) { |
| 3306 return node.accept(new ConstructorResolver(compiler, this, | 3344 return node.accept(new ConstructorResolver(compiler, this, |
| 3307 inConstContext: inConstContext)); | 3345 inConstContext: inConstContext)); |
| 3308 } | 3346 } |
| 3309 | 3347 |
| 3310 DartType resolveTypeAnnotation(TypeAnnotation node, | 3348 DartType resolveTypeAnnotation(TypeAnnotation node, |
| 3311 {bool malformedIsError: false, | 3349 {bool malformedIsError: false, |
| 3312 bool deferredIsMalformed: true}) { | 3350 bool deferredIsMalformed: true}) { |
| 3313 DartType type = typeResolver.resolveTypeAnnotation( | 3351 DartType type = typeResolver.resolveTypeAnnotation( |
| 3314 this, node, malformedIsError: malformedIsError, | 3352 this, node, malformedIsError: malformedIsError, |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3492 } | 3530 } |
| 3493 if (loopVariableSelector != null) { | 3531 if (loopVariableSelector != null) { |
| 3494 registry.setSelector(declaration, loopVariableSelector); | 3532 registry.setSelector(declaration, loopVariableSelector); |
| 3495 registerSend(loopVariableSelector, loopVariable); | 3533 registerSend(loopVariableSelector, loopVariable); |
| 3496 } else { | 3534 } else { |
| 3497 // The selector may only be null if we reported an error. | 3535 // The selector may only be null if we reported an error. |
| 3498 assert(invariant(declaration, compiler.compilationFailed)); | 3536 assert(invariant(declaration, compiler.compilationFailed)); |
| 3499 } | 3537 } |
| 3500 if (loopVariable != null) { | 3538 if (loopVariable != null) { |
| 3501 // loopVariable may be null if it could not be resolved. | 3539 // loopVariable may be null if it could not be resolved. |
| 3502 registry.defineElement(declaration, loopVariable); | 3540 registry.setForInVariable(node, loopVariable); |
| 3503 } | 3541 } |
| 3504 visitLoopBodyIn(node, node.body, blockScope); | 3542 visitLoopBodyIn(node, node.body, blockScope); |
| 3505 } | 3543 } |
| 3506 | 3544 |
| 3507 visitLabel(Label node) { | 3545 visitLabel(Label node) { |
| 3508 // Labels are handled by their containing statements/cases. | 3546 // Labels are handled by their containing statements/cases. |
| 3509 } | 3547 } |
| 3510 | 3548 |
| 3511 visitLabeledStatement(LabeledStatement node) { | 3549 visitLabeledStatement(LabeledStatement node) { |
| 3512 Statement body = node.statement; | 3550 Statement body = node.statement; |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3928 TypedefType type = element.computeType(compiler); | 3966 TypedefType type = element.computeType(compiler); |
| 3929 scope = new TypeDeclarationScope(scope, element); | 3967 scope = new TypeDeclarationScope(scope, element); |
| 3930 resolveTypeVariableBounds(node.typeParameters); | 3968 resolveTypeVariableBounds(node.typeParameters); |
| 3931 | 3969 |
| 3932 FunctionSignature signature = SignatureResolver.analyze( | 3970 FunctionSignature signature = SignatureResolver.analyze( |
| 3933 compiler, node.formals, node.returnType, element, registry, | 3971 compiler, node.formals, node.returnType, element, registry, |
| 3934 defaultValuesError: MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT); | 3972 defaultValuesError: MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT); |
| 3935 element.functionSignature = signature; | 3973 element.functionSignature = signature; |
| 3936 | 3974 |
| 3937 scope = new MethodScope(scope, element); | 3975 scope = new MethodScope(scope, element); |
| 3938 signature.forEachParameter((FormalElement element) { | 3976 signature.forEachParameter(addToScope); |
| 3939 defineElement(element.node, element); | |
| 3940 }); | |
| 3941 | 3977 |
| 3942 element.alias = signature.type; | 3978 element.alias = signature.type; |
| 3943 | 3979 |
| 3944 void checkCyclicReference() { | 3980 void checkCyclicReference() { |
| 3945 element.checkCyclicReference(compiler); | 3981 element.checkCyclicReference(compiler); |
| 3946 } | 3982 } |
| 3947 addDeferredAction(element, checkCyclicReference); | 3983 addDeferredAction(element, checkCyclicReference); |
| 3948 } | 3984 } |
| 3949 } | 3985 } |
| 3950 | 3986 |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4577 if (definitions.modifiers.isFinal && | 4613 if (definitions.modifiers.isFinal && |
| 4578 !resolver.allowFinalWithoutInitializer) { | 4614 !resolver.allowFinalWithoutInitializer) { |
| 4579 compiler.reportError(node, MessageKind.FINAL_WITHOUT_INITIALIZER); | 4615 compiler.reportError(node, MessageKind.FINAL_WITHOUT_INITIALIZER); |
| 4580 } | 4616 } |
| 4581 return node; | 4617 return node; |
| 4582 } | 4618 } |
| 4583 | 4619 |
| 4584 visitNodeList(NodeList node) { | 4620 visitNodeList(NodeList node) { |
| 4585 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 4621 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 4586 Identifier name = visit(link.head); | 4622 Identifier name = visit(link.head); |
| 4587 VariableElement element = new LocalVariableElementX( | 4623 LocalVariableElement element = new LocalVariableElementX( |
| 4588 name.source, resolver.enclosingElement, | 4624 name.source, resolver.enclosingElement, |
| 4589 variables, name.token); | 4625 variables, name.token); |
| 4590 resolver.defineElement(link.head, element); | 4626 resolver.defineLocalVariable(link.head, element); |
| 4627 resolver.addToScope(element); |
| 4591 if (definitions.modifiers.isConst) { | 4628 if (definitions.modifiers.isConst) { |
| 4592 compiler.enqueuer.resolution.addDeferredAction(element, () { | 4629 compiler.enqueuer.resolution.addDeferredAction(element, () { |
| 4593 compiler.resolver.constantCompiler.compileConstant(element); | 4630 compiler.resolver.constantCompiler.compileConstant(element); |
| 4594 }); | 4631 }); |
| 4595 } | 4632 } |
| 4596 } | 4633 } |
| 4597 } | 4634 } |
| 4598 } | 4635 } |
| 4599 | 4636 |
| 4600 class ConstructorResolver extends CommonResolverVisitor<Element> { | 4637 class ConstructorResolver extends CommonResolverVisitor<Element> { |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4760 } else if (element.isTypeVariable) { | 4797 } else if (element.isTypeVariable) { |
| 4761 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, | 4798 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, |
| 4762 {'typeVariableName': name}); | 4799 {'typeVariableName': name}); |
| 4763 } else if (!element.isClass && !element.isPrefix) { | 4800 } else if (!element.isClass && !element.isPrefix) { |
| 4764 error(node, MessageKind.NOT_A_TYPE, {'node': name}); | 4801 error(node, MessageKind.NOT_A_TYPE, {'node': name}); |
| 4765 } | 4802 } |
| 4766 return element; | 4803 return element; |
| 4767 } | 4804 } |
| 4768 | 4805 |
| 4769 /// Assumed to be called by [resolveRedirectingFactory]. | 4806 /// Assumed to be called by [resolveRedirectingFactory]. |
| 4770 Element visitReturn(Return node) { | 4807 Element visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
| 4771 Node expression = node.expression; | 4808 Node constructorReference = node.constructorReference; |
| 4772 return finishConstructorReference(visit(expression), | 4809 return finishConstructorReference(visit(constructorReference), |
| 4773 expression, expression); | 4810 constructorReference, node); |
| 4774 } | 4811 } |
| 4775 } | 4812 } |
| 4776 | 4813 |
| 4777 /// Looks up [name] in [scope] and unwraps the result. | 4814 /// Looks up [name] in [scope] and unwraps the result. |
| 4778 Element lookupInScope(Compiler compiler, Node node, | 4815 Element lookupInScope(Compiler compiler, Node node, |
| 4779 Scope scope, String name) { | 4816 Scope scope, String name) { |
| 4780 return Elements.unwrap(scope.lookup(name), compiler, node); | 4817 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4781 } | 4818 } |
| 4782 | 4819 |
| 4783 TreeElements _ensureTreeElements(AnalyzableElementX element) { | 4820 TreeElements _ensureTreeElements(AnalyzableElementX element) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4833 } | 4870 } |
| 4834 | 4871 |
| 4835 /// The result for the resolution of the `assert` method. | 4872 /// The result for the resolution of the `assert` method. |
| 4836 class AssertResult implements ResolutionResult { | 4873 class AssertResult implements ResolutionResult { |
| 4837 const AssertResult(); | 4874 const AssertResult(); |
| 4838 | 4875 |
| 4839 Element get element => null; | 4876 Element get element => null; |
| 4840 | 4877 |
| 4841 String toString() => 'AssertResult()'; | 4878 String toString() => 'AssertResult()'; |
| 4842 } | 4879 } |
| OLD | NEW |