| 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 Set<Node> get superUses; | 9 Set<Node> get superUses; |
| 10 | 10 |
| 11 /// A set of additional dependencies. See [registerDependency] below. | 11 /// A set of additional dependencies. See [registerDependency] below. |
| 12 Set<Element> get otherDependencies; | 12 Set<Element> get otherDependencies; |
| 13 | 13 |
| 14 Element operator[](Node node); | 14 Element operator[](Node node); |
| 15 Selector getSelector(Send send); | 15 Selector getSelector(Send send); |
| 16 Selector getGetterSelectorInComplexSendSet(SendSet node); | 16 Selector getGetterSelectorInComplexSendSet(SendSet node); |
| 17 Selector getOperatorSelectorInComplexSendSet(SendSet node); | 17 Selector getOperatorSelectorInComplexSendSet(SendSet node); |
| 18 DartType getType(Node node); | 18 DartType getType(Node node); |
| 19 void setSelector(Node node, Selector selector); | 19 void setSelector(Node node, Selector selector); |
| 20 void setGetterSelectorInComplexSendSet(SendSet node, Selector selector); | 20 void setGetterSelectorInComplexSendSet(SendSet node, Selector selector); |
| 21 void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector); | 21 void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector); |
| 22 Selector getIteratorSelector(ForIn node); | 22 Selector getIteratorSelector(ForIn node); |
| 23 Selector getMoveNextSelector(ForIn node); | 23 Selector getMoveNextSelector(ForIn node); |
| 24 Selector getCurrentSelector(ForIn node); | 24 Selector getCurrentSelector(ForIn node); |
| 25 Selector setIteratorSelector(ForIn node, Selector selector); | 25 Selector setIteratorSelector(ForIn node, Selector selector); |
| 26 Selector setMoveNextSelector(ForIn node, Selector selector); | 26 Selector setMoveNextSelector(ForIn node, Selector selector); |
| 27 Selector setCurrentSelector(ForIn node, Selector selector); | 27 Selector setCurrentSelector(ForIn node, Selector selector); |
| 28 void setConstant(Node node, Constant constant); |
| 29 Constant getConstant(Node node); |
| 28 | 30 |
| 29 /** | 31 /** |
| 30 * Returns [:true:] if [node] is a type literal. | 32 * Returns [:true:] if [node] is a type literal. |
| 31 * | 33 * |
| 32 * Resolution marks this by setting the type on the node to be the | 34 * Resolution marks this by setting the type on the node to be the |
| 33 * [:Type:] type. | 35 * [:Type:] type. |
| 34 */ | 36 */ |
| 35 bool isTypeLiteral(Send node); | 37 bool isTypeLiteral(Send node); |
| 36 | 38 |
| 37 /// Register additional dependencies required by [currentElement]. | 39 /// Register additional dependencies required by [currentElement]. |
| 38 /// For example, elements that are used by a backend. | 40 /// For example, elements that are used by a backend. |
| 39 void registerDependency(Element element); | 41 void registerDependency(Element element); |
| 40 } | 42 } |
| 41 | 43 |
| 42 class TreeElementMapping implements TreeElements { | 44 class TreeElementMapping implements TreeElements { |
| 43 final Element currentElement; | 45 final Element currentElement; |
| 44 final Map<Spannable, Selector> selectors = | 46 final Map<Spannable, Selector> selectors = |
| 45 new LinkedHashMap<Spannable, Selector>(); | 47 new LinkedHashMap<Spannable, Selector>(); |
| 46 final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>(); | 48 final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>(); |
| 47 final Set<Node> superUses = new LinkedHashSet<Node>(); | 49 final Set<Node> superUses = new LinkedHashSet<Node>(); |
| 48 final Set<Element> otherDependencies = new LinkedHashSet<Element>(); | 50 final Set<Element> otherDependencies = new LinkedHashSet<Element>(); |
| 51 final Map<Node, Constant> constants = new Map<Node, Constant>(); |
| 49 final int hashCode = ++hashCodeCounter; | 52 final int hashCode = ++hashCodeCounter; |
| 50 static int hashCodeCounter = 0; | 53 static int hashCodeCounter = 0; |
| 51 | 54 |
| 52 TreeElementMapping(this.currentElement); | 55 TreeElementMapping(this.currentElement); |
| 53 | 56 |
| 54 operator []=(Node node, Element element) { | 57 operator []=(Node node, Element element) { |
| 55 assert(invariant(node, () { | 58 assert(invariant(node, () { |
| 56 FunctionExpression functionExpression = node.asFunctionExpression(); | 59 FunctionExpression functionExpression = node.asFunctionExpression(); |
| 57 if (functionExpression != null) { | 60 if (functionExpression != null) { |
| 58 return !functionExpression.modifiers.isExternal(); | 61 return !functionExpression.modifiers.isExternal(); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 } | 136 } |
| 134 | 137 |
| 135 Selector setCurrentSelector(ForIn node, Selector selector) { | 138 Selector setCurrentSelector(ForIn node, Selector selector) { |
| 136 selectors[node.inToken] = selector; | 139 selectors[node.inToken] = selector; |
| 137 } | 140 } |
| 138 | 141 |
| 139 Selector getCurrentSelector(ForIn node) { | 142 Selector getCurrentSelector(ForIn node) { |
| 140 return selectors[node.inToken]; | 143 return selectors[node.inToken]; |
| 141 } | 144 } |
| 142 | 145 |
| 146 void setConstant(Node node, Constant constant) { |
| 147 constants[node] = constant; |
| 148 } |
| 149 |
| 150 Constant getConstant(Node node) { |
| 151 return constants[node]; |
| 152 } |
| 153 |
| 143 bool isTypeLiteral(Send node) { | 154 bool isTypeLiteral(Send node) { |
| 144 return getType(node) != null; | 155 return getType(node) != null; |
| 145 } | 156 } |
| 146 | 157 |
| 147 void registerDependency(Element element) { | 158 void registerDependency(Element element) { |
| 148 otherDependencies.add(element.implementation); | 159 otherDependencies.add(element.implementation); |
| 149 } | 160 } |
| 150 | 161 |
| 151 String toString() => 'TreeElementMapping($currentElement)'; | 162 String toString() => 'TreeElementMapping($currentElement)'; |
| 152 } | 163 } |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 } | 352 } |
| 342 | 353 |
| 343 TreeElements resolveMethodElement(FunctionElement element) { | 354 TreeElements resolveMethodElement(FunctionElement element) { |
| 344 assert(invariant(element, element.isDeclaration)); | 355 assert(invariant(element, element.isDeclaration)); |
| 345 return compiler.withCurrentElement(element, () { | 356 return compiler.withCurrentElement(element, () { |
| 346 bool isConstructor = | 357 bool isConstructor = |
| 347 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR); | 358 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR); |
| 348 TreeElements elements = | 359 TreeElements elements = |
| 349 compiler.enqueuer.resolution.getCachedElements(element); | 360 compiler.enqueuer.resolution.getCachedElements(element); |
| 350 if (elements != null) { | 361 if (elements != null) { |
| 351 assert(isConstructor); | 362 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] |
| 363 // should never be non-null, not even for constructors. |
| 364 assert(invariant(element, isConstructor, |
| 365 message: 'Non-constructor element $element ' |
| 366 'has already been analyzed.')); |
| 352 return elements; | 367 return elements; |
| 353 } | 368 } |
| 354 if (element.isSynthesized) { | 369 if (element.isSynthesized) { |
| 355 Element target = element.targetConstructor; | 370 Element target = element.targetConstructor; |
| 356 // Ensure the signature of the synthesized element is | 371 // Ensure the signature of the synthesized element is |
| 357 // resolved. This is the only place where the resolver is | 372 // resolved. This is the only place where the resolver is |
| 358 // seeing this element. | 373 // seeing this element. |
| 359 element.computeSignature(compiler); | 374 element.computeSignature(compiler); |
| 360 if (!target.isErroneous()) { | 375 if (!target.isErroneous()) { |
| 361 compiler.enqueuer.resolution.registerStaticUse( | 376 compiler.enqueuer.resolution.registerStaticUse( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 FunctionElement redirection = | 410 FunctionElement redirection = |
| 396 resolver.resolveInitializers(element, tree); | 411 resolver.resolveInitializers(element, tree); |
| 397 if (redirection != null) { | 412 if (redirection != null) { |
| 398 resolveRedirectingConstructor(resolver, tree, element, redirection); | 413 resolveRedirectingConstructor(resolver, tree, element, redirection); |
| 399 } | 414 } |
| 400 } else if (element.isForwardingConstructor) { | 415 } else if (element.isForwardingConstructor) { |
| 401 // Initializers will be checked on the original constructor. | 416 // Initializers will be checked on the original constructor. |
| 402 } else if (tree.initializers != null) { | 417 } else if (tree.initializers != null) { |
| 403 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER); | 418 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER); |
| 404 } | 419 } |
| 405 visitBody(visitor, tree.body); | 420 |
| 421 if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) { |
| 422 // We need to analyze the redirecting factory bodies to ensure that |
| 423 // we can analyze compile-time constants. |
| 424 visitor.visit(tree.body); |
| 425 } |
| 406 | 426 |
| 407 // Get the resolution tree and check that the resolved | 427 // Get the resolution tree and check that the resolved |
| 408 // function doesn't use 'super' if it is mixed into another | 428 // function doesn't use 'super' if it is mixed into another |
| 409 // class. This is the part of the 'super' mixin check that | 429 // class. This is the part of the 'super' mixin check that |
| 410 // happens when a function is resolved after the mixin | 430 // happens when a function is resolved after the mixin |
| 411 // application has been performed. | 431 // application has been performed. |
| 412 TreeElements resolutionTree = visitor.mapping; | 432 TreeElements resolutionTree = visitor.mapping; |
| 413 ClassElement enclosingClass = element.getEnclosingClass(); | 433 ClassElement enclosingClass = element.getEnclosingClass(); |
| 414 if (enclosingClass != null) { | 434 if (enclosingClass != null) { |
| 415 Set<MixinApplicationElement> mixinUses = | 435 Set<MixinApplicationElement> mixinUses = |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 SendSet send = tree.asSendSet(); | 471 SendSet send = tree.asSendSet(); |
| 452 if (send != null) { | 472 if (send != null) { |
| 453 // TODO(johnniwinther): Avoid analyzing initializers if | 473 // TODO(johnniwinther): Avoid analyzing initializers if |
| 454 // [Compiler.analyzeSignaturesOnly] is set. | 474 // [Compiler.analyzeSignaturesOnly] is set. |
| 455 visitor.visit(send.arguments.head); | 475 visitor.visit(send.arguments.head); |
| 456 } else if (element.modifiers.isConst()) { | 476 } else if (element.modifiers.isConst()) { |
| 457 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER); | 477 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER); |
| 458 } | 478 } |
| 459 | 479 |
| 460 if (Elements.isStaticOrTopLevelField(element)) { | 480 if (Elements.isStaticOrTopLevelField(element)) { |
| 481 visitor.addPostProcessAction(element, () { |
| 482 compiler.constantHandler.compileVariable( |
| 483 element, isConst: element.modifiers.isConst()); |
| 484 }); |
| 461 if (tree.asSendSet() != null) { | 485 if (tree.asSendSet() != null) { |
| 462 // TODO(13429): We could do better here by using the | 486 if (!element.modifiers.isConst()) { |
| 463 // constant handler to figure out if it's a lazy field or not. | 487 // TODO(johnniwinther): Determine the const-ness eagerly to avoid |
| 464 compiler.backend.registerLazyField(visitor.mapping); | 488 // unnecessary registrations. |
| 489 compiler.backend.registerLazyField(visitor.mapping); |
| 490 } |
| 465 } else { | 491 } else { |
| 466 compiler.enqueuer.resolution.registerInstantiatedClass( | 492 compiler.enqueuer.resolution.registerInstantiatedClass( |
| 467 compiler.nullClass, visitor.mapping); | 493 compiler.nullClass, visitor.mapping); |
| 468 } | 494 } |
| 469 } | 495 } |
| 470 | 496 |
| 471 // Perform various checks as side effect of "computing" the type. | 497 // Perform various checks as side effect of "computing" the type. |
| 472 element.computeType(compiler); | 498 element.computeType(compiler); |
| 473 | 499 |
| 474 return visitor.mapping; | 500 return visitor.mapping; |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 annotation.resolutionState = STATE_STARTED; | 1062 annotation.resolutionState = STATE_STARTED; |
| 1037 | 1063 |
| 1038 Node node = annotation.parseNode(compiler); | 1064 Node node = annotation.parseNode(compiler); |
| 1039 Element annotatedElement = annotation.annotatedElement; | 1065 Element annotatedElement = annotation.annotatedElement; |
| 1040 Element context = annotatedElement.enclosingElement; | 1066 Element context = annotatedElement.enclosingElement; |
| 1041 if (context == null) { | 1067 if (context == null) { |
| 1042 context = annotatedElement; | 1068 context = annotatedElement; |
| 1043 } | 1069 } |
| 1044 ResolverVisitor visitor = visitorFor(context); | 1070 ResolverVisitor visitor = visitorFor(context); |
| 1045 node.accept(visitor); | 1071 node.accept(visitor); |
| 1046 annotation.value = compiler.metadataHandler.compileNodeWithDefinitions( | 1072 annotation.value = compiler.constantHandler.compileNodeWithDefinitions( |
| 1047 node, visitor.mapping, isConst: true); | 1073 node, visitor.mapping, isConst: true); |
| 1074 compiler.backend.registerMetadataConstant(annotation.value, |
| 1075 visitor.mapping); |
| 1048 | 1076 |
| 1049 annotation.resolutionState = STATE_DONE; | 1077 annotation.resolutionState = STATE_DONE; |
| 1050 })); | 1078 })); |
| 1051 } | 1079 } |
| 1052 | 1080 |
| 1053 error(Node node, MessageKind kind, [arguments = const {}]) { | 1081 error(Node node, MessageKind kind, [arguments = const {}]) { |
| 1054 // TODO(ahe): Make non-fatal. | 1082 // TODO(ahe): Make non-fatal. |
| 1055 compiler.reportFatalError(node, kind, arguments); | 1083 compiler.reportFatalError(node, kind, arguments); |
| 1056 } | 1084 } |
| 1057 } | 1085 } |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1388 compiler.cancel(message, node: node); | 1416 compiler.cancel(message, node: node); |
| 1389 } | 1417 } |
| 1390 | 1418 |
| 1391 void internalError(Node node, String message) { | 1419 void internalError(Node node, String message) { |
| 1392 compiler.internalError(message, node: node); | 1420 compiler.internalError(message, node: node); |
| 1393 } | 1421 } |
| 1394 | 1422 |
| 1395 void unimplemented(Node node, String message) { | 1423 void unimplemented(Node node, String message) { |
| 1396 compiler.unimplemented(message, node: node); | 1424 compiler.unimplemented(message, node: node); |
| 1397 } | 1425 } |
| 1426 |
| 1427 void addPostProcessAction(Element element, PostProcessAction action) { |
| 1428 compiler.enqueuer.resolution.addPostProcessAction(element, action); |
| 1429 } |
| 1398 } | 1430 } |
| 1399 | 1431 |
| 1400 abstract class LabelScope { | 1432 abstract class LabelScope { |
| 1401 LabelScope get outer; | 1433 LabelScope get outer; |
| 1402 LabelElement lookup(String label); | 1434 LabelElement lookup(String label); |
| 1403 } | 1435 } |
| 1404 | 1436 |
| 1405 class LabeledStatementLabelScope implements LabelScope { | 1437 class LabeledStatementLabelScope implements LabelScope { |
| 1406 final LabelScope outer; | 1438 final LabelScope outer; |
| 1407 final Map<String, LabelElement> labels; | 1439 final Map<String, LabelElement> labels; |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1650 type = checkNoTypeArguments(type); | 1682 type = checkNoTypeArguments(type); |
| 1651 } else { | 1683 } else { |
| 1652 compiler.cancel("unexpected element kind ${element.kind}", | 1684 compiler.cancel("unexpected element kind ${element.kind}", |
| 1653 node: node); | 1685 node: node); |
| 1654 } | 1686 } |
| 1655 // TODO(johnniwinther): We should not resolve type annotations after the | 1687 // TODO(johnniwinther): We should not resolve type annotations after the |
| 1656 // resolution queue has been closed. Currently the dart backend does so. | 1688 // resolution queue has been closed. Currently the dart backend does so. |
| 1657 // Remove the guarded when this is fixed. | 1689 // Remove the guarded when this is fixed. |
| 1658 if (!compiler.enqueuer.resolution.queueIsClosed && | 1690 if (!compiler.enqueuer.resolution.queueIsClosed && |
| 1659 addTypeVariableBoundsCheck) { | 1691 addTypeVariableBoundsCheck) { |
| 1660 compiler.enqueuer.resolution.addPostProcessAction( | 1692 visitor.addPostProcessAction( |
| 1661 visitor.enclosingElement, | 1693 visitor.enclosingElement, |
| 1662 () => checkTypeVariableBounds(node, type)); | 1694 () => checkTypeVariableBounds(node, type)); |
| 1663 } | 1695 } |
| 1664 } | 1696 } |
| 1665 visitor.useType(node, type); | 1697 visitor.useType(node, type); |
| 1666 return type; | 1698 return type; |
| 1667 } | 1699 } |
| 1668 | 1700 |
| 1669 /// Checks the type arguments of [type] against the type variable bounds. | 1701 /// Checks the type arguments of [type] against the type variable bounds. |
| 1670 void checkTypeVariableBounds(TypeAnnotation node, GenericType type) { | 1702 void checkTypeVariableBounds(TypeAnnotation node, GenericType type) { |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2026 initializerDo(parameterNode, (n) => n.accept(this)); | 2058 initializerDo(parameterNode, (n) => n.accept(this)); |
| 2027 // Field parameters (this.x) are not visible inside the constructor. The | 2059 // Field parameters (this.x) are not visible inside the constructor. The |
| 2028 // fields they reference are visible, but must be resolved independently. | 2060 // fields they reference are visible, but must be resolved independently. |
| 2029 if (element.kind == ElementKind.FIELD_PARAMETER) { | 2061 if (element.kind == ElementKind.FIELD_PARAMETER) { |
| 2030 useElement(parameterNode, element); | 2062 useElement(parameterNode, element); |
| 2031 } else { | 2063 } else { |
| 2032 defineElement(variableDefinitions.definitions.nodes.head, element); | 2064 defineElement(variableDefinitions.definitions.nodes.head, element); |
| 2033 } | 2065 } |
| 2034 parameterNodes = parameterNodes.tail; | 2066 parameterNodes = parameterNodes.tail; |
| 2035 }); | 2067 }); |
| 2068 addPostProcessAction(enclosingElement, () { |
| 2069 functionParameters.forEachOptionalParameter((Element parameter) { |
| 2070 compiler.constantHandler.compileConstant(parameter); |
| 2071 }); |
| 2072 }); |
| 2036 if (inCheckContext) { | 2073 if (inCheckContext) { |
| 2037 functionParameters.forEachParameter((Element element) { | 2074 functionParameters.forEachParameter((Element element) { |
| 2038 compiler.enqueuer.resolution.registerIsCheck( | 2075 compiler.enqueuer.resolution.registerIsCheck( |
| 2039 element.computeType(compiler), mapping); | 2076 element.computeType(compiler), mapping); |
| 2040 }); | 2077 }); |
| 2041 } | 2078 } |
| 2042 } | 2079 } |
| 2043 | 2080 |
| 2044 visitCascade(Cascade node) { | 2081 visitCascade(Cascade node) { |
| 2045 visit(node.expression); | 2082 visit(node.expression); |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2397 compiler.backend.registerTypeVariableExpression(mapping); | 2434 compiler.backend.registerTypeVariableExpression(mapping); |
| 2398 // Set the type of the node to [Type] to mark this send as a | 2435 // Set the type of the node to [Type] to mark this send as a |
| 2399 // type variable expression. | 2436 // type variable expression. |
| 2400 mapping.setType(node, compiler.typeClass.computeType(compiler)); | 2437 mapping.setType(node, compiler.typeClass.computeType(compiler)); |
| 2401 world.registerTypeLiteral(target, mapping); | 2438 world.registerTypeLiteral(target, mapping); |
| 2402 } else if (target.impliesType() && !sendIsMemberAccess) { | 2439 } else if (target.impliesType() && !sendIsMemberAccess) { |
| 2403 // Set the type of the node to [Type] to mark this send as a | 2440 // Set the type of the node to [Type] to mark this send as a |
| 2404 // type literal. | 2441 // type literal. |
| 2405 mapping.setType(node, compiler.typeClass.computeType(compiler)); | 2442 mapping.setType(node, compiler.typeClass.computeType(compiler)); |
| 2406 world.registerTypeLiteral(target, mapping); | 2443 world.registerTypeLiteral(target, mapping); |
| 2444 analyzeConstant(node); |
| 2407 } | 2445 } |
| 2408 } | 2446 } |
| 2409 | 2447 |
| 2410 bool resolvedArguments = false; | 2448 bool resolvedArguments = false; |
| 2411 if (node.isOperator) { | 2449 if (node.isOperator) { |
| 2412 String operatorString = node.selector.asOperator().source.stringValue; | 2450 String operatorString = node.selector.asOperator().source.stringValue; |
| 2413 if (identical(operatorString, 'is')) { | 2451 if (identical(operatorString, 'is')) { |
| 2414 DartType type = | 2452 DartType type = |
| 2415 resolveTypeExpression(node.typeAnnotationFromIsCheckOrCast); | 2453 resolveTypeExpression(node.typeAnnotationFromIsCheckOrCast); |
| 2416 if (type != null) { | 2454 if (type != null) { |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2617 } | 2655 } |
| 2618 | 2656 |
| 2619 visitLiteralSymbol(LiteralSymbol node) { | 2657 visitLiteralSymbol(LiteralSymbol node) { |
| 2620 world.registerInstantiatedClass(compiler.symbolClass, mapping); | 2658 world.registerInstantiatedClass(compiler.symbolClass, mapping); |
| 2621 world.registerStaticUse(compiler.symbolConstructor.declaration); | 2659 world.registerStaticUse(compiler.symbolConstructor.declaration); |
| 2622 world.registerConstSymbol(node.slowNameString, mapping); | 2660 world.registerConstSymbol(node.slowNameString, mapping); |
| 2623 if (!validateSymbol(node, node.slowNameString, reportError: false)) { | 2661 if (!validateSymbol(node, node.slowNameString, reportError: false)) { |
| 2624 compiler.reportError(node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL, | 2662 compiler.reportError(node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL, |
| 2625 {'value': node.slowNameString}); | 2663 {'value': node.slowNameString}); |
| 2626 } | 2664 } |
| 2665 analyzeConstant(node); |
| 2627 } | 2666 } |
| 2628 | 2667 |
| 2629 visitStringJuxtaposition(StringJuxtaposition node) { | 2668 visitStringJuxtaposition(StringJuxtaposition node) { |
| 2630 world.registerInstantiatedClass(compiler.stringClass, mapping); | 2669 world.registerInstantiatedClass(compiler.stringClass, mapping); |
| 2631 node.visitChildren(this); | 2670 node.visitChildren(this); |
| 2632 } | 2671 } |
| 2633 | 2672 |
| 2634 visitNodeList(NodeList node) { | 2673 visitNodeList(NodeList node) { |
| 2635 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 2674 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 2636 visit(link.head); | 2675 visit(link.head); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2702 redirectionTarget.computeSignature(compiler); | 2741 redirectionTarget.computeSignature(compiler); |
| 2703 FunctionSignature constructorSignature = | 2742 FunctionSignature constructorSignature = |
| 2704 constructor.computeSignature(compiler); | 2743 constructor.computeSignature(compiler); |
| 2705 if (!targetSignature.isCompatibleWith(constructorSignature)) { | 2744 if (!targetSignature.isCompatibleWith(constructorSignature)) { |
| 2706 assert(!isSubtype); | 2745 assert(!isSubtype); |
| 2707 compiler.backend.registerThrowNoSuchMethod(mapping); | 2746 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2708 } | 2747 } |
| 2709 | 2748 |
| 2710 // Register a post process to check for cycles in the redirection chain and | 2749 // Register a post process to check for cycles in the redirection chain and |
| 2711 // set the actual generative constructor at the end of the chain. | 2750 // set the actual generative constructor at the end of the chain. |
| 2712 compiler.enqueuer.resolution.addPostProcessAction(constructor, () { | 2751 addPostProcessAction(constructor, () { |
| 2713 compiler.resolver.resolveRedirectionChain(constructor, node); | 2752 compiler.resolver.resolveRedirectionChain(constructor, node); |
| 2714 }); | 2753 }); |
| 2715 | 2754 |
| 2716 world.registerStaticUse(redirectionTarget); | 2755 world.registerStaticUse(redirectionTarget); |
| 2717 world.registerInstantiatedClass( | 2756 world.registerInstantiatedClass( |
| 2718 redirectionTarget.enclosingElement.declaration, mapping); | 2757 redirectionTarget.enclosingElement.declaration, mapping); |
| 2719 if (isSymbolConstructor) { | 2758 if (isSymbolConstructor) { |
| 2720 compiler.backend.registerSymbolConstructor(mapping); | 2759 compiler.backend.registerSymbolConstructor(mapping); |
| 2721 } | 2760 } |
| 2722 } | 2761 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2814 world.registerFactoryWithTypeArguments(mapping); | 2853 world.registerFactoryWithTypeArguments(mapping); |
| 2815 } | 2854 } |
| 2816 if (constructor.isGenerativeConstructor() && cls.isAbstract(compiler)) { | 2855 if (constructor.isGenerativeConstructor() && cls.isAbstract(compiler)) { |
| 2817 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); | 2856 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); |
| 2818 compiler.backend.registerAbstractClassInstantiation(mapping); | 2857 compiler.backend.registerAbstractClassInstantiation(mapping); |
| 2819 } | 2858 } |
| 2820 | 2859 |
| 2821 if (isSymbolConstructor) { | 2860 if (isSymbolConstructor) { |
| 2822 if (node.isConst()) { | 2861 if (node.isConst()) { |
| 2823 Node argumentNode = node.send.arguments.head; | 2862 Node argumentNode = node.send.arguments.head; |
| 2824 Constant name = compiler.metadataHandler.compileNodeWithDefinitions( | 2863 Constant name = compiler.constantHandler.compileNodeWithDefinitions( |
| 2825 argumentNode, mapping, isConst: true); | 2864 argumentNode, mapping, isConst: true); |
| 2826 if (!name.isString()) { | 2865 if (!name.isString()) { |
| 2827 DartType type = name.computeType(compiler); | 2866 DartType type = name.computeType(compiler); |
| 2828 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, | 2867 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, |
| 2829 {'type': type}); | 2868 {'type': type}); |
| 2830 } else { | 2869 } else { |
| 2831 StringConstant stringConstant = name; | 2870 StringConstant stringConstant = name; |
| 2832 String nameString = stringConstant.toDartString().slowToString(); | 2871 String nameString = stringConstant.toDartString().slowToString(); |
| 2833 if (validateSymbol(argumentNode, nameString)) { | 2872 if (validateSymbol(argumentNode, nameString)) { |
| 2834 world.registerConstSymbol(nameString, mapping); | 2873 world.registerConstSymbol(nameString, mapping); |
| 2835 } | 2874 } |
| 2836 } | 2875 } |
| 2837 } else { | 2876 } else { |
| 2838 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( | 2877 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( |
| 2839 enclosingElement)) { | 2878 enclosingElement)) { |
| 2840 compiler.reportHint( | 2879 compiler.reportHint( |
| 2841 node.newToken, MessageKind.NON_CONST_BLOAT, | 2880 node.newToken, MessageKind.NON_CONST_BLOAT, |
| 2842 {'name': compiler.symbolClass.name}); | 2881 {'name': compiler.symbolClass.name}); |
| 2843 } | 2882 } |
| 2844 world.registerNewSymbol(mapping); | 2883 world.registerNewSymbol(mapping); |
| 2845 } | 2884 } |
| 2846 } else if (isMirrorsUsedConstant) { | 2885 } else if (isMirrorsUsedConstant) { |
| 2847 compiler.mirrorUsageAnalyzerTask.validate(node, mapping); | 2886 compiler.mirrorUsageAnalyzerTask.validate(node, mapping); |
| 2848 } | 2887 } |
| 2888 if (node.isConst()) { |
| 2889 analyzeConstant(node); |
| 2890 } |
| 2849 | 2891 |
| 2850 return null; | 2892 return null; |
| 2851 } | 2893 } |
| 2852 | 2894 |
| 2895 void analyzeConstant(Node node) { |
| 2896 addPostProcessAction(enclosingElement, () { |
| 2897 mapping.setConstant(node, |
| 2898 compiler.constantHandler.compileNodeWithDefinitions( |
| 2899 node, mapping, isConst: true)); |
| 2900 }); |
| 2901 } |
| 2902 |
| 2853 bool validateSymbol(Node node, String name, {bool reportError: true}) { | 2903 bool validateSymbol(Node node, String name, {bool reportError: true}) { |
| 2854 if (name.isEmpty) return true; | 2904 if (name.isEmpty) return true; |
| 2855 if (name.startsWith('_')) { | 2905 if (name.startsWith('_')) { |
| 2856 if (reportError) { | 2906 if (reportError) { |
| 2857 compiler.reportError(node, MessageKind.PRIVATE_IDENTIFIER, | 2907 compiler.reportError(node, MessageKind.PRIVATE_IDENTIFIER, |
| 2858 {'value': name}); | 2908 {'value': name}); |
| 2859 } | 2909 } |
| 2860 return false; | 2910 return false; |
| 2861 } | 2911 } |
| 2862 if (!symbolValidationPattern.hasMatch(name)) { | 2912 if (!symbolValidationPattern.hasMatch(name)) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2926 listType = new InterfaceType(compiler.listClass, | 2976 listType = new InterfaceType(compiler.listClass, |
| 2927 new Link<DartType>.fromList([typeArgument])); | 2977 new Link<DartType>.fromList([typeArgument])); |
| 2928 } else { | 2978 } else { |
| 2929 compiler.listClass.computeType(compiler); | 2979 compiler.listClass.computeType(compiler); |
| 2930 listType = compiler.listClass.rawType; | 2980 listType = compiler.listClass.rawType; |
| 2931 } | 2981 } |
| 2932 mapping.setType(node, listType); | 2982 mapping.setType(node, listType); |
| 2933 world.registerInstantiatedType(listType, mapping); | 2983 world.registerInstantiatedType(listType, mapping); |
| 2934 compiler.backend.registerRequiredType(listType, enclosingElement); | 2984 compiler.backend.registerRequiredType(listType, enclosingElement); |
| 2935 visit(node.elements); | 2985 visit(node.elements); |
| 2986 if (node.isConst()) { |
| 2987 analyzeConstant(node); |
| 2988 } |
| 2936 } | 2989 } |
| 2937 | 2990 |
| 2938 visitConditional(Conditional node) { | 2991 visitConditional(Conditional node) { |
| 2939 node.visitChildren(this); | 2992 node.visitChildren(this); |
| 2940 } | 2993 } |
| 2941 | 2994 |
| 2942 visitStringInterpolation(StringInterpolation node) { | 2995 visitStringInterpolation(StringInterpolation node) { |
| 2943 world.registerInstantiatedClass(compiler.stringClass, mapping); | 2996 world.registerInstantiatedClass(compiler.stringClass, mapping); |
| 2944 compiler.backend.registerStringInterpolation(mapping); | 2997 compiler.backend.registerStringInterpolation(mapping); |
| 2945 node.visitChildren(this); | 2998 node.visitChildren(this); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3141 compiler.reportError(arguments, | 3194 compiler.reportError(arguments, |
| 3142 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 3195 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 3143 } | 3196 } |
| 3144 mapping.setType(node, mapType); | 3197 mapping.setType(node, mapType); |
| 3145 world.registerInstantiatedClass(compiler.mapClass, mapping); | 3198 world.registerInstantiatedClass(compiler.mapClass, mapping); |
| 3146 if (node.isConst()) { | 3199 if (node.isConst()) { |
| 3147 compiler.backend.registerConstantMap(mapping); | 3200 compiler.backend.registerConstantMap(mapping); |
| 3148 } | 3201 } |
| 3149 compiler.backend.registerRequiredType(mapType, enclosingElement); | 3202 compiler.backend.registerRequiredType(mapType, enclosingElement); |
| 3150 node.visitChildren(this); | 3203 node.visitChildren(this); |
| 3204 if (node.isConst()) { |
| 3205 analyzeConstant(node); |
| 3206 } |
| 3151 } | 3207 } |
| 3152 | 3208 |
| 3153 visitLiteralMapEntry(LiteralMapEntry node) { | 3209 visitLiteralMapEntry(LiteralMapEntry node) { |
| 3154 node.visitChildren(this); | 3210 node.visitChildren(this); |
| 3155 } | 3211 } |
| 3156 | 3212 |
| 3157 visitNamedArgument(NamedArgument node) { | 3213 visitNamedArgument(NamedArgument node) { |
| 3158 visit(node.expression); | 3214 visit(node.expression); |
| 3159 } | 3215 } |
| 3160 | 3216 |
| 3161 visitSwitchStatement(SwitchStatement node) { | 3217 visitSwitchStatement(SwitchStatement node) { |
| 3162 node.expression.accept(this); | 3218 node.expression.accept(this); |
| 3163 | 3219 |
| 3164 TargetElement breakElement = getOrCreateTargetElement(node); | 3220 TargetElement breakElement = getOrCreateTargetElement(node); |
| 3165 Map<String, LabelElement> continueLabels = <String, LabelElement>{}; | 3221 Map<String, LabelElement> continueLabels = <String, LabelElement>{}; |
| 3166 Link<Node> cases = node.cases.nodes; | 3222 Link<Node> cases = node.cases.nodes; |
| 3167 while (!cases.isEmpty) { | 3223 while (!cases.isEmpty) { |
| 3168 SwitchCase switchCase = cases.head; | 3224 SwitchCase switchCase = cases.head; |
| 3169 for (Node labelOrCase in switchCase.labelsAndCases) { | 3225 for (Node labelOrCase in switchCase.labelsAndCases) { |
| 3170 if (labelOrCase is! Label) continue; | 3226 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
| 3227 if (caseMatch != null) { |
| 3228 analyzeConstant(caseMatch.expression); |
| 3229 continue; |
| 3230 } |
| 3171 Label label = labelOrCase; | 3231 Label label = labelOrCase; |
| 3172 String labelName = label.slowToString(); | 3232 String labelName = label.slowToString(); |
| 3173 | 3233 |
| 3174 LabelElement existingElement = continueLabels[labelName]; | 3234 LabelElement existingElement = continueLabels[labelName]; |
| 3175 if (existingElement != null) { | 3235 if (existingElement != null) { |
| 3176 // It's an error if the same label occurs twice in the same switch. | 3236 // It's an error if the same label occurs twice in the same switch. |
| 3177 compiler.reportError( | 3237 compiler.reportError( |
| 3178 label, | 3238 label, |
| 3179 MessageKind.DUPLICATE_LABEL.error, {'labelName': labelName}); | 3239 MessageKind.DUPLICATE_LABEL.error, {'labelName': labelName}); |
| 3180 compiler.reportInfo( | 3240 compiler.reportInfo( |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3366 // generating multiple errors for the same cyclicity. | 3426 // generating multiple errors for the same cyclicity. |
| 3367 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, | 3427 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, |
| 3368 {'typeVariableName': variableElement.name}); | 3428 {'typeVariableName': variableElement.name}); |
| 3369 } | 3429 } |
| 3370 break; | 3430 break; |
| 3371 } | 3431 } |
| 3372 seenTypeVariables = seenTypeVariables.prepend(element); | 3432 seenTypeVariables = seenTypeVariables.prepend(element); |
| 3373 bound = element.bound; | 3433 bound = element.bound; |
| 3374 } | 3434 } |
| 3375 } | 3435 } |
| 3376 compiler.enqueuer.resolution.addPostProcessAction( | 3436 addPostProcessAction(element, checkTypeVariableBound); |
| 3377 element, checkTypeVariableBound); | |
| 3378 } else { | 3437 } else { |
| 3379 variableElement.bound = compiler.objectClass.computeType(compiler); | 3438 variableElement.bound = compiler.objectClass.computeType(compiler); |
| 3380 } | 3439 } |
| 3381 nodeLink = nodeLink.tail; | 3440 nodeLink = nodeLink.tail; |
| 3382 typeLink = typeLink.tail; | 3441 typeLink = typeLink.tail; |
| 3383 } | 3442 } |
| 3384 assert(typeLink.isEmpty); | 3443 assert(typeLink.isEmpty); |
| 3385 } | 3444 } |
| 3386 } | 3445 } |
| 3387 | 3446 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3407 signature.forEachParameter((Element element) { | 3466 signature.forEachParameter((Element element) { |
| 3408 defineElement(element.parseNode(compiler), element); | 3467 defineElement(element.parseNode(compiler), element); |
| 3409 }); | 3468 }); |
| 3410 | 3469 |
| 3411 element.alias = compiler.computeFunctionType(element, signature); | 3470 element.alias = compiler.computeFunctionType(element, signature); |
| 3412 | 3471 |
| 3413 void checkCyclicReference() { | 3472 void checkCyclicReference() { |
| 3414 var visitor = new TypedefCyclicVisitor(compiler, element); | 3473 var visitor = new TypedefCyclicVisitor(compiler, element); |
| 3415 type.accept(visitor, null); | 3474 type.accept(visitor, null); |
| 3416 } | 3475 } |
| 3417 compiler.enqueuer.resolution.addPostProcessAction(element, | 3476 addPostProcessAction(element, checkCyclicReference); |
| 3418 checkCyclicReference); | |
| 3419 } | 3477 } |
| 3420 } | 3478 } |
| 3421 | 3479 |
| 3422 // TODO(johnniwinther): Replace with a traversal on the AST when the type | 3480 // TODO(johnniwinther): Replace with a traversal on the AST when the type |
| 3423 // annotations in typedef alias are stored in a [TreeElements] mapping. | 3481 // annotations in typedef alias are stored in a [TreeElements] mapping. |
| 3424 class TypedefCyclicVisitor extends DartTypeVisitor { | 3482 class TypedefCyclicVisitor extends DartTypeVisitor { |
| 3425 final Compiler compiler; | 3483 final Compiler compiler; |
| 3426 final TypedefElement element; | 3484 final TypedefElement element; |
| 3427 bool hasCyclicReference = false; | 3485 bool hasCyclicReference = false; |
| 3428 | 3486 |
| (...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4420 return e; | 4478 return e; |
| 4421 } | 4479 } |
| 4422 | 4480 |
| 4423 /// Assumed to be called by [resolveRedirectingFactory]. | 4481 /// Assumed to be called by [resolveRedirectingFactory]. |
| 4424 Element visitReturn(Return node) { | 4482 Element visitReturn(Return node) { |
| 4425 Node expression = node.expression; | 4483 Node expression = node.expression; |
| 4426 return finishConstructorReference(visit(expression), | 4484 return finishConstructorReference(visit(expression), |
| 4427 expression, expression); | 4485 expression, expression); |
| 4428 } | 4486 } |
| 4429 } | 4487 } |
| OLD | NEW |