| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dart2js.semantics_visitor.resolver; | 5 library dart2js.semantics_visitor.resolver; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../constants/expressions.dart'; | 8 import '../constants/expressions.dart'; |
| 9 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
| 10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| 11 import '../tree/tree.dart'; | 11 import '../tree/tree.dart'; |
| 12 import '../universe/call_structure.dart' show | |
| 13 CallStructure; | |
| 14 import '../universe/selector.dart' show | |
| 15 Selector; | |
| 16 | 12 |
| 17 import 'access_semantics.dart'; | |
| 18 import 'semantic_visitor.dart'; | 13 import 'semantic_visitor.dart'; |
| 19 import 'send_structure.dart'; | 14 import 'send_structure.dart'; |
| 20 import 'tree_elements.dart'; | 15 import 'tree_elements.dart'; |
| 21 | 16 |
| 22 abstract class SendResolverMixin { | |
| 23 TreeElements get elements; | |
| 24 | |
| 25 internalError(Spannable spannable, String message); | |
| 26 | |
| 27 ConstructorAccessSemantics computeConstructorAccessSemantics( | |
| 28 ConstructorElement constructor, | |
| 29 CallStructure callStructure, | |
| 30 DartType type, | |
| 31 {bool mustBeConstant: false}) { | |
| 32 if (mustBeConstant && !constructor.isConst) { | |
| 33 return new ConstructorAccessSemantics( | |
| 34 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, constructor, type); | |
| 35 } | |
| 36 if (constructor.isMalformed) { | |
| 37 if (constructor is ErroneousElement) { | |
| 38 ErroneousElement error = constructor; | |
| 39 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR || | |
| 40 error.messageKind == MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR) { | |
| 41 return new ConstructorAccessSemantics( | |
| 42 ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, constructor, type); | |
| 43 } | |
| 44 } | |
| 45 return new ConstructorAccessSemantics( | |
| 46 ConstructorAccessKind.UNRESOLVED_TYPE, constructor, type); | |
| 47 } else if (constructor.isRedirectingFactory) { | |
| 48 ConstructorElement effectiveTarget = constructor.effectiveTarget; | |
| 49 if (effectiveTarget == constructor || | |
| 50 effectiveTarget.isMalformed || | |
| 51 (mustBeConstant && !effectiveTarget.isConst)) { | |
| 52 return new ConstructorAccessSemantics( | |
| 53 ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY, | |
| 54 constructor, | |
| 55 type); | |
| 56 } | |
| 57 ConstructorAccessSemantics effectiveTargetSemantics = | |
| 58 computeConstructorAccessSemantics( | |
| 59 effectiveTarget, | |
| 60 callStructure, | |
| 61 constructor.computeEffectiveTargetType(type)); | |
| 62 if (effectiveTargetSemantics.isErroneous) { | |
| 63 return new RedirectingFactoryConstructorAccessSemantics( | |
| 64 ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY, | |
| 65 constructor, | |
| 66 type, | |
| 67 effectiveTargetSemantics); | |
| 68 } | |
| 69 return new RedirectingFactoryConstructorAccessSemantics( | |
| 70 ConstructorAccessKind.REDIRECTING_FACTORY, | |
| 71 constructor, | |
| 72 type, | |
| 73 effectiveTargetSemantics); | |
| 74 } else { | |
| 75 if (!callStructure.signatureApplies(constructor.functionSignature)) { | |
| 76 return new ConstructorAccessSemantics( | |
| 77 ConstructorAccessKind.INCOMPATIBLE, | |
| 78 constructor, | |
| 79 type); | |
| 80 } else if (constructor.isFactoryConstructor) { | |
| 81 return new ConstructorAccessSemantics( | |
| 82 ConstructorAccessKind.FACTORY, constructor, type); | |
| 83 } else if (constructor.isRedirectingGenerative) { | |
| 84 if (constructor.enclosingClass.isAbstract) { | |
| 85 return new ConstructorAccessSemantics( | |
| 86 ConstructorAccessKind.ABSTRACT, constructor, type); | |
| 87 } | |
| 88 return new ConstructorAccessSemantics( | |
| 89 ConstructorAccessKind.REDIRECTING_GENERATIVE, constructor, type); | |
| 90 } else if (constructor.enclosingClass.isAbstract) { | |
| 91 return new ConstructorAccessSemantics( | |
| 92 ConstructorAccessKind.ABSTRACT, constructor, type); | |
| 93 } else { | |
| 94 return new ConstructorAccessSemantics( | |
| 95 ConstructorAccessKind.GENERATIVE, constructor, type); | |
| 96 } | |
| 97 } | |
| 98 } | |
| 99 | |
| 100 NewStructure computeNewStructure(NewExpression node) { | |
| 101 Element element = elements[node.send]; | |
| 102 Selector selector = elements.getSelector(node.send); | |
| 103 DartType type = elements.getType(node); | |
| 104 | |
| 105 ConstructorAccessSemantics constructorAccessSemantics = | |
| 106 computeConstructorAccessSemantics( | |
| 107 element, selector.callStructure, type, | |
| 108 mustBeConstant: node.isConst); | |
| 109 if (node.isConst) { | |
| 110 ConstantExpression constant = elements.getConstant(node); | |
| 111 if (constructorAccessSemantics.isErroneous || | |
| 112 constant == null || | |
| 113 constant.kind == ConstantExpressionKind.ERRONEOUS) { | |
| 114 // This is a non-constant constant constructor invocation, like | |
| 115 // `const Const(method())`. | |
| 116 constructorAccessSemantics = new ConstructorAccessSemantics( | |
| 117 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type); | |
| 118 } else { | |
| 119 ConstantInvokeKind kind; | |
| 120 switch (constant.kind) { | |
| 121 case ConstantExpressionKind.CONSTRUCTED: | |
| 122 kind = ConstantInvokeKind.CONSTRUCTED; | |
| 123 break; | |
| 124 case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT: | |
| 125 kind = ConstantInvokeKind.BOOL_FROM_ENVIRONMENT; | |
| 126 break; | |
| 127 case ConstantExpressionKind.INT_FROM_ENVIRONMENT: | |
| 128 kind = ConstantInvokeKind.INT_FROM_ENVIRONMENT; | |
| 129 break; | |
| 130 case ConstantExpressionKind.STRING_FROM_ENVIRONMENT: | |
| 131 kind = ConstantInvokeKind.STRING_FROM_ENVIRONMENT; | |
| 132 break; | |
| 133 default: | |
| 134 return internalError( | |
| 135 node, "Unexpected constant kind $kind: ${constant.getText()}"); | |
| 136 } | |
| 137 return new ConstInvokeStructure(kind, constant); | |
| 138 } | |
| 139 } | |
| 140 return new NewInvokeStructure(constructorAccessSemantics, selector); | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 abstract class DeclStructure<R, A> { | 17 abstract class DeclStructure<R, A> { |
| 145 final FunctionElement element; | 18 final FunctionElement element; |
| 146 | 19 |
| 147 DeclStructure(this.element); | 20 DeclStructure(this.element); |
| 148 | 21 |
| 149 /// Calls the matching visit method on [visitor] with [node] and [arg]. | 22 /// Calls the matching visit method on [visitor] with [node] and [arg]. |
| 150 R dispatch(SemanticDeclarationVisitor<R, A> visitor, | 23 R dispatch(SemanticDeclarationVisitor<R, A> visitor, |
| 151 FunctionExpression node, | 24 FunctionExpression node, |
| 152 A arg); | 25 A arg); |
| 153 } | 26 } |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 return internalError(node, "Unexpected variable $element."); | 342 return internalError(node, "Unexpected variable $element."); |
| 470 } | 343 } |
| 471 if (element.isConst) { | 344 if (element.isConst) { |
| 472 ConstantExpression constant = elements.getConstant(element.initializer); | 345 ConstantExpression constant = elements.getConstant(element.initializer); |
| 473 return new ConstantVariableStructure(kind, node, element, constant); | 346 return new ConstantVariableStructure(kind, node, element, constant); |
| 474 } else { | 347 } else { |
| 475 return new NonConstantVariableStructure(kind, node, element); | 348 return new NonConstantVariableStructure(kind, node, element); |
| 476 } | 349 } |
| 477 } | 350 } |
| 478 } | 351 } |
| OLD | NEW |