Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(382)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 24282005: Move compile-time constant registrations to the backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update status Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698