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

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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698