Chromium Code Reviews| 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 | |
| 154 | |
|
ahe
2013/09/30 11:05:26
Extra line.
Johnni Winther
2013/10/01 11:21:48
Done.
| |
| 143 bool isTypeLiteral(Send node) { | 155 bool isTypeLiteral(Send node) { |
| 144 return getType(node) != null; | 156 return getType(node) != null; |
| 145 } | 157 } |
| 146 | 158 |
| 147 void registerDependency(Element element) { | 159 void registerDependency(Element element) { |
| 148 otherDependencies.add(element.implementation); | 160 otherDependencies.add(element.implementation); |
| 149 } | 161 } |
| 150 | 162 |
| 151 String toString() => 'TreeElementMapping($currentElement)'; | 163 String toString() => 'TreeElementMapping($currentElement)'; |
| 152 } | 164 } |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 } | 353 } |
| 342 | 354 |
| 343 TreeElements resolveMethodElement(FunctionElement element) { | 355 TreeElements resolveMethodElement(FunctionElement element) { |
| 344 assert(invariant(element, element.isDeclaration)); | 356 assert(invariant(element, element.isDeclaration)); |
| 345 return compiler.withCurrentElement(element, () { | 357 return compiler.withCurrentElement(element, () { |
| 346 bool isConstructor = | 358 bool isConstructor = |
| 347 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR); | 359 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR); |
| 348 TreeElements elements = | 360 TreeElements elements = |
| 349 compiler.enqueuer.resolution.getCachedElements(element); | 361 compiler.enqueuer.resolution.getCachedElements(element); |
| 350 if (elements != null) { | 362 if (elements != null) { |
| 351 assert(isConstructor); | 363 // TODO(karlklose): This should never happen, not even for constructors. |
|
ngeoffray
2013/10/01 08:33:35
Please add: TODO(...): remove this check. elements
Johnni Winther
2013/10/01 11:21:48
Done.
| |
| 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) { | |
|
ngeoffray
2013/10/01 08:33:35
What's this redirecting factory check? Please add
Johnni Winther
2013/10/01 11:21:48
Added comment: We need to analyze the redirecting
| |
| 422 visitor.visit(tree.body); | |
| 423 } | |
| 406 | 424 |
| 407 // Get the resolution tree and check that the resolved | 425 // Get the resolution tree and check that the resolved |
| 408 // function doesn't use 'super' if it is mixed into another | 426 // function doesn't use 'super' if it is mixed into another |
| 409 // class. This is the part of the 'super' mixin check that | 427 // class. This is the part of the 'super' mixin check that |
| 410 // happens when a function is resolved after the mixin | 428 // happens when a function is resolved after the mixin |
| 411 // application has been performed. | 429 // application has been performed. |
| 412 TreeElements resolutionTree = visitor.mapping; | 430 TreeElements resolutionTree = visitor.mapping; |
| 413 ClassElement enclosingClass = element.getEnclosingClass(); | 431 ClassElement enclosingClass = element.getEnclosingClass(); |
| 414 if (enclosingClass != null) { | 432 if (enclosingClass != null) { |
| 415 Set<MixinApplicationElement> mixinUses = | 433 Set<MixinApplicationElement> mixinUses = |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 451 SendSet send = tree.asSendSet(); | 469 SendSet send = tree.asSendSet(); |
| 452 if (send != null) { | 470 if (send != null) { |
| 453 // TODO(johnniwinther): Avoid analyzing initializers if | 471 // TODO(johnniwinther): Avoid analyzing initializers if |
| 454 // [Compiler.analyzeSignaturesOnly] is set. | 472 // [Compiler.analyzeSignaturesOnly] is set. |
| 455 visitor.visit(send.arguments.head); | 473 visitor.visit(send.arguments.head); |
| 456 } else if (element.modifiers.isConst()) { | 474 } else if (element.modifiers.isConst()) { |
| 457 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER); | 475 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER); |
| 458 } | 476 } |
| 459 | 477 |
| 460 if (Elements.isStaticOrTopLevelField(element)) { | 478 if (Elements.isStaticOrTopLevelField(element)) { |
| 479 visitor.addPostProcessAction(element, () { | |
| 480 compiler.constantHandler.compileVariable( | |
| 481 element, isConst: element.modifiers.isConst()); | |
| 482 }); | |
| 461 if (tree.asSendSet() != null) { | 483 if (tree.asSendSet() != null) { |
| 462 // TODO(13429): We could do better here by using the | 484 if (!element.modifiers.isConst()) { |
|
ngeoffray
2013/10/01 08:33:35
Note that this is not fixing it: what we want to k
Johnni Winther
2013/10/01 11:21:48
Added a TODO.
| |
| 463 // constant handler to figure out if it's a lazy field or not. | 485 compiler.backend.registerLazyField(visitor.mapping); |
| 464 compiler.backend.registerLazyField(visitor.mapping); | 486 } |
| 465 } else { | 487 } else { |
| 466 compiler.enqueuer.resolution.registerInstantiatedClass( | 488 compiler.enqueuer.resolution.registerInstantiatedClass( |
| 467 compiler.nullClass, visitor.mapping); | 489 compiler.nullClass, visitor.mapping); |
| 468 } | 490 } |
| 469 } | 491 } |
| 470 | 492 |
| 471 // Perform various checks as side effect of "computing" the type. | 493 // Perform various checks as side effect of "computing" the type. |
| 472 element.computeType(compiler); | 494 element.computeType(compiler); |
| 473 | 495 |
| 474 return visitor.mapping; | 496 return visitor.mapping; |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1036 annotation.resolutionState = STATE_STARTED; | 1058 annotation.resolutionState = STATE_STARTED; |
| 1037 | 1059 |
| 1038 Node node = annotation.parseNode(compiler); | 1060 Node node = annotation.parseNode(compiler); |
| 1039 Element annotatedElement = annotation.annotatedElement; | 1061 Element annotatedElement = annotation.annotatedElement; |
| 1040 Element context = annotatedElement.enclosingElement; | 1062 Element context = annotatedElement.enclosingElement; |
| 1041 if (context == null) { | 1063 if (context == null) { |
| 1042 context = annotatedElement; | 1064 context = annotatedElement; |
| 1043 } | 1065 } |
| 1044 ResolverVisitor visitor = visitorFor(context); | 1066 ResolverVisitor visitor = visitorFor(context); |
| 1045 node.accept(visitor); | 1067 node.accept(visitor); |
| 1046 annotation.value = compiler.metadataHandler.compileNodeWithDefinitions( | 1068 annotation.value = compiler.constantHandler.compileNodeWithDefinitions( |
| 1047 node, visitor.mapping, isConst: true); | 1069 node, visitor.mapping, isConst: true); |
| 1070 compiler.backend.registerMetadataConstant(annotation.value, | |
| 1071 visitor.mapping); | |
| 1048 | 1072 |
| 1049 annotation.resolutionState = STATE_DONE; | 1073 annotation.resolutionState = STATE_DONE; |
| 1050 })); | 1074 })); |
| 1051 } | 1075 } |
| 1052 | 1076 |
| 1053 error(Node node, MessageKind kind, [arguments = const {}]) { | 1077 error(Node node, MessageKind kind, [arguments = const {}]) { |
| 1054 // TODO(ahe): Make non-fatal. | 1078 // TODO(ahe): Make non-fatal. |
| 1055 compiler.reportFatalError(node, kind, arguments); | 1079 compiler.reportFatalError(node, kind, arguments); |
| 1056 } | 1080 } |
| 1057 } | 1081 } |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1388 compiler.cancel(message, node: node); | 1412 compiler.cancel(message, node: node); |
| 1389 } | 1413 } |
| 1390 | 1414 |
| 1391 void internalError(Node node, String message) { | 1415 void internalError(Node node, String message) { |
| 1392 compiler.internalError(message, node: node); | 1416 compiler.internalError(message, node: node); |
| 1393 } | 1417 } |
| 1394 | 1418 |
| 1395 void unimplemented(Node node, String message) { | 1419 void unimplemented(Node node, String message) { |
| 1396 compiler.unimplemented(message, node: node); | 1420 compiler.unimplemented(message, node: node); |
| 1397 } | 1421 } |
| 1422 | |
| 1423 void addPostProcessAction(Element element, PostProcessAction action) { | |
| 1424 compiler.enqueuer.resolution.addPostProcessAction(element, action); | |
| 1425 } | |
| 1398 } | 1426 } |
| 1399 | 1427 |
| 1400 abstract class LabelScope { | 1428 abstract class LabelScope { |
| 1401 LabelScope get outer; | 1429 LabelScope get outer; |
| 1402 LabelElement lookup(String label); | 1430 LabelElement lookup(String label); |
| 1403 } | 1431 } |
| 1404 | 1432 |
| 1405 class LabeledStatementLabelScope implements LabelScope { | 1433 class LabeledStatementLabelScope implements LabelScope { |
| 1406 final LabelScope outer; | 1434 final LabelScope outer; |
| 1407 final Map<String, LabelElement> labels; | 1435 final Map<String, LabelElement> labels; |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1650 type = checkNoTypeArguments(type); | 1678 type = checkNoTypeArguments(type); |
| 1651 } else { | 1679 } else { |
| 1652 compiler.cancel("unexpected element kind ${element.kind}", | 1680 compiler.cancel("unexpected element kind ${element.kind}", |
| 1653 node: node); | 1681 node: node); |
| 1654 } | 1682 } |
| 1655 // TODO(johnniwinther): We should not resolve type annotations after the | 1683 // TODO(johnniwinther): We should not resolve type annotations after the |
| 1656 // resolution queue has been closed. Currently the dart backend does so. | 1684 // resolution queue has been closed. Currently the dart backend does so. |
| 1657 // Remove the guarded when this is fixed. | 1685 // Remove the guarded when this is fixed. |
| 1658 if (!compiler.enqueuer.resolution.queueIsClosed && | 1686 if (!compiler.enqueuer.resolution.queueIsClosed && |
| 1659 addTypeVariableBoundsCheck) { | 1687 addTypeVariableBoundsCheck) { |
| 1660 compiler.enqueuer.resolution.addPostProcessAction( | 1688 visitor.addPostProcessAction( |
| 1661 visitor.enclosingElement, | 1689 visitor.enclosingElement, |
| 1662 () => checkTypeVariableBounds(node, type)); | 1690 () => checkTypeVariableBounds(node, type)); |
| 1663 } | 1691 } |
| 1664 } | 1692 } |
| 1665 visitor.useType(node, type); | 1693 visitor.useType(node, type); |
| 1666 return type; | 1694 return type; |
| 1667 } | 1695 } |
| 1668 | 1696 |
| 1669 /// Checks the type arguments of [type] against the type variable bounds. | 1697 /// Checks the type arguments of [type] against the type variable bounds. |
| 1670 void checkTypeVariableBounds(TypeAnnotation node, GenericType type) { | 1698 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)); | 2054 initializerDo(parameterNode, (n) => n.accept(this)); |
| 2027 // Field parameters (this.x) are not visible inside the constructor. The | 2055 // Field parameters (this.x) are not visible inside the constructor. The |
| 2028 // fields they reference are visible, but must be resolved independently. | 2056 // fields they reference are visible, but must be resolved independently. |
| 2029 if (element.kind == ElementKind.FIELD_PARAMETER) { | 2057 if (element.kind == ElementKind.FIELD_PARAMETER) { |
| 2030 useElement(parameterNode, element); | 2058 useElement(parameterNode, element); |
| 2031 } else { | 2059 } else { |
| 2032 defineElement(variableDefinitions.definitions.nodes.head, element); | 2060 defineElement(variableDefinitions.definitions.nodes.head, element); |
| 2033 } | 2061 } |
| 2034 parameterNodes = parameterNodes.tail; | 2062 parameterNodes = parameterNodes.tail; |
| 2035 }); | 2063 }); |
| 2064 addPostProcessAction(enclosingElement, () { | |
| 2065 functionParameters.forEachOptionalParameter((Element parameter) { | |
| 2066 compiler.constantHandler.compileConstant(parameter); | |
| 2067 }); | |
| 2068 }); | |
| 2036 if (inCheckContext) { | 2069 if (inCheckContext) { |
| 2037 functionParameters.forEachParameter((Element element) { | 2070 functionParameters.forEachParameter((Element element) { |
| 2038 compiler.enqueuer.resolution.registerIsCheck( | 2071 compiler.enqueuer.resolution.registerIsCheck( |
| 2039 element.computeType(compiler), mapping); | 2072 element.computeType(compiler), mapping); |
| 2040 }); | 2073 }); |
| 2041 } | 2074 } |
| 2042 } | 2075 } |
| 2043 | 2076 |
| 2044 visitCascade(Cascade node) { | 2077 visitCascade(Cascade node) { |
| 2045 visit(node.expression); | 2078 visit(node.expression); |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2394 compiler.backend.registerTypeVariableExpression(mapping); | 2427 compiler.backend.registerTypeVariableExpression(mapping); |
| 2395 // Set the type of the node to [Type] to mark this send as a | 2428 // Set the type of the node to [Type] to mark this send as a |
| 2396 // type variable expression. | 2429 // type variable expression. |
| 2397 mapping.setType(node, compiler.typeClass.computeType(compiler)); | 2430 mapping.setType(node, compiler.typeClass.computeType(compiler)); |
| 2398 world.registerTypeLiteral(target, mapping); | 2431 world.registerTypeLiteral(target, mapping); |
| 2399 } else if (target.impliesType() && !sendIsMemberAccess) { | 2432 } else if (target.impliesType() && !sendIsMemberAccess) { |
| 2400 // Set the type of the node to [Type] to mark this send as a | 2433 // Set the type of the node to [Type] to mark this send as a |
| 2401 // type literal. | 2434 // type literal. |
| 2402 mapping.setType(node, compiler.typeClass.computeType(compiler)); | 2435 mapping.setType(node, compiler.typeClass.computeType(compiler)); |
| 2403 world.registerTypeLiteral(target, mapping); | 2436 world.registerTypeLiteral(target, mapping); |
| 2437 analyzeConstant(node); | |
| 2404 } | 2438 } |
| 2405 } | 2439 } |
| 2406 | 2440 |
| 2407 bool resolvedArguments = false; | 2441 bool resolvedArguments = false; |
| 2408 if (node.isOperator) { | 2442 if (node.isOperator) { |
| 2409 String operatorString = node.selector.asOperator().source.stringValue; | 2443 String operatorString = node.selector.asOperator().source.stringValue; |
| 2410 if (identical(operatorString, 'is')) { | 2444 if (identical(operatorString, 'is')) { |
| 2411 DartType type = | 2445 DartType type = |
| 2412 resolveTypeExpression(node.typeAnnotationFromIsCheckOrCast); | 2446 resolveTypeExpression(node.typeAnnotationFromIsCheckOrCast); |
| 2413 if (type != null) { | 2447 if (type != null) { |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2617 } | 2651 } |
| 2618 | 2652 |
| 2619 visitLiteralSymbol(LiteralSymbol node) { | 2653 visitLiteralSymbol(LiteralSymbol node) { |
| 2620 world.registerInstantiatedClass(compiler.symbolClass, mapping); | 2654 world.registerInstantiatedClass(compiler.symbolClass, mapping); |
| 2621 world.registerStaticUse(compiler.symbolConstructor.declaration); | 2655 world.registerStaticUse(compiler.symbolConstructor.declaration); |
| 2622 world.registerConstSymbol(node.slowNameString, mapping); | 2656 world.registerConstSymbol(node.slowNameString, mapping); |
| 2623 if (!validateSymbol(node, node.slowNameString, reportError: false)) { | 2657 if (!validateSymbol(node, node.slowNameString, reportError: false)) { |
| 2624 compiler.reportError(node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL, | 2658 compiler.reportError(node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL, |
| 2625 {'value': node.slowNameString}); | 2659 {'value': node.slowNameString}); |
| 2626 } | 2660 } |
| 2661 analyzeConstant(node); | |
| 2627 } | 2662 } |
| 2628 | 2663 |
| 2629 visitStringJuxtaposition(StringJuxtaposition node) { | 2664 visitStringJuxtaposition(StringJuxtaposition node) { |
| 2630 world.registerInstantiatedClass(compiler.stringClass, mapping); | 2665 world.registerInstantiatedClass(compiler.stringClass, mapping); |
| 2631 node.visitChildren(this); | 2666 node.visitChildren(this); |
| 2632 } | 2667 } |
| 2633 | 2668 |
| 2634 visitNodeList(NodeList node) { | 2669 visitNodeList(NodeList node) { |
| 2635 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 2670 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 2636 visit(link.head); | 2671 visit(link.head); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2702 redirectionTarget.computeSignature(compiler); | 2737 redirectionTarget.computeSignature(compiler); |
| 2703 FunctionSignature constructorSignature = | 2738 FunctionSignature constructorSignature = |
| 2704 constructor.computeSignature(compiler); | 2739 constructor.computeSignature(compiler); |
| 2705 if (!targetSignature.isCompatibleWith(constructorSignature)) { | 2740 if (!targetSignature.isCompatibleWith(constructorSignature)) { |
| 2706 assert(!isSubtype); | 2741 assert(!isSubtype); |
| 2707 compiler.backend.registerThrowNoSuchMethod(mapping); | 2742 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2708 } | 2743 } |
| 2709 | 2744 |
| 2710 // Register a post process to check for cycles in the redirection chain and | 2745 // 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. | 2746 // set the actual generative constructor at the end of the chain. |
| 2712 compiler.enqueuer.resolution.addPostProcessAction(constructor, () { | 2747 addPostProcessAction(constructor, () { |
| 2713 compiler.resolver.resolveRedirectionChain(constructor, node); | 2748 compiler.resolver.resolveRedirectionChain(constructor, node); |
| 2714 }); | 2749 }); |
| 2715 | 2750 |
| 2716 world.registerStaticUse(redirectionTarget); | 2751 world.registerStaticUse(redirectionTarget); |
| 2717 world.registerInstantiatedClass( | 2752 world.registerInstantiatedClass( |
| 2718 redirectionTarget.enclosingElement.declaration, mapping); | 2753 redirectionTarget.enclosingElement.declaration, mapping); |
| 2719 if (isSymbolConstructor) { | 2754 if (isSymbolConstructor) { |
| 2720 compiler.backend.registerSymbolConstructor(mapping); | 2755 compiler.backend.registerSymbolConstructor(mapping); |
| 2721 } | 2756 } |
| 2722 } | 2757 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2805 world.registerFactoryWithTypeArguments(mapping); | 2840 world.registerFactoryWithTypeArguments(mapping); |
| 2806 } | 2841 } |
| 2807 if (constructor.isGenerativeConstructor() && cls.isAbstract(compiler)) { | 2842 if (constructor.isGenerativeConstructor() && cls.isAbstract(compiler)) { |
| 2808 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); | 2843 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); |
| 2809 compiler.backend.registerAbstractClassInstantiation(mapping); | 2844 compiler.backend.registerAbstractClassInstantiation(mapping); |
| 2810 } | 2845 } |
| 2811 | 2846 |
| 2812 if (isSymbolConstructor) { | 2847 if (isSymbolConstructor) { |
| 2813 if (node.isConst()) { | 2848 if (node.isConst()) { |
| 2814 Node argumentNode = node.send.arguments.head; | 2849 Node argumentNode = node.send.arguments.head; |
| 2815 Constant name = compiler.metadataHandler.compileNodeWithDefinitions( | 2850 Constant name = compiler.constantHandler.compileNodeWithDefinitions( |
| 2816 argumentNode, mapping, isConst: true); | 2851 argumentNode, mapping, isConst: true); |
| 2817 if (!name.isString()) { | 2852 if (!name.isString()) { |
| 2818 DartType type = name.computeType(compiler); | 2853 DartType type = name.computeType(compiler); |
| 2819 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, | 2854 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, |
| 2820 {'type': type}); | 2855 {'type': type}); |
| 2821 } else { | 2856 } else { |
| 2822 StringConstant stringConstant = name; | 2857 StringConstant stringConstant = name; |
| 2823 String nameString = stringConstant.toDartString().slowToString(); | 2858 String nameString = stringConstant.toDartString().slowToString(); |
| 2824 if (validateSymbol(argumentNode, nameString)) { | 2859 if (validateSymbol(argumentNode, nameString)) { |
| 2825 world.registerConstSymbol(nameString, mapping); | 2860 world.registerConstSymbol(nameString, mapping); |
| 2826 } | 2861 } |
| 2827 } | 2862 } |
| 2828 } else { | 2863 } else { |
| 2829 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( | 2864 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( |
| 2830 enclosingElement)) { | 2865 enclosingElement)) { |
| 2831 compiler.reportHint( | 2866 compiler.reportHint( |
| 2832 node.newToken, MessageKind.NON_CONST_BLOAT, | 2867 node.newToken, MessageKind.NON_CONST_BLOAT, |
| 2833 {'name': compiler.symbolClass.name}); | 2868 {'name': compiler.symbolClass.name}); |
| 2834 } | 2869 } |
| 2835 world.registerNewSymbol(mapping); | 2870 world.registerNewSymbol(mapping); |
| 2836 } | 2871 } |
| 2837 } else if (isMirrorsUsedConstant) { | 2872 } else if (isMirrorsUsedConstant) { |
| 2838 compiler.mirrorUsageAnalyzerTask.validate(node, mapping); | 2873 compiler.mirrorUsageAnalyzerTask.validate(node, mapping); |
| 2839 } | 2874 } |
| 2875 if (node.isConst()) { | |
| 2876 analyzeConstant(node); | |
| 2877 } | |
| 2840 | 2878 |
| 2841 return null; | 2879 return null; |
| 2842 } | 2880 } |
| 2843 | 2881 |
| 2882 void analyzeConstant(Node node) { | |
| 2883 addPostProcessAction(enclosingElement, () { | |
| 2884 mapping.setConstant(node, | |
| 2885 compiler.constantHandler.compileNodeWithDefinitions( | |
| 2886 node, mapping, isConst: true)); | |
| 2887 }); | |
| 2888 } | |
| 2889 | |
| 2844 bool validateSymbol(Node node, String name, {bool reportError: true}) { | 2890 bool validateSymbol(Node node, String name, {bool reportError: true}) { |
| 2845 if (name.isEmpty) return true; | 2891 if (name.isEmpty) return true; |
| 2846 if (name.startsWith('_')) { | 2892 if (name.startsWith('_')) { |
| 2847 if (reportError) { | 2893 if (reportError) { |
| 2848 compiler.reportError(node, MessageKind.PRIVATE_IDENTIFIER, | 2894 compiler.reportError(node, MessageKind.PRIVATE_IDENTIFIER, |
| 2849 {'value': name}); | 2895 {'value': name}); |
| 2850 } | 2896 } |
| 2851 return false; | 2897 return false; |
| 2852 } | 2898 } |
| 2853 if (!symbolValidationPattern.hasMatch(name)) { | 2899 if (!symbolValidationPattern.hasMatch(name)) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2917 listType = new InterfaceType(compiler.listClass, | 2963 listType = new InterfaceType(compiler.listClass, |
| 2918 new Link<DartType>.fromList([typeArgument])); | 2964 new Link<DartType>.fromList([typeArgument])); |
| 2919 } else { | 2965 } else { |
| 2920 compiler.listClass.computeType(compiler); | 2966 compiler.listClass.computeType(compiler); |
| 2921 listType = compiler.listClass.rawType; | 2967 listType = compiler.listClass.rawType; |
| 2922 } | 2968 } |
| 2923 mapping.setType(node, listType); | 2969 mapping.setType(node, listType); |
| 2924 world.registerInstantiatedType(listType, mapping); | 2970 world.registerInstantiatedType(listType, mapping); |
| 2925 compiler.backend.registerRequiredType(listType, enclosingElement); | 2971 compiler.backend.registerRequiredType(listType, enclosingElement); |
| 2926 visit(node.elements); | 2972 visit(node.elements); |
| 2973 if (node.isConst()) { | |
| 2974 analyzeConstant(node); | |
| 2975 } | |
| 2927 } | 2976 } |
| 2928 | 2977 |
| 2929 visitConditional(Conditional node) { | 2978 visitConditional(Conditional node) { |
| 2930 node.visitChildren(this); | 2979 node.visitChildren(this); |
| 2931 } | 2980 } |
| 2932 | 2981 |
| 2933 visitStringInterpolation(StringInterpolation node) { | 2982 visitStringInterpolation(StringInterpolation node) { |
| 2934 world.registerInstantiatedClass(compiler.stringClass, mapping); | 2983 world.registerInstantiatedClass(compiler.stringClass, mapping); |
| 2935 compiler.backend.registerStringInterpolation(mapping); | 2984 compiler.backend.registerStringInterpolation(mapping); |
| 2936 node.visitChildren(this); | 2985 node.visitChildren(this); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3132 compiler.reportError(arguments, | 3181 compiler.reportError(arguments, |
| 3133 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 3182 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 3134 } | 3183 } |
| 3135 mapping.setType(node, mapType); | 3184 mapping.setType(node, mapType); |
| 3136 world.registerInstantiatedClass(compiler.mapClass, mapping); | 3185 world.registerInstantiatedClass(compiler.mapClass, mapping); |
| 3137 if (node.isConst()) { | 3186 if (node.isConst()) { |
| 3138 compiler.backend.registerConstantMap(mapping); | 3187 compiler.backend.registerConstantMap(mapping); |
| 3139 } | 3188 } |
| 3140 compiler.backend.registerRequiredType(mapType, enclosingElement); | 3189 compiler.backend.registerRequiredType(mapType, enclosingElement); |
| 3141 node.visitChildren(this); | 3190 node.visitChildren(this); |
| 3191 if (node.isConst()) { | |
| 3192 analyzeConstant(node); | |
| 3193 } | |
| 3142 } | 3194 } |
| 3143 | 3195 |
| 3144 visitLiteralMapEntry(LiteralMapEntry node) { | 3196 visitLiteralMapEntry(LiteralMapEntry node) { |
| 3145 node.visitChildren(this); | 3197 node.visitChildren(this); |
| 3146 } | 3198 } |
| 3147 | 3199 |
| 3148 visitNamedArgument(NamedArgument node) { | 3200 visitNamedArgument(NamedArgument node) { |
| 3149 visit(node.expression); | 3201 visit(node.expression); |
| 3150 } | 3202 } |
| 3151 | 3203 |
| 3152 visitSwitchStatement(SwitchStatement node) { | 3204 visitSwitchStatement(SwitchStatement node) { |
| 3153 node.expression.accept(this); | 3205 node.expression.accept(this); |
| 3154 | 3206 |
| 3155 TargetElement breakElement = getOrCreateTargetElement(node); | 3207 TargetElement breakElement = getOrCreateTargetElement(node); |
| 3156 Map<String, LabelElement> continueLabels = <String, LabelElement>{}; | 3208 Map<String, LabelElement> continueLabels = <String, LabelElement>{}; |
| 3157 Link<Node> cases = node.cases.nodes; | 3209 Link<Node> cases = node.cases.nodes; |
| 3158 while (!cases.isEmpty) { | 3210 while (!cases.isEmpty) { |
| 3159 SwitchCase switchCase = cases.head; | 3211 SwitchCase switchCase = cases.head; |
| 3160 for (Node labelOrCase in switchCase.labelsAndCases) { | 3212 for (Node labelOrCase in switchCase.labelsAndCases) { |
| 3161 if (labelOrCase is! Label) continue; | 3213 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
| 3214 if (caseMatch != null) { | |
| 3215 analyzeConstant(caseMatch.expression); | |
| 3216 continue; | |
| 3217 } | |
| 3162 Label label = labelOrCase; | 3218 Label label = labelOrCase; |
| 3163 String labelName = label.slowToString(); | 3219 String labelName = label.slowToString(); |
| 3164 | 3220 |
| 3165 LabelElement existingElement = continueLabels[labelName]; | 3221 LabelElement existingElement = continueLabels[labelName]; |
| 3166 if (existingElement != null) { | 3222 if (existingElement != null) { |
| 3167 // It's an error if the same label occurs twice in the same switch. | 3223 // It's an error if the same label occurs twice in the same switch. |
| 3168 compiler.reportError( | 3224 compiler.reportError( |
| 3169 label, | 3225 label, |
| 3170 MessageKind.DUPLICATE_LABEL.error, {'labelName': labelName}); | 3226 MessageKind.DUPLICATE_LABEL.error, {'labelName': labelName}); |
| 3171 compiler.reportInfo( | 3227 compiler.reportInfo( |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3357 // generating multiple errors for the same cyclicity. | 3413 // generating multiple errors for the same cyclicity. |
| 3358 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, | 3414 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, |
| 3359 {'typeVariableName': variableElement.name}); | 3415 {'typeVariableName': variableElement.name}); |
| 3360 } | 3416 } |
| 3361 break; | 3417 break; |
| 3362 } | 3418 } |
| 3363 seenTypeVariables = seenTypeVariables.prepend(element); | 3419 seenTypeVariables = seenTypeVariables.prepend(element); |
| 3364 bound = element.bound; | 3420 bound = element.bound; |
| 3365 } | 3421 } |
| 3366 } | 3422 } |
| 3367 compiler.enqueuer.resolution.addPostProcessAction( | 3423 addPostProcessAction(element, checkTypeVariableBound); |
| 3368 element, checkTypeVariableBound); | |
| 3369 } else { | 3424 } else { |
| 3370 variableElement.bound = compiler.objectClass.computeType(compiler); | 3425 variableElement.bound = compiler.objectClass.computeType(compiler); |
| 3371 } | 3426 } |
| 3372 nodeLink = nodeLink.tail; | 3427 nodeLink = nodeLink.tail; |
| 3373 typeLink = typeLink.tail; | 3428 typeLink = typeLink.tail; |
| 3374 } | 3429 } |
| 3375 assert(typeLink.isEmpty); | 3430 assert(typeLink.isEmpty); |
| 3376 } | 3431 } |
| 3377 } | 3432 } |
| 3378 | 3433 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 3398 signature.forEachParameter((Element element) { | 3453 signature.forEachParameter((Element element) { |
| 3399 defineElement(element.parseNode(compiler), element); | 3454 defineElement(element.parseNode(compiler), element); |
| 3400 }); | 3455 }); |
| 3401 | 3456 |
| 3402 element.alias = compiler.computeFunctionType(element, signature); | 3457 element.alias = compiler.computeFunctionType(element, signature); |
| 3403 | 3458 |
| 3404 void checkCyclicReference() { | 3459 void checkCyclicReference() { |
| 3405 var visitor = new TypedefCyclicVisitor(compiler, element); | 3460 var visitor = new TypedefCyclicVisitor(compiler, element); |
| 3406 type.accept(visitor, null); | 3461 type.accept(visitor, null); |
| 3407 } | 3462 } |
| 3408 compiler.enqueuer.resolution.addPostProcessAction(element, | 3463 addPostProcessAction(element, checkCyclicReference); |
| 3409 checkCyclicReference); | |
| 3410 } | 3464 } |
| 3411 } | 3465 } |
| 3412 | 3466 |
| 3413 // TODO(johnniwinther): Replace with a traversal on the AST when the type | 3467 // TODO(johnniwinther): Replace with a traversal on the AST when the type |
| 3414 // annotations in typedef alias are stored in a [TreeElements] mapping. | 3468 // annotations in typedef alias are stored in a [TreeElements] mapping. |
| 3415 class TypedefCyclicVisitor extends DartTypeVisitor { | 3469 class TypedefCyclicVisitor extends DartTypeVisitor { |
| 3416 final Compiler compiler; | 3470 final Compiler compiler; |
| 3417 final TypedefElement element; | 3471 final TypedefElement element; |
| 3418 bool hasCyclicReference = false; | 3472 bool hasCyclicReference = false; |
| 3419 | 3473 |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4395 return e; | 4449 return e; |
| 4396 } | 4450 } |
| 4397 | 4451 |
| 4398 /// Assumed to be called by [resolveRedirectingFactory]. | 4452 /// Assumed to be called by [resolveRedirectingFactory]. |
| 4399 Element visitReturn(Return node) { | 4453 Element visitReturn(Return node) { |
| 4400 Node expression = node.expression; | 4454 Node expression = node.expression; |
| 4401 return finishConstructorReference(visit(expression), | 4455 return finishConstructorReference(visit(expression), |
| 4402 expression, expression); | 4456 expression, expression); |
| 4403 } | 4457 } |
| 4404 } | 4458 } |
| OLD | NEW |