| 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 library dart2js.resolution.members; | 5 library dart2js.resolution.members; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/names.dart' show | 8 import '../common/names.dart' show Selectors; |
| 9 Selectors; | 9 import '../common/resolution.dart' show Feature; |
| 10 import '../common/resolution.dart' show | 10 import '../compiler.dart' show Compiler; |
| 11 Feature; | 11 import '../constants/constructors.dart' |
| 12 import '../compiler.dart' show | 12 show RedirectingFactoryConstantConstructor; |
| 13 Compiler; | |
| 14 import '../constants/constructors.dart' show | |
| 15 RedirectingFactoryConstantConstructor; | |
| 16 import '../constants/expressions.dart'; | 13 import '../constants/expressions.dart'; |
| 17 import '../constants/values.dart'; | 14 import '../constants/values.dart'; |
| 18 import '../core_types.dart'; | 15 import '../core_types.dart'; |
| 19 import '../dart_types.dart'; | 16 import '../dart_types.dart'; |
| 20 import '../elements/elements.dart'; | 17 import '../elements/elements.dart'; |
| 21 import '../elements/modelx.dart' show | 18 import '../elements/modelx.dart' |
| 22 ConstructorElementX, | 19 show |
| 23 ErroneousElementX, | 20 ConstructorElementX, |
| 24 FunctionElementX, | 21 ErroneousElementX, |
| 25 JumpTargetX, | 22 FunctionElementX, |
| 26 LocalFunctionElementX, | 23 JumpTargetX, |
| 27 LocalParameterElementX, | 24 LocalFunctionElementX, |
| 28 LocalVariableElementX, | 25 LocalParameterElementX, |
| 29 MethodElementX, | 26 LocalVariableElementX, |
| 30 ParameterElementX, | 27 MethodElementX, |
| 31 VariableElementX, | 28 ParameterElementX, |
| 32 VariableList; | 29 VariableElementX, |
| 33 import '../tokens/token.dart' show | 30 VariableList; |
| 34 isUserDefinableOperator; | 31 import '../tokens/token.dart' show isUserDefinableOperator; |
| 35 import '../tree/tree.dart'; | 32 import '../tree/tree.dart'; |
| 36 import '../util/util.dart' show | 33 import '../util/util.dart' show Link; |
| 37 Link; | 34 import '../universe/call_structure.dart' show CallStructure; |
| 38 import '../universe/call_structure.dart' show | 35 import '../universe/selector.dart' show Selector; |
| 39 CallStructure; | 36 import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse; |
| 40 import '../universe/selector.dart' show | |
| 41 Selector; | |
| 42 import '../universe/use.dart' show | |
| 43 DynamicUse, | |
| 44 StaticUse, | |
| 45 TypeUse; | |
| 46 | 37 |
| 47 import 'access_semantics.dart'; | 38 import 'access_semantics.dart'; |
| 48 import 'class_members.dart' show MembersCreator; | 39 import 'class_members.dart' show MembersCreator; |
| 49 import 'operators.dart'; | 40 import 'operators.dart'; |
| 50 import 'send_structure.dart'; | 41 import 'send_structure.dart'; |
| 51 | 42 |
| 52 import 'constructors.dart' show | 43 import 'constructors.dart' |
| 53 ConstructorResolver, | 44 show ConstructorResolver, ConstructorResult, ConstructorResultKind; |
| 54 ConstructorResult, | 45 import 'label_scope.dart' show StatementScope; |
| 55 ConstructorResultKind; | 46 import 'registry.dart' show ResolutionRegistry; |
| 56 import 'label_scope.dart' show | 47 import 'resolution.dart' show ResolverTask; |
| 57 StatementScope; | 48 import 'resolution_common.dart' show MappingVisitor; |
| 58 import 'registry.dart' show | |
| 59 ResolutionRegistry; | |
| 60 import 'resolution.dart' show | |
| 61 ResolverTask; | |
| 62 import 'resolution_common.dart' show | |
| 63 MappingVisitor; | |
| 64 import 'resolution_result.dart'; | 49 import 'resolution_result.dart'; |
| 65 import 'scope.dart' show | 50 import 'scope.dart' show BlockScope, MethodScope, Scope; |
| 66 BlockScope, | 51 import 'signatures.dart' show SignatureResolver; |
| 67 MethodScope, | 52 import 'variables.dart' show VariableDefinitionsVisitor; |
| 68 Scope; | |
| 69 import 'signatures.dart' show | |
| 70 SignatureResolver; | |
| 71 import 'variables.dart' show | |
| 72 VariableDefinitionsVisitor; | |
| 73 | 53 |
| 74 /// The state of constants in resolutions. | 54 /// The state of constants in resolutions. |
| 75 enum ConstantState { | 55 enum ConstantState { |
| 76 /// Expressions are not required to be constants. | 56 /// Expressions are not required to be constants. |
| 77 NON_CONSTANT, | 57 NON_CONSTANT, |
| 78 | 58 |
| 79 /// Expressions are required to be constants. | 59 /// Expressions are required to be constants. |
| 80 /// | 60 /// |
| 81 /// For instance the values of a constant list literal. | 61 /// For instance the values of a constant list literal. |
| 82 CONSTANT, | 62 CONSTANT, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 113 Scope scope; | 93 Scope scope; |
| 114 ClassElement currentClass; | 94 ClassElement currentClass; |
| 115 ExpressionStatement currentExpressionStatement; | 95 ExpressionStatement currentExpressionStatement; |
| 116 | 96 |
| 117 /// `true` if a [Send] or [SendSet] is visited as the prefix of member access. | 97 /// `true` if a [Send] or [SendSet] is visited as the prefix of member access. |
| 118 /// For instance `Class` in `Class.staticField` or `prefix.Class` in | 98 /// For instance `Class` in `Class.staticField` or `prefix.Class` in |
| 119 /// `prefix.Class.staticMethod()`. | 99 /// `prefix.Class.staticMethod()`. |
| 120 bool sendIsMemberAccess = false; | 100 bool sendIsMemberAccess = false; |
| 121 | 101 |
| 122 StatementScope statementScope; | 102 StatementScope statementScope; |
| 123 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION | 103 int allowedCategory = ElementCategory.VARIABLE | |
| 124 | ElementCategory.IMPLIES_TYPE; | 104 ElementCategory.FUNCTION | |
| 105 ElementCategory.IMPLIES_TYPE; |
| 125 | 106 |
| 126 /// When visiting the type declaration of the variable in a [ForIn] loop, | 107 /// When visiting the type declaration of the variable in a [ForIn] loop, |
| 127 /// the initializer of the variable is implicit and we should not emit an | 108 /// the initializer of the variable is implicit and we should not emit an |
| 128 /// error when verifying that all final variables are initialized. | 109 /// error when verifying that all final variables are initialized. |
| 129 bool inLoopVariable = false; | 110 bool inLoopVariable = false; |
| 130 | 111 |
| 131 /// The nodes for which variable access and mutation must be registered in | 112 /// The nodes for which variable access and mutation must be registered in |
| 132 /// order to determine when the static type of variables types is promoted. | 113 /// order to determine when the static type of variables types is promoted. |
| 133 Link<Node> promotionScope = const Link<Node>(); | 114 Link<Node> promotionScope = const Link<Node>(); |
| 134 | 115 |
| 135 bool isPotentiallyMutableTarget(Element target) { | 116 bool isPotentiallyMutableTarget(Element target) { |
| 136 if (target == null) return false; | 117 if (target == null) return false; |
| 137 return (target.isVariable || target.isParameter) && | 118 return (target.isVariable || target.isParameter) && |
| 138 !(target.isFinal || target.isConst); | 119 !(target.isFinal || target.isConst); |
| 139 } | 120 } |
| 140 | 121 |
| 141 // TODO(ahe): Find a way to share this with runtime implementation. | 122 // TODO(ahe): Find a way to share this with runtime implementation. |
| 142 static final RegExp symbolValidationPattern = | 123 static final RegExp symbolValidationPattern = |
| 143 new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|' | 124 new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|' |
| 144 r'-|' | 125 r'-|' |
| 145 r'unary-|' | 126 r'unary-|' |
| 146 r'\[\]=|' | 127 r'\[\]=|' |
| 147 r'~|' | 128 r'~|' |
| 148 r'==|' | 129 r'==|' |
| 149 r'\[\]|' | 130 r'\[\]|' |
| 150 r'\*|' | 131 r'\*|' |
| 151 r'/|' | 132 r'/|' |
| 152 r'%|' | 133 r'%|' |
| 153 r'~/|' | 134 r'~/|' |
| 154 r'\+|' | 135 r'\+|' |
| 155 r'<<|' | 136 r'<<|' |
| 156 r'>>|' | 137 r'>>|' |
| 157 r'>=|' | 138 r'>=|' |
| 158 r'>|' | 139 r'>|' |
| 159 r'<=|' | 140 r'<=|' |
| 160 r'<|' | 141 r'<|' |
| 161 r'&|' | 142 r'&|' |
| 162 r'\^|' | 143 r'\^|' |
| 163 r'\|' | 144 r'\|' |
| 164 r')$'); | 145 r')$'); |
| 165 | 146 |
| 166 ResolverVisitor(Compiler compiler, | 147 ResolverVisitor( |
| 167 Element element, | 148 Compiler compiler, Element element, ResolutionRegistry registry, |
| 168 ResolutionRegistry registry, | 149 {bool useEnclosingScope: false}) |
| 169 {bool useEnclosingScope: false}) | 150 : this.enclosingElement = element, |
| 170 : this.enclosingElement = element, | 151 // When the element is a field, we are actually resolving its |
| 171 // When the element is a field, we are actually resolving its | 152 // initial value, which should not have access to instance |
| 172 // initial value, which should not have access to instance | 153 // fields. |
| 173 // fields. | 154 inInstanceContext = (element.isInstanceMember && !element.isField) || |
| 174 inInstanceContext = (element.isInstanceMember && !element.isField) | 155 element.isGenerativeConstructor, |
| 175 || element.isGenerativeConstructor, | 156 this.currentClass = |
| 176 this.currentClass = element.isClassMember ? element.enclosingClass | 157 element.isClassMember ? element.enclosingClass : null, |
| 177 : null, | 158 this.statementScope = new StatementScope(), |
| 178 this.statementScope = new StatementScope(), | 159 scope = useEnclosingScope |
| 179 scope = useEnclosingScope | 160 ? Scope.buildEnclosingScope(element) |
| 180 ? Scope.buildEnclosingScope(element) : element.buildScope(), | 161 : element.buildScope(), |
| 181 // The type annotations on a typedef do not imply type checks. | 162 // The type annotations on a typedef do not imply type checks. |
| 182 // TODO(karlklose): clean this up (dartbug.com/8870). | 163 // TODO(karlklose): clean this up (dartbug.com/8870). |
| 183 inCheckContext = compiler.options.enableTypeAssertions && | 164 inCheckContext = compiler.options.enableTypeAssertions && |
| 184 !element.isLibrary && | 165 !element.isLibrary && |
| 185 !element.isTypedef && | 166 !element.isTypedef && |
| 186 !element.enclosingElement.isTypedef, | 167 !element.enclosingElement.isTypedef, |
| 187 inCatchBlock = false, | 168 inCatchBlock = false, |
| 188 constantState = element.isConst | 169 constantState = element.isConst |
| 189 ? ConstantState.CONSTANT : ConstantState.NON_CONSTANT, | 170 ? ConstantState.CONSTANT |
| 190 super(compiler, registry); | 171 : ConstantState.NON_CONSTANT, |
| 172 super(compiler, registry); |
| 191 | 173 |
| 192 CoreClasses get coreClasses => compiler.coreClasses; | 174 CoreClasses get coreClasses => compiler.coreClasses; |
| 193 | 175 |
| 194 CoreTypes get coreTypes => compiler.coreTypes; | 176 CoreTypes get coreTypes => compiler.coreTypes; |
| 195 | 177 |
| 196 AsyncMarker get currentAsyncMarker { | 178 AsyncMarker get currentAsyncMarker { |
| 197 if (enclosingElement is FunctionElement) { | 179 if (enclosingElement is FunctionElement) { |
| 198 FunctionElement function = enclosingElement; | 180 FunctionElement function = enclosingElement; |
| 199 return function.asyncMarker; | 181 return function.asyncMarker; |
| 200 } | 182 } |
| 201 return AsyncMarker.SYNC; | 183 return AsyncMarker.SYNC; |
| 202 } | 184 } |
| 203 | 185 |
| 204 Element reportLookupErrorIfAny(Element result, Node node, String name) { | 186 Element reportLookupErrorIfAny(Element result, Node node, String name) { |
| 205 if (!Elements.isUnresolved(result)) { | 187 if (!Elements.isUnresolved(result)) { |
| 206 if (!inInstanceContext && result.isInstanceMember) { | 188 if (!inInstanceContext && result.isInstanceMember) { |
| 207 reporter.reportErrorMessage( | 189 reporter.reportErrorMessage( |
| 208 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); | 190 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
| 209 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, | 191 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, |
| 210 {'name': name}, | 192 {'name': name}, name, enclosingElement); |
| 211 name, enclosingElement); | |
| 212 } else if (result.isAmbiguous) { | 193 } else if (result.isAmbiguous) { |
| 213 AmbiguousElement ambiguous = result; | 194 AmbiguousElement ambiguous = result; |
| 214 return reportAndCreateErroneousElement( | 195 return reportAndCreateErroneousElement( |
| 215 node, | 196 node, name, ambiguous.messageKind, ambiguous.messageArguments, |
| 216 name, | 197 infos: ambiguous.computeInfos(enclosingElement, reporter), |
| 217 ambiguous.messageKind, | 198 isError: true); |
| 218 ambiguous.messageArguments, | |
| 219 infos: ambiguous.computeInfos(enclosingElement, reporter), | |
| 220 isError: true); | |
| 221 } | 199 } |
| 222 } | 200 } |
| 223 return result; | 201 return result; |
| 224 } | 202 } |
| 225 | 203 |
| 226 // Create, or reuse an already created, target element for a statement. | 204 // Create, or reuse an already created, target element for a statement. |
| 227 JumpTarget getOrDefineTarget(Node statement) { | 205 JumpTarget getOrDefineTarget(Node statement) { |
| 228 JumpTarget element = registry.getTargetDefinition(statement); | 206 JumpTarget element = registry.getTargetDefinition(statement); |
| 229 if (element == null) { | 207 if (element == null) { |
| 230 element = new JumpTargetX(statement, | 208 element = new JumpTargetX( |
| 231 statementScope.nestingLevel, | 209 statement, statementScope.nestingLevel, enclosingElement); |
| 232 enclosingElement); | |
| 233 registry.defineTarget(statement, element); | 210 registry.defineTarget(statement, element); |
| 234 } | 211 } |
| 235 return element; | 212 return element; |
| 236 } | 213 } |
| 237 | 214 |
| 238 doInPromotionScope(Node node, action()) { | 215 doInPromotionScope(Node node, action()) { |
| 239 promotionScope = promotionScope.prepend(node); | 216 promotionScope = promotionScope.prepend(node); |
| 240 var result = action(); | 217 var result = action(); |
| 241 promotionScope = promotionScope.tail; | 218 promotionScope = promotionScope.tail; |
| 242 return result; | 219 return result; |
| 243 } | 220 } |
| 244 | 221 |
| 245 inStaticContext(action(), | 222 inStaticContext(action(), {bool inConstantInitializer: false}) { |
| 246 {bool inConstantInitializer: false}) { | |
| 247 bool wasInstanceContext = inInstanceContext; | 223 bool wasInstanceContext = inInstanceContext; |
| 248 ConstantState oldConstantState = constantState; | 224 ConstantState oldConstantState = constantState; |
| 249 constantState = inConstantInitializer | 225 constantState = inConstantInitializer |
| 250 ? ConstantState.CONSTANT_INITIALIZER | 226 ? ConstantState.CONSTANT_INITIALIZER |
| 251 : constantState; | 227 : constantState; |
| 252 inInstanceContext = false; | 228 inInstanceContext = false; |
| 253 var result = action(); | 229 var result = action(); |
| 254 inInstanceContext = wasInstanceContext; | 230 inInstanceContext = wasInstanceContext; |
| 255 constantState = oldConstantState; | 231 constantState = oldConstantState; |
| 256 return result; | 232 return result; |
| 257 } | 233 } |
| 258 | 234 |
| 259 ResolutionResult visitInStaticContext(Node node, | 235 ResolutionResult visitInStaticContext(Node node, |
| 260 {bool inConstantInitializer: false}) { | 236 {bool inConstantInitializer: false}) { |
| 261 return inStaticContext( | 237 return inStaticContext(() => visit(node), |
| 262 () => visit(node), | |
| 263 inConstantInitializer: inConstantInitializer); | 238 inConstantInitializer: inConstantInitializer); |
| 264 } | 239 } |
| 265 | 240 |
| 266 /// Execute [action] where the constant state is `ConstantState.CONSTANT` if | 241 /// Execute [action] where the constant state is `ConstantState.CONSTANT` if |
| 267 /// not already `ConstantState.CONSTANT_INITIALIZER`. | 242 /// not already `ConstantState.CONSTANT_INITIALIZER`. |
| 268 inConstantContext(action()) { | 243 inConstantContext(action()) { |
| 269 ConstantState oldConstantState = constantState; | 244 ConstantState oldConstantState = constantState; |
| 270 if (constantState != ConstantState.CONSTANT_INITIALIZER) { | 245 if (constantState != ConstantState.CONSTANT_INITIALIZER) { |
| 271 constantState = ConstantState.CONSTANT; | 246 constantState = ConstantState.CONSTANT; |
| 272 } | 247 } |
| 273 var result = action(); | 248 var result = action(); |
| 274 constantState = oldConstantState; | 249 constantState = oldConstantState; |
| 275 return result; | 250 return result; |
| 276 } | 251 } |
| 277 | 252 |
| 278 /// Visit [node] where the constant state is `ConstantState.CONSTANT` if | 253 /// Visit [node] where the constant state is `ConstantState.CONSTANT` if |
| 279 /// not already `ConstantState.CONSTANT_INITIALIZER`. | 254 /// not already `ConstantState.CONSTANT_INITIALIZER`. |
| 280 ResolutionResult visitInConstantContext(Node node) { | 255 ResolutionResult visitInConstantContext(Node node) { |
| 281 ResolutionResult result = inConstantContext(() => visit(node)); | 256 ResolutionResult result = inConstantContext(() => visit(node)); |
| 282 assert(invariant(node, result != null, | 257 assert(invariant(node, result != null, |
| 283 message: "No resolution result for $node.")); | 258 message: "No resolution result for $node.")); |
| 284 | 259 |
| 285 return result; | 260 return result; |
| 286 } | 261 } |
| 287 | 262 |
| 288 ErroneousElement reportAndCreateErroneousElement( | 263 ErroneousElement reportAndCreateErroneousElement( |
| 289 Node node, | 264 Node node, String name, MessageKind kind, Map arguments, |
| 290 String name, | |
| 291 MessageKind kind, | |
| 292 Map arguments, | |
| 293 {List<DiagnosticMessage> infos: const <DiagnosticMessage>[], | 265 {List<DiagnosticMessage> infos: const <DiagnosticMessage>[], |
| 294 bool isError: false}) { | 266 bool isError: false}) { |
| 295 if (isError) { | 267 if (isError) { |
| 296 reporter.reportError( | 268 reporter.reportError( |
| 297 reporter.createMessage(node, kind, arguments), infos); | 269 reporter.createMessage(node, kind, arguments), infos); |
| 298 } else { | 270 } else { |
| 299 reporter.reportWarning( | 271 reporter.reportWarning( |
| 300 reporter.createMessage(node, kind, arguments), infos); | 272 reporter.createMessage(node, kind, arguments), infos); |
| 301 } | 273 } |
| 302 // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass | 274 // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass |
| 303 // of [ErroneousElementX]. For example, [ErroneousFieldElementX], | 275 // of [ErroneousElementX]. For example, [ErroneousFieldElementX], |
| 304 // [ErroneousConstructorElementX], etc. | 276 // [ErroneousConstructorElementX], etc. |
| 305 return new ErroneousElementX(kind, arguments, name, enclosingElement); | 277 return new ErroneousElementX(kind, arguments, name, enclosingElement); |
| 306 } | 278 } |
| 307 | 279 |
| 308 /// Report a warning or error on an unresolved access in non-instance context. | 280 /// Report a warning or error on an unresolved access in non-instance context. |
| 309 /// | 281 /// |
| 310 /// The [ErroneousElement] corresponding to the message is returned. | 282 /// The [ErroneousElement] corresponding to the message is returned. |
| 311 ErroneousElement reportCannotResolve(Node node, String name) { | 283 ErroneousElement reportCannotResolve(Node node, String name) { |
| 312 assert(invariant(node, !inInstanceContext, | 284 assert(invariant(node, !inInstanceContext, |
| 313 message: "ResolverVisitor.reportCannotResolve must not be called in " | 285 message: "ResolverVisitor.reportCannotResolve must not be called in " |
| 314 "instance context.")); | 286 "instance context.")); |
| 315 | 287 |
| 316 // We report an error within initializers because `this` is implicitly | 288 // We report an error within initializers because `this` is implicitly |
| 317 // accessed when unqualified identifiers are not resolved. For | 289 // accessed when unqualified identifiers are not resolved. For |
| 318 // details, see section 16.14.3 of the spec (2nd edition): | 290 // details, see section 16.14.3 of the spec (2nd edition): |
| 319 // An unqualified invocation `i` of the form `id(a1, ...)` | 291 // An unqualified invocation `i` of the form `id(a1, ...)` |
| 320 // ... | 292 // ... |
| 321 // If `i` does not occur inside a top level or static function, `i` | 293 // If `i` does not occur inside a top level or static function, `i` |
| 322 // is equivalent to `this.id(a1 , ...)`. | 294 // is equivalent to `this.id(a1 , ...)`. |
| 323 bool inInitializer = | 295 bool inInitializer = enclosingElement.isGenerativeConstructor || |
| 324 enclosingElement.isGenerativeConstructor || | |
| 325 (enclosingElement.isInstanceMember && enclosingElement.isField); | 296 (enclosingElement.isInstanceMember && enclosingElement.isField); |
| 326 MessageKind kind; | 297 MessageKind kind; |
| 327 Map arguments = {'name': name}; | 298 Map arguments = {'name': name}; |
| 328 if (inInitializer) { | 299 if (inInitializer) { |
| 329 kind = MessageKind.CANNOT_RESOLVE_IN_INITIALIZER; | 300 kind = MessageKind.CANNOT_RESOLVE_IN_INITIALIZER; |
| 330 } else if (name == 'await') { | 301 } else if (name == 'await') { |
| 331 var functionName = enclosingElement.name; | 302 var functionName = enclosingElement.name; |
| 332 if (functionName == '') { | 303 if (functionName == '') { |
| 333 kind = MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE; | 304 kind = MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE; |
| 334 } else { | 305 } else { |
| 335 kind = MessageKind.CANNOT_RESOLVE_AWAIT; | 306 kind = MessageKind.CANNOT_RESOLVE_AWAIT; |
| 336 arguments['functionName'] = functionName; | 307 arguments['functionName'] = functionName; |
| 337 } | 308 } |
| 338 } else { | 309 } else { |
| 339 kind = MessageKind.CANNOT_RESOLVE; | 310 kind = MessageKind.CANNOT_RESOLVE; |
| 340 } | 311 } |
| 341 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 312 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 342 return reportAndCreateErroneousElement( | 313 return reportAndCreateErroneousElement(node, name, kind, arguments, |
| 343 node, name, kind, arguments, isError: inInitializer); | 314 isError: inInitializer); |
| 344 } | 315 } |
| 345 | 316 |
| 346 ResolutionResult visitIdentifier(Identifier node) { | 317 ResolutionResult visitIdentifier(Identifier node) { |
| 347 if (node.isThis()) { | 318 if (node.isThis()) { |
| 348 if (!inInstanceContext) { | 319 if (!inInstanceContext) { |
| 349 reporter.reportErrorMessage( | 320 reporter.reportErrorMessage( |
| 350 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); | 321 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); |
| 351 } | 322 } |
| 352 return const NoneResult(); | 323 return const NoneResult(); |
| 353 } else if (node.isSuper()) { | 324 } else if (node.isSuper()) { |
| 354 if (!inInstanceContext) { | 325 if (!inInstanceContext) { |
| 355 reporter.reportErrorMessage( | 326 reporter.reportErrorMessage(node, MessageKind.NO_SUPER_IN_STATIC); |
| 356 node, MessageKind.NO_SUPER_IN_STATIC); | |
| 357 } | 327 } |
| 358 if ((ElementCategory.SUPER & allowedCategory) == 0) { | 328 if ((ElementCategory.SUPER & allowedCategory) == 0) { |
| 359 reporter.reportErrorMessage( | 329 reporter.reportErrorMessage(node, MessageKind.INVALID_USE_OF_SUPER); |
| 360 node, MessageKind.INVALID_USE_OF_SUPER); | |
| 361 } | 330 } |
| 362 return const NoneResult(); | 331 return const NoneResult(); |
| 363 } else { | 332 } else { |
| 364 String name = node.source; | 333 String name = node.source; |
| 365 Element element = lookupInScope(reporter, node, scope, name); | 334 Element element = lookupInScope(reporter, node, scope, name); |
| 366 if (Elements.isUnresolved(element) && name == 'dynamic') { | 335 if (Elements.isUnresolved(element) && name == 'dynamic') { |
| 367 // TODO(johnniwinther): Remove this hack when we can return more complex | 336 // TODO(johnniwinther): Remove this hack when we can return more complex |
| 368 // objects than [Element] from this method. | 337 // objects than [Element] from this method. |
| 369 element = coreClasses.typeClass; | 338 element = coreClasses.typeClass; |
| 370 // Set the type to be `dynamic` to mark that this is a type literal. | 339 // Set the type to be `dynamic` to mark that this is a type literal. |
| 371 registry.setType(node, const DynamicType()); | 340 registry.setType(node, const DynamicType()); |
| 372 } | 341 } |
| 373 element = reportLookupErrorIfAny(element, node, name); | 342 element = reportLookupErrorIfAny(element, node, name); |
| 374 if (element == null) { | 343 if (element == null) { |
| 375 if (!inInstanceContext) { | 344 if (!inInstanceContext) { |
| 376 element = reportCannotResolve(node, name); | 345 element = reportCannotResolve(node, name); |
| 377 } | 346 } |
| 378 } else if (element.isMalformed) { | 347 } else if (element.isMalformed) { |
| 379 // Use the malformed element. | 348 // Use the malformed element. |
| 380 } else { | 349 } else { |
| 381 if ((element.kind.category & allowedCategory) == 0) { | 350 if ((element.kind.category & allowedCategory) == 0) { |
| 382 element = reportAndCreateErroneousElement( | 351 element = |
| 383 node, name, MessageKind.GENERIC, | 352 reportAndCreateErroneousElement(node, name, MessageKind.GENERIC, |
| 384 // TODO(ahe): Improve error message. Need UX input. | 353 // TODO(ahe): Improve error message. Need UX input. |
| 385 {'text': "is not an expression $element"}); | 354 {'text': "is not an expression $element"}); |
| 386 } | 355 } |
| 387 } | 356 } |
| 388 if (!Elements.isUnresolved(element) && element.isClass) { | 357 if (!Elements.isUnresolved(element) && element.isClass) { |
| 389 ClassElement classElement = element; | 358 ClassElement classElement = element; |
| 390 classElement.ensureResolved(resolution); | 359 classElement.ensureResolved(resolution); |
| 391 } | 360 } |
| 392 if (element != null) { | 361 if (element != null) { |
| 393 registry.useElement(node, element); | 362 registry.useElement(node, element); |
| 394 if (element.isPrefix) { | 363 if (element.isPrefix) { |
| 395 return new PrefixResult(element, null); | 364 return new PrefixResult(element, null); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 423 | 392 |
| 424 FunctionElement resolveConstructorRedirection(FunctionElementX constructor) { | 393 FunctionElement resolveConstructorRedirection(FunctionElementX constructor) { |
| 425 FunctionExpression node = constructor.parseNode(resolution.parsing); | 394 FunctionExpression node = constructor.parseNode(resolution.parsing); |
| 426 | 395 |
| 427 // A synthetic constructor does not have a node. | 396 // A synthetic constructor does not have a node. |
| 428 if (node == null) return null; | 397 if (node == null) return null; |
| 429 if (node.initializers == null) return null; | 398 if (node.initializers == null) return null; |
| 430 Link<Node> initializers = node.initializers.nodes; | 399 Link<Node> initializers = node.initializers.nodes; |
| 431 if (!initializers.isEmpty && | 400 if (!initializers.isEmpty && |
| 432 Initializers.isConstructorRedirect(initializers.head)) { | 401 Initializers.isConstructorRedirect(initializers.head)) { |
| 433 Name name = | 402 Name name = getRedirectingThisOrSuperConstructorName(initializers.head); |
| 434 getRedirectingThisOrSuperConstructorName(initializers.head); | |
| 435 final ClassElement classElement = constructor.enclosingClass; | 403 final ClassElement classElement = constructor.enclosingClass; |
| 436 return classElement.lookupConstructor(name.text); | 404 return classElement.lookupConstructor(name.text); |
| 437 } | 405 } |
| 438 return null; | 406 return null; |
| 439 } | 407 } |
| 440 | 408 |
| 441 void setupFunction(FunctionExpression node, FunctionElement function) { | 409 void setupFunction(FunctionExpression node, FunctionElement function) { |
| 442 Element enclosingElement = function.enclosingElement; | 410 Element enclosingElement = function.enclosingElement; |
| 443 if (node.modifiers.isStatic && | 411 if (node.modifiers.isStatic && enclosingElement.kind != ElementKind.CLASS) { |
| 444 enclosingElement.kind != ElementKind.CLASS) { | |
| 445 reporter.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC); | 412 reporter.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC); |
| 446 } | 413 } |
| 447 | 414 |
| 448 scope = new MethodScope(scope, function); | 415 scope = new MethodScope(scope, function); |
| 449 // Put the parameters in scope. | 416 // Put the parameters in scope. |
| 450 FunctionSignature functionParameters = function.functionSignature; | 417 FunctionSignature functionParameters = function.functionSignature; |
| 451 Link<Node> parameterNodes = (node.parameters == null) | 418 Link<Node> parameterNodes = |
| 452 ? const Link<Node>() : node.parameters.nodes; | 419 (node.parameters == null) ? const Link<Node>() : node.parameters.nodes; |
| 453 functionParameters.forEachParameter((ParameterElementX element) { | 420 functionParameters.forEachParameter((ParameterElementX element) { |
| 454 // TODO(karlklose): should be a list of [FormalElement]s, but the actual | 421 // TODO(karlklose): should be a list of [FormalElement]s, but the actual |
| 455 // implementation uses [Element]. | 422 // implementation uses [Element]. |
| 456 List<Element> optionals = functionParameters.optionalParameters; | 423 List<Element> optionals = functionParameters.optionalParameters; |
| 457 if (!optionals.isEmpty && element == optionals.first) { | 424 if (!optionals.isEmpty && element == optionals.first) { |
| 458 NodeList nodes = parameterNodes.head; | 425 NodeList nodes = parameterNodes.head; |
| 459 parameterNodes = nodes.nodes; | 426 parameterNodes = nodes.nodes; |
| 460 } | 427 } |
| 461 if (element.isOptional) { | 428 if (element.isOptional) { |
| 462 if (element.initializer != null) { | 429 if (element.initializer != null) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 475 if (element.isInitializingFormal) { | 442 if (element.isInitializingFormal) { |
| 476 registry.useElement(parameterNode, element); | 443 registry.useElement(parameterNode, element); |
| 477 } else { | 444 } else { |
| 478 LocalParameterElementX parameterElement = element; | 445 LocalParameterElementX parameterElement = element; |
| 479 defineLocalVariable(parameterNode, parameterElement); | 446 defineLocalVariable(parameterNode, parameterElement); |
| 480 addToScope(parameterElement); | 447 addToScope(parameterElement); |
| 481 } | 448 } |
| 482 parameterNodes = parameterNodes.tail; | 449 parameterNodes = parameterNodes.tail; |
| 483 }); | 450 }); |
| 484 addDeferredAction(enclosingElement, () { | 451 addDeferredAction(enclosingElement, () { |
| 485 functionParameters.forEachOptionalParameter( | 452 functionParameters |
| 486 (ParameterElementX parameter) { | 453 .forEachOptionalParameter((ParameterElementX parameter) { |
| 487 parameter.constant = | 454 parameter.constant = |
| 488 compiler.resolver.constantCompiler.compileConstant(parameter); | 455 compiler.resolver.constantCompiler.compileConstant(parameter); |
| 489 }); | 456 }); |
| 490 }); | 457 }); |
| 491 if (inCheckContext) { | 458 if (inCheckContext) { |
| 492 functionParameters.forEachParameter((ParameterElement element) { | 459 functionParameters.forEachParameter((ParameterElement element) { |
| 493 registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type)); | 460 registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type)); |
| 494 }); | 461 }); |
| 495 } | 462 } |
| 496 } | 463 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 visitLoopBodyIn(node, node.body, blockScope); | 541 visitLoopBodyIn(node, node.body, blockScope); |
| 575 return const NoneResult(); | 542 return const NoneResult(); |
| 576 } | 543 } |
| 577 | 544 |
| 578 ResolutionResult visitFunctionDeclaration(FunctionDeclaration node) { | 545 ResolutionResult visitFunctionDeclaration(FunctionDeclaration node) { |
| 579 assert(node.function.name != null); | 546 assert(node.function.name != null); |
| 580 visitFunctionExpression(node.function, inFunctionDeclaration: true); | 547 visitFunctionExpression(node.function, inFunctionDeclaration: true); |
| 581 return const NoneResult(); | 548 return const NoneResult(); |
| 582 } | 549 } |
| 583 | 550 |
| 584 | |
| 585 /// Process a local function declaration or an anonymous function expression. | 551 /// Process a local function declaration or an anonymous function expression. |
| 586 /// | 552 /// |
| 587 /// [inFunctionDeclaration] is `true` when the current node is the immediate | 553 /// [inFunctionDeclaration] is `true` when the current node is the immediate |
| 588 /// child of a function declaration. | 554 /// child of a function declaration. |
| 589 /// | 555 /// |
| 590 /// This is used to distinguish local function declarations from anonymous | 556 /// This is used to distinguish local function declarations from anonymous |
| 591 /// function expressions. | 557 /// function expressions. |
| 592 ResolutionResult visitFunctionExpression( | 558 ResolutionResult visitFunctionExpression(FunctionExpression node, |
| 593 FunctionExpression node, | |
| 594 {bool inFunctionDeclaration: false}) { | 559 {bool inFunctionDeclaration: false}) { |
| 595 bool doAddToScope = inFunctionDeclaration; | 560 bool doAddToScope = inFunctionDeclaration; |
| 596 if (!inFunctionDeclaration && node.name != null) { | 561 if (!inFunctionDeclaration && node.name != null) { |
| 597 reporter.reportErrorMessage( | 562 reporter.reportErrorMessage(node.name, |
| 598 node.name, | 563 MessageKind.NAMED_FUNCTION_EXPRESSION, {'name': node.name}); |
| 599 MessageKind.NAMED_FUNCTION_EXPRESSION, | |
| 600 {'name': node.name}); | |
| 601 } | 564 } |
| 602 visit(node.returnType); | 565 visit(node.returnType); |
| 603 String name; | 566 String name; |
| 604 if (node.name == null) { | 567 if (node.name == null) { |
| 605 name = ""; | 568 name = ""; |
| 606 } else { | 569 } else { |
| 607 name = node.name.asIdentifier().source; | 570 name = node.name.asIdentifier().source; |
| 608 } | 571 } |
| 609 LocalFunctionElementX function = new LocalFunctionElementX( | 572 LocalFunctionElementX function = new LocalFunctionElementX( |
| 610 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, | 573 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, enclosingElement); |
| 611 enclosingElement); | |
| 612 ResolverTask.processAsyncMarker(compiler, function, registry); | 574 ResolverTask.processAsyncMarker(compiler, function, registry); |
| 613 function.functionSignature = SignatureResolver.analyze( | 575 function.functionSignature = SignatureResolver.analyze( |
| 614 compiler, | 576 compiler, node.parameters, node.returnType, function, registry, |
| 615 node.parameters, | |
| 616 node.returnType, | |
| 617 function, | |
| 618 registry, | |
| 619 createRealParameters: true, | 577 createRealParameters: true, |
| 620 isFunctionExpression: !inFunctionDeclaration); | 578 isFunctionExpression: !inFunctionDeclaration); |
| 621 checkLocalDefinitionName(node, function); | 579 checkLocalDefinitionName(node, function); |
| 622 registry.defineFunction(node, function); | 580 registry.defineFunction(node, function); |
| 623 if (doAddToScope) { | 581 if (doAddToScope) { |
| 624 addToScope(function); | 582 addToScope(function); |
| 625 } | 583 } |
| 626 Scope oldScope = scope; // The scope is modified by [setupFunction]. | 584 Scope oldScope = scope; // The scope is modified by [setupFunction]. |
| 627 setupFunction(node, function); | 585 setupFunction(node, function); |
| 628 | 586 |
| 629 Element previousEnclosingElement = enclosingElement; | 587 Element previousEnclosingElement = enclosingElement; |
| 630 enclosingElement = function; | 588 enclosingElement = function; |
| 631 // Run the body in a fresh statement scope. | 589 // Run the body in a fresh statement scope. |
| 632 StatementScope oldStatementScope = statementScope; | 590 StatementScope oldStatementScope = statementScope; |
| 633 statementScope = new StatementScope(); | 591 statementScope = new StatementScope(); |
| 634 visit(node.body); | 592 visit(node.body); |
| 635 statementScope = oldStatementScope; | 593 statementScope = oldStatementScope; |
| 636 | 594 |
| 637 scope = oldScope; | 595 scope = oldScope; |
| 638 enclosingElement = previousEnclosingElement; | 596 enclosingElement = previousEnclosingElement; |
| 639 | 597 |
| 640 registry.registerStaticUse(new StaticUse.closure(function)); | 598 registry.registerStaticUse(new StaticUse.closure(function)); |
| 641 return const NoneResult(); | 599 return const NoneResult(); |
| 642 } | 600 } |
| 643 | 601 |
| 644 ResolutionResult visitIf(If node) { | 602 ResolutionResult visitIf(If node) { |
| 645 doInPromotionScope(node.condition.expression, () => visit(node.condition)); | 603 doInPromotionScope(node.condition.expression, () => visit(node.condition)); |
| 646 doInPromotionScope(node.thenPart, | 604 doInPromotionScope( |
| 647 () => visitIn(node.thenPart, new BlockScope(scope))); | 605 node.thenPart, () => visitIn(node.thenPart, new BlockScope(scope))); |
| 648 visitIn(node.elsePart, new BlockScope(scope)); | 606 visitIn(node.elsePart, new BlockScope(scope)); |
| 649 return const NoneResult(); | 607 return const NoneResult(); |
| 650 } | 608 } |
| 651 | 609 |
| 652 static Selector computeSendSelector(Send node, | 610 static Selector computeSendSelector( |
| 653 LibraryElement library, | 611 Send node, LibraryElement library, Element element) { |
| 654 Element element) { | |
| 655 // First determine if this is part of an assignment. | 612 // First determine if this is part of an assignment. |
| 656 bool isSet = node.asSendSet() != null; | 613 bool isSet = node.asSendSet() != null; |
| 657 | 614 |
| 658 if (node.isIndex) { | 615 if (node.isIndex) { |
| 659 return isSet ? new Selector.indexSet() : new Selector.index(); | 616 return isSet ? new Selector.indexSet() : new Selector.index(); |
| 660 } | 617 } |
| 661 | 618 |
| 662 if (node.isOperator) { | 619 if (node.isOperator) { |
| 663 String source = node.selector.asOperator().source; | 620 String source = node.selector.asOperator().source; |
| 664 String string = source; | 621 String string = source; |
| 665 if (identical(string, '!') || | 622 if (identical(string, '!') || |
| 666 identical(string, '&&') || identical(string, '||') || | 623 identical(string, '&&') || |
| 667 identical(string, 'is') || identical(string, 'as') || | 624 identical(string, '||') || |
| 668 identical(string, '?') || identical(string, '??')) { | 625 identical(string, 'is') || |
| 626 identical(string, 'as') || |
| 627 identical(string, '?') || |
| 628 identical(string, '??')) { |
| 669 return null; | 629 return null; |
| 670 } | 630 } |
| 671 String op = source; | 631 String op = source; |
| 672 if (!isUserDefinableOperator(source)) { | 632 if (!isUserDefinableOperator(source)) { |
| 673 op = Elements.mapToUserOperatorOrNull(source); | 633 op = Elements.mapToUserOperatorOrNull(source); |
| 674 } | 634 } |
| 675 if (op == null) { | 635 if (op == null) { |
| 676 // Unsupported operator. An error has been reported during parsing. | 636 // Unsupported operator. An error has been reported during parsing. |
| 677 return new Selector.call( | 637 return new Selector.call(new Name(source, library), |
| 678 new Name(source, library), | |
| 679 new CallStructure.unnamed(node.argumentsNode.slowLength())); | 638 new CallStructure.unnamed(node.argumentsNode.slowLength())); |
| 680 } | 639 } |
| 681 return node.arguments.isEmpty | 640 return node.arguments.isEmpty |
| 682 ? new Selector.unaryOperator(op) | 641 ? new Selector.unaryOperator(op) |
| 683 : new Selector.binaryOperator(op); | 642 : new Selector.binaryOperator(op); |
| 684 } | 643 } |
| 685 | 644 |
| 686 Identifier identifier = node.selector.asIdentifier(); | 645 Identifier identifier = node.selector.asIdentifier(); |
| 687 if (node.isPropertyAccess) { | 646 if (node.isPropertyAccess) { |
| 688 assert(!isSet); | 647 assert(!isSet); |
| 689 return new Selector.getter( | 648 return new Selector.getter(new Name(identifier.source, library)); |
| 690 new Name(identifier.source, library)); | |
| 691 } else if (isSet) { | 649 } else if (isSet) { |
| 692 return new Selector.setter( | 650 return new Selector.setter( |
| 693 new Name(identifier.source, library, isSetter: true)); | 651 new Name(identifier.source, library, isSetter: true)); |
| 694 } | 652 } |
| 695 | 653 |
| 696 // Compute the arity and the list of named arguments. | 654 // Compute the arity and the list of named arguments. |
| 697 int arity = 0; | 655 int arity = 0; |
| 698 List<String> named = <String>[]; | 656 List<String> named = <String>[]; |
| 699 for (Link<Node> link = node.argumentsNode.nodes; | 657 for (Link<Node> link = node.argumentsNode.nodes; |
| 700 !link.isEmpty; | 658 !link.isEmpty; |
| 701 link = link.tail) { | 659 link = link.tail) { |
| 702 Expression argument = link.head; | 660 Expression argument = link.head; |
| 703 NamedArgument namedArgument = argument.asNamedArgument(); | 661 NamedArgument namedArgument = argument.asNamedArgument(); |
| 704 if (namedArgument != null) { | 662 if (namedArgument != null) { |
| 705 named.add(namedArgument.name.source); | 663 named.add(namedArgument.name.source); |
| 706 } | 664 } |
| 707 arity++; | 665 arity++; |
| 708 } | 666 } |
| 709 | 667 |
| 710 if (element != null && element.isConstructor) { | 668 if (element != null && element.isConstructor) { |
| 711 return new Selector.callConstructor( | 669 return new Selector.callConstructor( |
| 712 new Name(element.name, library), arity, named); | 670 new Name(element.name, library), arity, named); |
| 713 } | 671 } |
| 714 | 672 |
| 715 // If we're invoking a closure, we do not have an identifier. | 673 // If we're invoking a closure, we do not have an identifier. |
| 716 return (identifier == null) | 674 return (identifier == null) |
| 717 ? new Selector.callClosure(arity, named) | 675 ? new Selector.callClosure(arity, named) |
| 718 : new Selector.call(new Name(identifier.source, library), | 676 : new Selector.call(new Name(identifier.source, library), |
| 719 new CallStructure(arity, named)); | 677 new CallStructure(arity, named)); |
| 720 } | 678 } |
| 721 | 679 |
| 722 Selector resolveSelector(Send node, Element element) { | 680 Selector resolveSelector(Send node, Element element) { |
| 723 LibraryElement library = enclosingElement.library; | 681 LibraryElement library = enclosingElement.library; |
| 724 Selector selector = computeSendSelector(node, library, element); | 682 Selector selector = computeSendSelector(node, library, element); |
| 725 if (selector != null) registry.setSelector(node, selector); | 683 if (selector != null) registry.setSelector(node, selector); |
| 726 return selector; | 684 return selector; |
| 727 } | 685 } |
| 728 | 686 |
| 729 ArgumentsResult resolveArguments(NodeList list) { | 687 ArgumentsResult resolveArguments(NodeList list) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 742 isValidAsConstant = false; | 700 isValidAsConstant = false; |
| 743 } | 701 } |
| 744 argumentResults.add(result); | 702 argumentResults.add(result); |
| 745 | 703 |
| 746 NamedArgument namedArgument = argument.asNamedArgument(); | 704 NamedArgument namedArgument = argument.asNamedArgument(); |
| 747 if (namedArgument != null) { | 705 if (namedArgument != null) { |
| 748 String source = namedArgument.name.source; | 706 String source = namedArgument.name.source; |
| 749 namedArguments.add(source); | 707 namedArguments.add(source); |
| 750 if (seenNamedArguments.containsKey(source)) { | 708 if (seenNamedArguments.containsKey(source)) { |
| 751 reportDuplicateDefinition( | 709 reportDuplicateDefinition( |
| 752 source, | 710 source, argument, seenNamedArguments[source]); |
| 753 argument, | |
| 754 seenNamedArguments[source]); | |
| 755 isValidAsConstant = false; | 711 isValidAsConstant = false; |
| 756 } else { | 712 } else { |
| 757 seenNamedArguments[source] = namedArgument; | 713 seenNamedArguments[source] = namedArgument; |
| 758 } | 714 } |
| 759 } else if (!seenNamedArguments.isEmpty) { | 715 } else if (!seenNamedArguments.isEmpty) { |
| 760 reporter.reportErrorMessage( | 716 reporter.reportErrorMessage( |
| 761 argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); | 717 argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); |
| 762 isValidAsConstant = false; | 718 isValidAsConstant = false; |
| 763 } | 719 } |
| 764 argumentCount++; | 720 argumentCount++; |
| 765 } | 721 } |
| 766 sendIsMemberAccess = oldSendIsMemberAccess; | 722 sendIsMemberAccess = oldSendIsMemberAccess; |
| 767 return new ArgumentsResult( | 723 return new ArgumentsResult( |
| 768 new CallStructure(argumentCount, namedArguments), | 724 new CallStructure(argumentCount, namedArguments), argumentResults, |
| 769 argumentResults, | |
| 770 isValidAsConstant: isValidAsConstant); | 725 isValidAsConstant: isValidAsConstant); |
| 771 } | 726 } |
| 772 | 727 |
| 773 /// Check that access to `super` is currently allowed. Returns an | 728 /// Check that access to `super` is currently allowed. Returns an |
| 774 /// [AccessSemantics] in case of an error, `null` otherwise. | 729 /// [AccessSemantics] in case of an error, `null` otherwise. |
| 775 AccessSemantics checkSuperAccess(Send node) { | 730 AccessSemantics checkSuperAccess(Send node) { |
| 776 if (!inInstanceContext) { | 731 if (!inInstanceContext) { |
| 777 ErroneousElement error = reportAndCreateErroneousElement( | 732 ErroneousElement error = reportAndCreateErroneousElement( |
| 778 node, 'super', | 733 node, 'super', MessageKind.NO_SUPER_IN_STATIC, {}, |
| 779 MessageKind.NO_SUPER_IN_STATIC, {}, | |
| 780 isError: true); | 734 isError: true); |
| 781 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 735 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
| 782 return new StaticAccess.invalid(error); | 736 return new StaticAccess.invalid(error); |
| 783 } | 737 } |
| 784 if (node.isConditional) { | 738 if (node.isConditional) { |
| 785 // `super?.foo` is not allowed. | 739 // `super?.foo` is not allowed. |
| 786 ErroneousElement error = reportAndCreateErroneousElement( | 740 ErroneousElement error = reportAndCreateErroneousElement( |
| 787 node, 'super', | 741 node, 'super', MessageKind.INVALID_USE_OF_SUPER, {}, |
| 788 MessageKind.INVALID_USE_OF_SUPER, {}, | |
| 789 isError: true); | 742 isError: true); |
| 790 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 743 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
| 791 return new StaticAccess.invalid(error); | 744 return new StaticAccess.invalid(error); |
| 792 } | 745 } |
| 793 if (currentClass.supertype == null) { | 746 if (currentClass.supertype == null) { |
| 794 // This is just to guard against internal errors, so no need | 747 // This is just to guard against internal errors, so no need |
| 795 // for a real error message. | 748 // for a real error message. |
| 796 ErroneousElement error = reportAndCreateErroneousElement( | 749 ErroneousElement error = reportAndCreateErroneousElement(node, 'super', |
| 797 node, 'super', | 750 MessageKind.GENERIC, {'text': "Object has no superclass"}, |
| 798 MessageKind.GENERIC, | |
| 799 {'text': "Object has no superclass"}, | |
| 800 isError: true); | 751 isError: true); |
| 801 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 752 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
| 802 return new StaticAccess.invalid(error); | 753 return new StaticAccess.invalid(error); |
| 803 } | 754 } |
| 804 registry.registerSuperUse(reporter.spanFromSpannable(node)); | 755 registry.registerSuperUse(reporter.spanFromSpannable(node)); |
| 805 return null; | 756 return null; |
| 806 } | 757 } |
| 807 | 758 |
| 808 /// Check that access to `this` is currently allowed. Returns an | 759 /// Check that access to `this` is currently allowed. Returns an |
| 809 /// [AccessSemantics] in case of an error, `null` otherwise. | 760 /// [AccessSemantics] in case of an error, `null` otherwise. |
| 810 AccessSemantics checkThisAccess(Send node) { | 761 AccessSemantics checkThisAccess(Send node) { |
| 811 if (!inInstanceContext) { | 762 if (!inInstanceContext) { |
| 812 ErroneousElement error = reportAndCreateErroneousElement( | 763 ErroneousElement error = reportAndCreateErroneousElement( |
| 813 node, 'this', | 764 node, 'this', MessageKind.NO_THIS_AVAILABLE, const {}, |
| 814 MessageKind.NO_THIS_AVAILABLE, const {}, | |
| 815 isError: true); | 765 isError: true); |
| 816 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 766 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
| 817 return new StaticAccess.invalid(error); | 767 return new StaticAccess.invalid(error); |
| 818 } | 768 } |
| 819 return null; | 769 return null; |
| 820 } | 770 } |
| 821 | 771 |
| 822 /// Compute the [AccessSemantics] corresponding to a super access of [target]. | 772 /// Compute the [AccessSemantics] corresponding to a super access of [target]. |
| 823 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) { | 773 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) { |
| 824 if (target.isMalformed) { | 774 if (target.isMalformed) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 836 } else { | 786 } else { |
| 837 assert(invariant(node, target.isFunction, | 787 assert(invariant(node, target.isFunction, |
| 838 message: "Unexpected super target '$target'.")); | 788 message: "Unexpected super target '$target'.")); |
| 839 return new StaticAccess.superMethod(target); | 789 return new StaticAccess.superMethod(target); |
| 840 } | 790 } |
| 841 } | 791 } |
| 842 | 792 |
| 843 /// Compute the [AccessSemantics] corresponding to a compound super access | 793 /// Compute the [AccessSemantics] corresponding to a compound super access |
| 844 /// reading from [getter] and writing to [setter]. | 794 /// reading from [getter] and writing to [setter]. |
| 845 AccessSemantics computeCompoundSuperAccessSemantics( | 795 AccessSemantics computeCompoundSuperAccessSemantics( |
| 846 Spannable node, | 796 Spannable node, Element getter, Element setter, |
| 847 Element getter, | |
| 848 Element setter, | |
| 849 {bool isIndex: false}) { | 797 {bool isIndex: false}) { |
| 850 if (getter.isMalformed) { | 798 if (getter.isMalformed) { |
| 851 if (setter.isMalformed) { | 799 if (setter.isMalformed) { |
| 852 return new StaticAccess.unresolvedSuper(getter); | 800 return new StaticAccess.unresolvedSuper(getter); |
| 853 } else if (setter.isFunction) { | 801 } else if (setter.isFunction) { |
| 854 assert(invariant(node, setter.name == '[]=', | 802 assert(invariant(node, setter.name == '[]=', |
| 855 message: "Unexpected super setter '$setter'.")); | 803 message: "Unexpected super setter '$setter'.")); |
| 856 return new CompoundAccessSemantics( | 804 return new CompoundAccessSemantics( |
| 857 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); | 805 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); |
| 858 } else { | 806 } else { |
| 859 assert(invariant(node, setter.isSetter, | 807 assert(invariant(node, setter.isSetter, |
| 860 message: "Unexpected super setter '$setter'.")); | 808 message: "Unexpected super setter '$setter'.")); |
| 861 return new CompoundAccessSemantics( | 809 return new CompoundAccessSemantics( |
| 862 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); | 810 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); |
| 863 } | 811 } |
| 864 } else if (getter.isField) { | 812 } else if (getter.isField) { |
| 865 if (setter.isMalformed) { | 813 if (setter.isMalformed) { |
| 866 assert(invariant(node, getter.isFinal, | 814 assert(invariant(node, getter.isFinal, |
| 867 message: "Unexpected super setter '$setter' for getter '$getter.")); | 815 message: "Unexpected super setter '$setter' for getter '$getter.")); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); | 852 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); |
| 905 } else { | 853 } else { |
| 906 return new StaticAccess.superMethod(getter); | 854 return new StaticAccess.superMethod(getter); |
| 907 } | 855 } |
| 908 } else if (setter.isFunction) { | 856 } else if (setter.isFunction) { |
| 909 assert(invariant(node, setter.name == '[]=', | 857 assert(invariant(node, setter.name == '[]=', |
| 910 message: "Unexpected super setter '$setter'.")); | 858 message: "Unexpected super setter '$setter'.")); |
| 911 assert(invariant(node, getter.name == '[]', | 859 assert(invariant(node, getter.name == '[]', |
| 912 message: "Unexpected super getter '$getter'.")); | 860 message: "Unexpected super getter '$getter'.")); |
| 913 return new CompoundAccessSemantics( | 861 return new CompoundAccessSemantics( |
| 914 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter); | 862 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter); |
| 915 } else { | 863 } else { |
| 916 assert(invariant(node, setter.isSetter, | 864 assert(invariant(node, setter.isSetter, |
| 917 message: "Unexpected super setter '$setter'.")); | 865 message: "Unexpected super setter '$setter'.")); |
| 918 return new CompoundAccessSemantics( | 866 return new CompoundAccessSemantics( |
| 919 CompoundAccessKind.SUPER_METHOD_SETTER, getter, setter); | 867 CompoundAccessKind.SUPER_METHOD_SETTER, getter, setter); |
| 920 } | 868 } |
| 921 } | 869 } |
| 922 } | 870 } |
| 923 | 871 |
| 924 /// Compute the [AccessSemantics] corresponding to a local access of [target]. | 872 /// Compute the [AccessSemantics] corresponding to a local access of [target]. |
| 925 AccessSemantics computeLocalAccessSemantics(Spannable node, | 873 AccessSemantics computeLocalAccessSemantics( |
| 926 LocalElement target) { | 874 Spannable node, LocalElement target) { |
| 927 if (target.isParameter) { | 875 if (target.isParameter) { |
| 928 if (target.isFinal || target.isConst) { | 876 if (target.isFinal || target.isConst) { |
| 929 return new StaticAccess.finalParameter(target); | 877 return new StaticAccess.finalParameter(target); |
| 930 } else { | 878 } else { |
| 931 return new StaticAccess.parameter(target); | 879 return new StaticAccess.parameter(target); |
| 932 } | 880 } |
| 933 } else if (target.isVariable) { | 881 } else if (target.isVariable) { |
| 934 if (target.isFinal || target.isConst) { | 882 if (target.isFinal || target.isConst) { |
| 935 return new StaticAccess.finalLocalVariable(target); | 883 return new StaticAccess.finalLocalVariable(target); |
| 936 } else { | 884 } else { |
| 937 return new StaticAccess.localVariable(target); | 885 return new StaticAccess.localVariable(target); |
| 938 } | 886 } |
| 939 } else { | 887 } else { |
| 940 assert(invariant(node, target.isFunction, | 888 assert(invariant(node, target.isFunction, |
| 941 message: "Unexpected local target '$target'.")); | 889 message: "Unexpected local target '$target'.")); |
| 942 return new StaticAccess.localFunction(target); | 890 return new StaticAccess.localFunction(target); |
| 943 } | 891 } |
| 944 } | 892 } |
| 945 | 893 |
| 946 /// Compute the [AccessSemantics] corresponding to a static or toplevel access | 894 /// Compute the [AccessSemantics] corresponding to a static or toplevel access |
| 947 /// of [target]. | 895 /// of [target]. |
| 948 AccessSemantics computeStaticOrTopLevelAccessSemantics( | 896 AccessSemantics computeStaticOrTopLevelAccessSemantics( |
| 949 Spannable node, | 897 Spannable node, Element target) { |
| 950 Element target) { | |
| 951 | |
| 952 target = target.declaration; | 898 target = target.declaration; |
| 953 if (target.isMalformed) { | 899 if (target.isMalformed) { |
| 954 // This handles elements with parser errors. | 900 // This handles elements with parser errors. |
| 955 return new StaticAccess.unresolved(target); | 901 return new StaticAccess.unresolved(target); |
| 956 } | 902 } |
| 957 if (target.isStatic) { | 903 if (target.isStatic) { |
| 958 if (target.isGetter) { | 904 if (target.isGetter) { |
| 959 return new StaticAccess.staticGetter(target); | 905 return new StaticAccess.staticGetter(target); |
| 960 } else if (target.isSetter) { | 906 } else if (target.isSetter) { |
| 961 return new StaticAccess.staticSetter(target); | 907 return new StaticAccess.staticSetter(target); |
| 962 } else if (target.isField) { | 908 } else if (target.isField) { |
| 963 if (target.isFinal || target.isConst) { | 909 if (target.isFinal || target.isConst) { |
| 964 return new StaticAccess.finalStaticField(target); | 910 return new StaticAccess.finalStaticField(target); |
| 965 } else { | 911 } else { |
| 966 return new StaticAccess.staticField(target); | 912 return new StaticAccess.staticField(target); |
| 967 } | 913 } |
| 968 } else { | 914 } else { |
| 969 assert(invariant(node, target.isFunction, | 915 assert(invariant(node, target.isFunction, |
| 970 message: "Unexpected static target '$target'.")); | 916 message: "Unexpected static target '$target'.")); |
| 971 return new StaticAccess.staticMethod(target); | 917 return new StaticAccess.staticMethod(target); |
| 972 } | 918 } |
| 973 } else { | 919 } else { |
| 974 assert(invariant(node, target.isTopLevel, | 920 assert(invariant(node, target.isTopLevel, |
| 975 message: "Unexpected statically resolved target '$target'.")); | 921 message: "Unexpected statically resolved target '$target'.")); |
| 976 if (target.isGetter) { | 922 if (target.isGetter) { |
| 977 return new StaticAccess.topLevelGetter(target); | 923 return new StaticAccess.topLevelGetter(target); |
| 978 } else if (target.isSetter) { | 924 } else if (target.isSetter) { |
| 979 return new StaticAccess.topLevelSetter(target); | 925 return new StaticAccess.topLevelSetter(target); |
| 980 } else if (target.isField) { | 926 } else if (target.isField) { |
| 981 if (target.isFinal) { | 927 if (target.isFinal) { |
| 982 return new StaticAccess.finalTopLevelField(target); | 928 return new StaticAccess.finalTopLevelField(target); |
| 983 } else { | 929 } else { |
| 984 return new StaticAccess.topLevelField(target); | 930 return new StaticAccess.topLevelField(target); |
| 985 } | 931 } |
| 986 } else { | 932 } else { |
| 987 assert(invariant(node, target.isFunction, | 933 assert(invariant(node, target.isFunction, |
| 988 message: "Unexpected top level target '$target'.")); | 934 message: "Unexpected top level target '$target'.")); |
| 989 return new StaticAccess.topLevelMethod(target); | 935 return new StaticAccess.topLevelMethod(target); |
| 990 } | 936 } |
| 991 } | 937 } |
| 992 } | 938 } |
| 993 | 939 |
| 994 /// Compute the [AccessSemantics] for accessing the name of [selector] on the | 940 /// Compute the [AccessSemantics] for accessing the name of [selector] on the |
| 995 /// super class. | 941 /// super class. |
| 996 /// | 942 /// |
| 997 /// If no matching super member is found and error is reported and | 943 /// If no matching super member is found and error is reported and |
| 998 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName] | 944 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName] |
| 999 /// is provided, the [AccessSemantics] corresponding to the alternate name is | 945 /// is provided, the [AccessSemantics] corresponding to the alternate name is |
| 1000 /// returned. For instance, the access of a super setter for an unresolved | 946 /// returned. For instance, the access of a super setter for an unresolved |
| 1001 /// getter: | 947 /// getter: |
| 1002 /// | 948 /// |
| 1003 /// class Super { | 949 /// class Super { |
| 1004 /// set name(_) {} | 950 /// set name(_) {} |
| 1005 /// } | 951 /// } |
| 1006 /// class Sub extends Super { | 952 /// class Sub extends Super { |
| 1007 /// foo => super.name; // Access to the setter. | 953 /// foo => super.name; // Access to the setter. |
| 1008 /// } | 954 /// } |
| 1009 /// | 955 /// |
| 1010 AccessSemantics computeSuperAccessSemanticsForSelector( | 956 AccessSemantics computeSuperAccessSemanticsForSelector( |
| 1011 Spannable node, | 957 Spannable node, Selector selector, |
| 1012 Selector selector, | |
| 1013 {Name alternateName}) { | 958 {Name alternateName}) { |
| 1014 | |
| 1015 Name name = selector.memberName; | 959 Name name = selector.memberName; |
| 1016 // TODO(johnniwinther): Ensure correct behavior if currentClass is a | 960 // TODO(johnniwinther): Ensure correct behavior if currentClass is a |
| 1017 // patch. | 961 // patch. |
| 1018 Element target = currentClass.lookupSuperByName(name); | 962 Element target = currentClass.lookupSuperByName(name); |
| 1019 // [target] may be null which means invoking noSuchMethod on super. | 963 // [target] may be null which means invoking noSuchMethod on super. |
| 1020 if (target == null) { | 964 if (target == null) { |
| 1021 if (alternateName != null) { | 965 if (alternateName != null) { |
| 1022 target = currentClass.lookupSuperByName(alternateName); | 966 target = currentClass.lookupSuperByName(alternateName); |
| 1023 } | 967 } |
| 1024 Element error; | 968 Element error; |
| 1025 if (selector.isSetter) { | 969 if (selector.isSetter) { |
| 1026 error = reportAndCreateErroneousElement( | 970 error = reportAndCreateErroneousElement( |
| 1027 node, name.text, MessageKind.UNDEFINED_SUPER_SETTER, | 971 node, |
| 1028 {'className': currentClass.name, 'memberName': name}); | 972 name.text, |
| 973 MessageKind.UNDEFINED_SUPER_SETTER, |
| 974 {'className': currentClass.name, 'memberName': name}); |
| 1029 } else { | 975 } else { |
| 1030 error = reportAndCreateErroneousElement( | 976 error = reportAndCreateErroneousElement( |
| 1031 node, name.text, MessageKind.NO_SUCH_SUPER_MEMBER, | 977 node, |
| 1032 {'className': currentClass.name, 'memberName': name}); | 978 name.text, |
| 979 MessageKind.NO_SUCH_SUPER_MEMBER, |
| 980 {'className': currentClass.name, 'memberName': name}); |
| 1033 } | 981 } |
| 1034 if (target == null) { | 982 if (target == null) { |
| 1035 // If a setter wasn't resolved, use the [ErroneousElement]. | 983 // If a setter wasn't resolved, use the [ErroneousElement]. |
| 1036 target = error; | 984 target = error; |
| 1037 } | 985 } |
| 1038 // We still need to register the invocation, because we might | 986 // We still need to register the invocation, because we might |
| 1039 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. | 987 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. |
| 1040 registry.registerDynamicUse(new DynamicUse(selector, null)); | 988 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 1041 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); | 989 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
| 1042 } | 990 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1053 /// getter: | 1001 /// getter: |
| 1054 /// | 1002 /// |
| 1055 /// class Super { | 1003 /// class Super { |
| 1056 /// set name(_) {} | 1004 /// set name(_) {} |
| 1057 /// } | 1005 /// } |
| 1058 /// class Sub extends Super { | 1006 /// class Sub extends Super { |
| 1059 /// foo => super.name; // Access to the setter. | 1007 /// foo => super.name; // Access to the setter. |
| 1060 /// } | 1008 /// } |
| 1061 /// | 1009 /// |
| 1062 AccessSemantics computeSuperAccessSemanticsForSelectors( | 1010 AccessSemantics computeSuperAccessSemanticsForSelectors( |
| 1063 Spannable node, | 1011 Spannable node, Selector getterSelector, Selector setterSelector, |
| 1064 Selector getterSelector, | |
| 1065 Selector setterSelector, | |
| 1066 {bool isIndex: false}) { | 1012 {bool isIndex: false}) { |
| 1067 bool getterError = false; | 1013 bool getterError = false; |
| 1068 bool setterError = false; | 1014 bool setterError = false; |
| 1069 | 1015 |
| 1070 // TODO(johnniwinther): Ensure correct behavior if currentClass is a | 1016 // TODO(johnniwinther): Ensure correct behavior if currentClass is a |
| 1071 // patch. | 1017 // patch. |
| 1072 Element getter = currentClass.lookupSuperByName(getterSelector.memberName); | 1018 Element getter = currentClass.lookupSuperByName(getterSelector.memberName); |
| 1073 // [target] may be null which means invoking noSuchMethod on super. | 1019 // [target] may be null which means invoking noSuchMethod on super. |
| 1074 if (getter == null) { | 1020 if (getter == null) { |
| 1075 getter = reportAndCreateErroneousElement( | 1021 getter = reportAndCreateErroneousElement( |
| 1076 node, getterSelector.name, MessageKind.NO_SUCH_SUPER_MEMBER, | 1022 node, |
| 1023 getterSelector.name, |
| 1024 MessageKind.NO_SUCH_SUPER_MEMBER, |
| 1077 {'className': currentClass.name, 'memberName': getterSelector.name}); | 1025 {'className': currentClass.name, 'memberName': getterSelector.name}); |
| 1078 getterError = true; | 1026 getterError = true; |
| 1079 } | 1027 } |
| 1080 Element setter = currentClass.lookupSuperByName(setterSelector.memberName); | 1028 Element setter = currentClass.lookupSuperByName(setterSelector.memberName); |
| 1081 // [target] may be null which means invoking noSuchMethod on super. | 1029 // [target] may be null which means invoking noSuchMethod on super. |
| 1082 if (setter == null) { | 1030 if (setter == null) { |
| 1083 setter = reportAndCreateErroneousElement( | 1031 setter = reportAndCreateErroneousElement( |
| 1084 node, setterSelector.name, MessageKind.NO_SUCH_SUPER_MEMBER, | 1032 node, |
| 1033 setterSelector.name, |
| 1034 MessageKind.NO_SUCH_SUPER_MEMBER, |
| 1085 {'className': currentClass.name, 'memberName': setterSelector.name}); | 1035 {'className': currentClass.name, 'memberName': setterSelector.name}); |
| 1086 setterError = true; | 1036 setterError = true; |
| 1087 } else if (getter == setter) { | 1037 } else if (getter == setter) { |
| 1088 if (setter.isFunction) { | 1038 if (setter.isFunction) { |
| 1089 setter = reportAndCreateErroneousElement( | 1039 setter = reportAndCreateErroneousElement( |
| 1090 node, setterSelector.name, | 1040 node, setterSelector.name, MessageKind.ASSIGNING_METHOD_IN_SUPER, { |
| 1091 MessageKind.ASSIGNING_METHOD_IN_SUPER, | 1041 'superclassName': setter.enclosingClass.name, |
| 1092 {'superclassName': setter.enclosingClass.name, | 1042 'name': setterSelector.name |
| 1093 'name': setterSelector.name}); | 1043 }); |
| 1094 setterError = true; | 1044 setterError = true; |
| 1095 } else if (setter.isField && setter.isFinal) { | 1045 } else if (setter.isField && setter.isFinal) { |
| 1096 setter = reportAndCreateErroneousElement( | 1046 setter = reportAndCreateErroneousElement(node, setterSelector.name, |
| 1097 node, setterSelector.name, | 1047 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, { |
| 1098 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 1048 'superclassName': setter.enclosingClass.name, |
| 1099 {'superclassName': setter.enclosingClass.name, | 1049 'name': setterSelector.name |
| 1100 'name': setterSelector.name}); | 1050 }); |
| 1101 setterError = true; | 1051 setterError = true; |
| 1102 } | 1052 } |
| 1103 } | 1053 } |
| 1104 if (getterError) { | 1054 if (getterError) { |
| 1105 // We still need to register the invocation, because we might | 1055 // We still need to register the invocation, because we might |
| 1106 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. | 1056 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. |
| 1107 registry.registerDynamicUse( | 1057 registry.registerDynamicUse(new DynamicUse(getterSelector, null)); |
| 1108 new DynamicUse(getterSelector, null)); | |
| 1109 } | 1058 } |
| 1110 if (setterError) { | 1059 if (setterError) { |
| 1111 // We still need to register the invocation, because we might | 1060 // We still need to register the invocation, because we might |
| 1112 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. | 1061 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. |
| 1113 registry.registerDynamicUse( | 1062 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
| 1114 new DynamicUse(setterSelector, null)); | |
| 1115 } | 1063 } |
| 1116 if (getterError || setterError) { | 1064 if (getterError || setterError) { |
| 1117 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); | 1065 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
| 1118 } | 1066 } |
| 1119 return computeCompoundSuperAccessSemantics( | 1067 return computeCompoundSuperAccessSemantics(node, getter, setter, |
| 1120 node, getter, setter, isIndex: isIndex); | 1068 isIndex: isIndex); |
| 1121 } | 1069 } |
| 1122 | 1070 |
| 1123 /// Resolve [node] as a subexpression that is _not_ the prefix of a member | 1071 /// Resolve [node] as a subexpression that is _not_ the prefix of a member |
| 1124 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`. | 1072 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`. |
| 1125 ResolutionResult visitExpression(Node node) { | 1073 ResolutionResult visitExpression(Node node) { |
| 1126 bool oldSendIsMemberAccess = sendIsMemberAccess; | 1074 bool oldSendIsMemberAccess = sendIsMemberAccess; |
| 1127 sendIsMemberAccess = false; | 1075 sendIsMemberAccess = false; |
| 1128 ResolutionResult result = visit(node); | 1076 ResolutionResult result = visit(node); |
| 1129 sendIsMemberAccess = oldSendIsMemberAccess; | 1077 sendIsMemberAccess = oldSendIsMemberAccess; |
| 1130 return result; | 1078 return result; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1207 registry.setSelector(node, selector); | 1155 registry.setSelector(node, selector); |
| 1208 | 1156 |
| 1209 AccessSemantics semantics; | 1157 AccessSemantics semantics; |
| 1210 if (node.isSuperCall) { | 1158 if (node.isSuperCall) { |
| 1211 semantics = checkSuperAccess(node); | 1159 semantics = checkSuperAccess(node); |
| 1212 if (semantics == null) { | 1160 if (semantics == null) { |
| 1213 semantics = computeSuperAccessSemanticsForSelector(node, selector); | 1161 semantics = computeSuperAccessSemanticsForSelector(node, selector); |
| 1214 // TODO(johnniwinther): Add information to [AccessSemantics] about | 1162 // TODO(johnniwinther): Add information to [AccessSemantics] about |
| 1215 // whether it is erroneous. | 1163 // whether it is erroneous. |
| 1216 if (semantics.kind == AccessKind.SUPER_METHOD) { | 1164 if (semantics.kind == AccessKind.SUPER_METHOD) { |
| 1217 registry.registerStaticUse( | 1165 registry.registerStaticUse(new StaticUse.superInvoke( |
| 1218 new StaticUse.superInvoke( | 1166 semantics.element.declaration, selector.callStructure)); |
| 1219 semantics.element.declaration, | |
| 1220 selector.callStructure)); | |
| 1221 } | 1167 } |
| 1222 // TODO(23998): Remove this when all information goes through | 1168 // TODO(23998): Remove this when all information goes through |
| 1223 // the [SendStructure]. | 1169 // the [SendStructure]. |
| 1224 registry.useElement(node, semantics.element); | 1170 registry.useElement(node, semantics.element); |
| 1225 } | 1171 } |
| 1226 } else { | 1172 } else { |
| 1227 ResolutionResult expressionResult = visitExpression(expression); | 1173 ResolutionResult expressionResult = visitExpression(expression); |
| 1228 semantics = const DynamicAccess.expression(); | 1174 semantics = const DynamicAccess.expression(); |
| 1229 registry.registerDynamicUse(new DynamicUse(selector, null)); | 1175 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 1230 | 1176 |
| 1231 if (expressionResult.isConstant) { | 1177 if (expressionResult.isConstant) { |
| 1232 bool isValidConstant; | 1178 bool isValidConstant; |
| 1233 ConstantExpression expressionConstant = expressionResult.constant; | 1179 ConstantExpression expressionConstant = expressionResult.constant; |
| 1234 DartType knownExpressionType = | 1180 DartType knownExpressionType = |
| 1235 expressionConstant.getKnownType(coreTypes); | 1181 expressionConstant.getKnownType(coreTypes); |
| 1236 switch (operator.kind) { | 1182 switch (operator.kind) { |
| 1237 case UnaryOperatorKind.COMPLEMENT: | 1183 case UnaryOperatorKind.COMPLEMENT: |
| 1238 isValidConstant = | 1184 isValidConstant = knownExpressionType == coreTypes.intType; |
| 1239 knownExpressionType == coreTypes.intType; | |
| 1240 break; | 1185 break; |
| 1241 case UnaryOperatorKind.NEGATE: | 1186 case UnaryOperatorKind.NEGATE: |
| 1242 isValidConstant = | 1187 isValidConstant = knownExpressionType == coreTypes.intType || |
| 1243 knownExpressionType == coreTypes.intType || | |
| 1244 knownExpressionType == coreTypes.doubleType; | 1188 knownExpressionType == coreTypes.doubleType; |
| 1245 break; | 1189 break; |
| 1246 case UnaryOperatorKind.NOT: | 1190 case UnaryOperatorKind.NOT: |
| 1247 reporter.internalError(node, | 1191 reporter.internalError( |
| 1248 "Unexpected user definable unary operator: $operator"); | 1192 node, "Unexpected user definable unary operator: $operator"); |
| 1249 } | 1193 } |
| 1250 if (isValidConstant) { | 1194 if (isValidConstant) { |
| 1251 // TODO(johnniwinther): Handle potentially invalid constant | 1195 // TODO(johnniwinther): Handle potentially invalid constant |
| 1252 // expressions. | 1196 // expressions. |
| 1253 ConstantExpression constant = | 1197 ConstantExpression constant = |
| 1254 new UnaryConstantExpression(operator, expressionConstant); | 1198 new UnaryConstantExpression(operator, expressionConstant); |
| 1255 registry.setConstant(node, constant); | 1199 registry.setConstant(node, constant); |
| 1256 result = new ConstantResult(node, constant); | 1200 result = new ConstantResult(node, constant); |
| 1257 } | 1201 } |
| 1258 } | 1202 } |
| 1259 } | 1203 } |
| 1260 if (semantics != null) { | 1204 if (semantics != null) { |
| 1261 registry.registerSendStructure(node, | 1205 registry.registerSendStructure( |
| 1262 new UnaryStructure(semantics, operator)); | 1206 node, new UnaryStructure(semantics, operator)); |
| 1263 } | 1207 } |
| 1264 return result; | 1208 return result; |
| 1265 } | 1209 } |
| 1266 | 1210 |
| 1267 /// Handle a not expression, like `!a`. | 1211 /// Handle a not expression, like `!a`. |
| 1268 ResolutionResult handleNot(Send node, UnaryOperator operator) { | 1212 ResolutionResult handleNot(Send node, UnaryOperator operator) { |
| 1269 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); | 1213 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); |
| 1270 | 1214 |
| 1271 Node expression = node.receiver; | 1215 Node expression = node.receiver; |
| 1272 ResolutionResult result = visitExpression(expression); | 1216 ResolutionResult result = visitExpression(expression); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1296 doInPromotionScope(right, () => visitExpression(right)); | 1240 doInPromotionScope(right, () => visitExpression(right)); |
| 1297 registry.registerSendStructure(node, const LogicalAndStructure()); | 1241 registry.registerSendStructure(node, const LogicalAndStructure()); |
| 1298 | 1242 |
| 1299 if (leftResult.isConstant && rightResult.isConstant) { | 1243 if (leftResult.isConstant && rightResult.isConstant) { |
| 1300 ConstantExpression leftConstant = leftResult.constant; | 1244 ConstantExpression leftConstant = leftResult.constant; |
| 1301 ConstantExpression rightConstant = rightResult.constant; | 1245 ConstantExpression rightConstant = rightResult.constant; |
| 1302 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && | 1246 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && |
| 1303 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { | 1247 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
| 1304 // TODO(johnniwinther): Handle potentially invalid constant expressions. | 1248 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
| 1305 ConstantExpression constant = new BinaryConstantExpression( | 1249 ConstantExpression constant = new BinaryConstantExpression( |
| 1306 leftConstant, | 1250 leftConstant, BinaryOperator.LOGICAL_AND, rightConstant); |
| 1307 BinaryOperator.LOGICAL_AND, | |
| 1308 rightConstant); | |
| 1309 registry.setConstant(node, constant); | 1251 registry.setConstant(node, constant); |
| 1310 return new ConstantResult(node, constant); | 1252 return new ConstantResult(node, constant); |
| 1311 } | 1253 } |
| 1312 } | 1254 } |
| 1313 | 1255 |
| 1314 return const NoneResult(); | 1256 return const NoneResult(); |
| 1315 } | 1257 } |
| 1316 | 1258 |
| 1317 /// Handle a logical or expression, like `a || b`. | 1259 /// Handle a logical or expression, like `a || b`. |
| 1318 ResolutionResult handleLogicalOr(Send node) { | 1260 ResolutionResult handleLogicalOr(Send node) { |
| 1319 Node left = node.receiver; | 1261 Node left = node.receiver; |
| 1320 Node right = node.arguments.head; | 1262 Node right = node.arguments.head; |
| 1321 ResolutionResult leftResult = visitExpression(left); | 1263 ResolutionResult leftResult = visitExpression(left); |
| 1322 ResolutionResult rightResult = visitExpression(right); | 1264 ResolutionResult rightResult = visitExpression(right); |
| 1323 registry.registerSendStructure(node, const LogicalOrStructure()); | 1265 registry.registerSendStructure(node, const LogicalOrStructure()); |
| 1324 | 1266 |
| 1325 if (leftResult.isConstant && rightResult.isConstant) { | 1267 if (leftResult.isConstant && rightResult.isConstant) { |
| 1326 ConstantExpression leftConstant = leftResult.constant; | 1268 ConstantExpression leftConstant = leftResult.constant; |
| 1327 ConstantExpression rightConstant = rightResult.constant; | 1269 ConstantExpression rightConstant = rightResult.constant; |
| 1328 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && | 1270 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && |
| 1329 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { | 1271 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
| 1330 // TODO(johnniwinther): Handle potentially invalid constant expressions. | 1272 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
| 1331 ConstantExpression constant = new BinaryConstantExpression( | 1273 ConstantExpression constant = new BinaryConstantExpression( |
| 1332 leftConstant, | 1274 leftConstant, BinaryOperator.LOGICAL_OR, rightConstant); |
| 1333 BinaryOperator.LOGICAL_OR, | |
| 1334 rightConstant); | |
| 1335 registry.setConstant(node, constant); | 1275 registry.setConstant(node, constant); |
| 1336 return new ConstantResult(node, constant); | 1276 return new ConstantResult(node, constant); |
| 1337 } | 1277 } |
| 1338 } | 1278 } |
| 1339 return const NoneResult(); | 1279 return const NoneResult(); |
| 1340 } | 1280 } |
| 1341 | 1281 |
| 1342 /// Handle an if-null expression, like `a ?? b`. | 1282 /// Handle an if-null expression, like `a ?? b`. |
| 1343 ResolutionResult handleIfNull(Send node) { | 1283 ResolutionResult handleIfNull(Send node) { |
| 1344 Node left = node.receiver; | 1284 Node left = node.receiver; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1359 } else { | 1299 } else { |
| 1360 visitExpression(left); | 1300 visitExpression(left); |
| 1361 } | 1301 } |
| 1362 visitExpression(right); | 1302 visitExpression(right); |
| 1363 registry.registerSendStructure(node, const InvalidBinaryStructure()); | 1303 registry.registerSendStructure(node, const InvalidBinaryStructure()); |
| 1364 return const NoneResult(); | 1304 return const NoneResult(); |
| 1365 } | 1305 } |
| 1366 | 1306 |
| 1367 /// Handle the binary expression of a user definable binary [operator], like | 1307 /// Handle the binary expression of a user definable binary [operator], like |
| 1368 /// `a + b`, `super + b`, `a == b` and `a != b`. | 1308 /// `a + b`, `super + b`, `a == b` and `a != b`. |
| 1369 ResolutionResult handleUserDefinableBinary(Send node, | 1309 ResolutionResult handleUserDefinableBinary( |
| 1370 BinaryOperator operator) { | 1310 Send node, BinaryOperator operator) { |
| 1371 ResolutionResult result = const NoneResult(); | 1311 ResolutionResult result = const NoneResult(); |
| 1372 Node left = node.receiver; | 1312 Node left = node.receiver; |
| 1373 Node right = node.arguments.head; | 1313 Node right = node.arguments.head; |
| 1374 AccessSemantics semantics; | 1314 AccessSemantics semantics; |
| 1375 Selector selector; | 1315 Selector selector; |
| 1376 if (operator.kind == BinaryOperatorKind.INDEX) { | 1316 if (operator.kind == BinaryOperatorKind.INDEX) { |
| 1377 selector = new Selector.index(); | 1317 selector = new Selector.index(); |
| 1378 } else { | 1318 } else { |
| 1379 selector = new Selector.binaryOperator(operator.selectorName); | 1319 selector = new Selector.binaryOperator(operator.selectorName); |
| 1380 } | 1320 } |
| 1381 // TODO(23998): Remove this when all information goes through the | 1321 // TODO(23998): Remove this when all information goes through the |
| 1382 // [SendStructure]. | 1322 // [SendStructure]. |
| 1383 registry.setSelector(node, selector); | 1323 registry.setSelector(node, selector); |
| 1384 | 1324 |
| 1385 if (node.isSuperCall) { | 1325 if (node.isSuperCall) { |
| 1386 semantics = checkSuperAccess(node); | 1326 semantics = checkSuperAccess(node); |
| 1387 if (semantics == null) { | 1327 if (semantics == null) { |
| 1388 semantics = computeSuperAccessSemanticsForSelector(node, selector); | 1328 semantics = computeSuperAccessSemanticsForSelector(node, selector); |
| 1389 // TODO(johnniwinther): Add information to [AccessSemantics] about | 1329 // TODO(johnniwinther): Add information to [AccessSemantics] about |
| 1390 // whether it is erroneous. | 1330 // whether it is erroneous. |
| 1391 if (semantics.kind == AccessKind.SUPER_METHOD) { | 1331 if (semantics.kind == AccessKind.SUPER_METHOD) { |
| 1392 registry.registerStaticUse( | 1332 registry.registerStaticUse(new StaticUse.superInvoke( |
| 1393 new StaticUse.superInvoke( | 1333 semantics.element.declaration, selector.callStructure)); |
| 1394 semantics.element.declaration, | |
| 1395 selector.callStructure)); | |
| 1396 } | 1334 } |
| 1397 // TODO(23998): Remove this when all information goes through | 1335 // TODO(23998): Remove this when all information goes through |
| 1398 // the [SendStructure]. | 1336 // the [SendStructure]. |
| 1399 registry.useElement(node, semantics.element); | 1337 registry.useElement(node, semantics.element); |
| 1400 } | 1338 } |
| 1401 visitExpression(right); | 1339 visitExpression(right); |
| 1402 } else { | 1340 } else { |
| 1403 ResolutionResult leftResult = visitExpression(left); | 1341 ResolutionResult leftResult = visitExpression(left); |
| 1404 ResolutionResult rightResult = visitExpression(right); | 1342 ResolutionResult rightResult = visitExpression(right); |
| 1405 registry.registerDynamicUse(new DynamicUse(selector, null)); | 1343 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 1406 semantics = const DynamicAccess.expression(); | 1344 semantics = const DynamicAccess.expression(); |
| 1407 | 1345 |
| 1408 if (leftResult.isConstant && rightResult.isConstant) { | 1346 if (leftResult.isConstant && rightResult.isConstant) { |
| 1409 bool isValidConstant; | 1347 bool isValidConstant; |
| 1410 ConstantExpression leftConstant = leftResult.constant; | 1348 ConstantExpression leftConstant = leftResult.constant; |
| 1411 ConstantExpression rightConstant = rightResult.constant; | 1349 ConstantExpression rightConstant = rightResult.constant; |
| 1412 DartType knownLeftType = leftConstant.getKnownType(coreTypes); | 1350 DartType knownLeftType = leftConstant.getKnownType(coreTypes); |
| 1413 DartType knownRightType = rightConstant.getKnownType(coreTypes); | 1351 DartType knownRightType = rightConstant.getKnownType(coreTypes); |
| 1414 switch (operator.kind) { | 1352 switch (operator.kind) { |
| 1415 case BinaryOperatorKind.EQ: | 1353 case BinaryOperatorKind.EQ: |
| 1416 case BinaryOperatorKind.NOT_EQ: | 1354 case BinaryOperatorKind.NOT_EQ: |
| 1417 isValidConstant = | 1355 isValidConstant = (knownLeftType == coreTypes.intType || |
| 1418 (knownLeftType == coreTypes.intType || | 1356 knownLeftType == coreTypes.doubleType || |
| 1419 knownLeftType == coreTypes.doubleType || | 1357 knownLeftType == coreTypes.stringType || |
| 1420 knownLeftType == coreTypes.stringType || | 1358 knownLeftType == coreTypes.boolType || |
| 1421 knownLeftType == coreTypes.boolType || | 1359 knownLeftType == coreTypes.nullType) && |
| 1422 knownLeftType == coreTypes.nullType) && | |
| 1423 (knownRightType == coreTypes.intType || | 1360 (knownRightType == coreTypes.intType || |
| 1424 knownRightType == coreTypes.doubleType || | 1361 knownRightType == coreTypes.doubleType || |
| 1425 knownRightType == coreTypes.stringType || | 1362 knownRightType == coreTypes.stringType || |
| 1426 knownRightType == coreTypes.boolType || | 1363 knownRightType == coreTypes.boolType || |
| 1427 knownRightType == coreTypes.nullType); | 1364 knownRightType == coreTypes.nullType); |
| 1428 break; | 1365 break; |
| 1429 case BinaryOperatorKind.ADD: | 1366 case BinaryOperatorKind.ADD: |
| 1430 isValidConstant = | 1367 isValidConstant = (knownLeftType == coreTypes.intType || |
| 1431 (knownLeftType == coreTypes.intType || | 1368 knownLeftType == coreTypes.doubleType || |
| 1432 knownLeftType == coreTypes.doubleType || | 1369 knownLeftType == coreTypes.stringType) && |
| 1433 knownLeftType == coreTypes.stringType) && | |
| 1434 (knownRightType == coreTypes.intType || | 1370 (knownRightType == coreTypes.intType || |
| 1435 knownRightType == coreTypes.doubleType || | 1371 knownRightType == coreTypes.doubleType || |
| 1436 knownRightType == coreTypes.stringType); | 1372 knownRightType == coreTypes.stringType); |
| 1437 break; | 1373 break; |
| 1438 case BinaryOperatorKind.SUB: | 1374 case BinaryOperatorKind.SUB: |
| 1439 case BinaryOperatorKind.MUL: | 1375 case BinaryOperatorKind.MUL: |
| 1440 case BinaryOperatorKind.DIV: | 1376 case BinaryOperatorKind.DIV: |
| 1441 case BinaryOperatorKind.IDIV: | 1377 case BinaryOperatorKind.IDIV: |
| 1442 case BinaryOperatorKind.MOD: | 1378 case BinaryOperatorKind.MOD: |
| 1443 case BinaryOperatorKind.GTEQ: | 1379 case BinaryOperatorKind.GTEQ: |
| 1444 case BinaryOperatorKind.GT: | 1380 case BinaryOperatorKind.GT: |
| 1445 case BinaryOperatorKind.LTEQ: | 1381 case BinaryOperatorKind.LTEQ: |
| 1446 case BinaryOperatorKind.LT: | 1382 case BinaryOperatorKind.LT: |
| 1447 isValidConstant = | 1383 isValidConstant = (knownLeftType == coreTypes.intType || |
| 1448 (knownLeftType == coreTypes.intType || | 1384 knownLeftType == coreTypes.doubleType) && |
| 1449 knownLeftType == coreTypes.doubleType) && | |
| 1450 (knownRightType == coreTypes.intType || | 1385 (knownRightType == coreTypes.intType || |
| 1451 knownRightType == coreTypes.doubleType); | 1386 knownRightType == coreTypes.doubleType); |
| 1452 break; | 1387 break; |
| 1453 case BinaryOperatorKind.SHL: | 1388 case BinaryOperatorKind.SHL: |
| 1454 case BinaryOperatorKind.SHR: | 1389 case BinaryOperatorKind.SHR: |
| 1455 case BinaryOperatorKind.AND: | 1390 case BinaryOperatorKind.AND: |
| 1456 case BinaryOperatorKind.OR: | 1391 case BinaryOperatorKind.OR: |
| 1457 case BinaryOperatorKind.XOR: | 1392 case BinaryOperatorKind.XOR: |
| 1458 isValidConstant = | 1393 isValidConstant = knownLeftType == coreTypes.intType && |
| 1459 knownLeftType == coreTypes.intType && | |
| 1460 knownRightType == coreTypes.intType; | 1394 knownRightType == coreTypes.intType; |
| 1461 break; | 1395 break; |
| 1462 case BinaryOperatorKind.INDEX: | 1396 case BinaryOperatorKind.INDEX: |
| 1463 isValidConstant = false; | 1397 isValidConstant = false; |
| 1464 break; | 1398 break; |
| 1465 case BinaryOperatorKind.LOGICAL_AND: | 1399 case BinaryOperatorKind.LOGICAL_AND: |
| 1466 case BinaryOperatorKind.LOGICAL_OR: | 1400 case BinaryOperatorKind.LOGICAL_OR: |
| 1467 case BinaryOperatorKind.IF_NULL: | 1401 case BinaryOperatorKind.IF_NULL: |
| 1468 reporter.internalError( | 1402 reporter.internalError( |
| 1469 node, "Unexpected binary operator '${operator}'."); | 1403 node, "Unexpected binary operator '${operator}'."); |
| 1470 break; | 1404 break; |
| 1471 } | 1405 } |
| 1472 if (isValidConstant) { | 1406 if (isValidConstant) { |
| 1473 // TODO(johnniwinther): Handle potentially invalid constant | 1407 // TODO(johnniwinther): Handle potentially invalid constant |
| 1474 // expressions. | 1408 // expressions. |
| 1475 ConstantExpression constant = new BinaryConstantExpression( | 1409 ConstantExpression constant = new BinaryConstantExpression( |
| 1476 leftResult.constant, | 1410 leftResult.constant, operator, rightResult.constant); |
| 1477 operator, | |
| 1478 rightResult.constant); | |
| 1479 registry.setConstant(node, constant); | 1411 registry.setConstant(node, constant); |
| 1480 result = new ConstantResult(node, constant); | 1412 result = new ConstantResult(node, constant); |
| 1481 } | 1413 } |
| 1482 } | 1414 } |
| 1483 } | 1415 } |
| 1484 | 1416 |
| 1485 if (semantics != null) { | 1417 if (semantics != null) { |
| 1486 // TODO(johnniwinther): Support invalid super access as an | 1418 // TODO(johnniwinther): Support invalid super access as an |
| 1487 // [AccessSemantics]. | 1419 // [AccessSemantics]. |
| 1488 SendStructure sendStructure; | 1420 SendStructure sendStructure; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1520 node, "Unexpected binary operator '${operator}'."); | 1452 node, "Unexpected binary operator '${operator}'."); |
| 1521 break; | 1453 break; |
| 1522 } | 1454 } |
| 1523 registry.registerSendStructure(node, sendStructure); | 1455 registry.registerSendStructure(node, sendStructure); |
| 1524 } | 1456 } |
| 1525 return result; | 1457 return result; |
| 1526 } | 1458 } |
| 1527 | 1459 |
| 1528 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. | 1460 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. |
| 1529 ResolutionResult handleExpressionInvoke(Send node) { | 1461 ResolutionResult handleExpressionInvoke(Send node) { |
| 1530 assert(invariant(node, node.isCall, | 1462 assert( |
| 1531 message: "Unexpected expression: $node")); | 1463 invariant(node, node.isCall, message: "Unexpected expression: $node")); |
| 1532 Node expression = node.selector; | 1464 Node expression = node.selector; |
| 1533 visitExpression(expression); | 1465 visitExpression(expression); |
| 1534 CallStructure callStructure = | 1466 CallStructure callStructure = |
| 1535 resolveArguments(node.argumentsNode).callStructure; | 1467 resolveArguments(node.argumentsNode).callStructure; |
| 1536 Selector selector = callStructure.callSelector; | 1468 Selector selector = callStructure.callSelector; |
| 1537 // TODO(23998): Remove this when all information goes through the | 1469 // TODO(23998): Remove this when all information goes through the |
| 1538 // [SendStructure]. | 1470 // [SendStructure]. |
| 1539 registry.setSelector(node, selector); | 1471 registry.setSelector(node, selector); |
| 1540 registry.registerDynamicUse(new DynamicUse(selector, null)); | 1472 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 1541 registry.registerSendStructure(node, | 1473 registry.registerSendStructure( |
| 1542 new InvokeStructure(const DynamicAccess.expression(), selector)); | 1474 node, new InvokeStructure(const DynamicAccess.expression(), selector)); |
| 1543 return const NoneResult(); | 1475 return const NoneResult(); |
| 1544 } | 1476 } |
| 1545 | 1477 |
| 1546 /// Handle access of a property of [name] on `this`, like `this.name` and | 1478 /// Handle access of a property of [name] on `this`, like `this.name` and |
| 1547 /// `this.name()`, or `name` and `name()` in instance context. | 1479 /// `this.name()`, or `name` and `name()` in instance context. |
| 1548 ResolutionResult handleThisPropertyAccess(Send node, Name name) { | 1480 ResolutionResult handleThisPropertyAccess(Send node, Name name) { |
| 1549 AccessSemantics semantics = new DynamicAccess.thisProperty(name); | 1481 AccessSemantics semantics = new DynamicAccess.thisProperty(name); |
| 1550 return handleDynamicAccessSemantics(node, name, semantics); | 1482 return handleDynamicAccessSemantics(node, name, semantics); |
| 1551 } | 1483 } |
| 1552 | 1484 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1563 ResolutionResult handleThisAccess(Send node) { | 1495 ResolutionResult handleThisAccess(Send node) { |
| 1564 if (node.isCall) { | 1496 if (node.isCall) { |
| 1565 CallStructure callStructure = | 1497 CallStructure callStructure = |
| 1566 resolveArguments(node.argumentsNode).callStructure; | 1498 resolveArguments(node.argumentsNode).callStructure; |
| 1567 Selector selector = callStructure.callSelector; | 1499 Selector selector = callStructure.callSelector; |
| 1568 // TODO(johnniwinther): Handle invalid this access as an | 1500 // TODO(johnniwinther): Handle invalid this access as an |
| 1569 // [AccessSemantics]. | 1501 // [AccessSemantics]. |
| 1570 AccessSemantics accessSemantics = checkThisAccess(node); | 1502 AccessSemantics accessSemantics = checkThisAccess(node); |
| 1571 if (accessSemantics == null) { | 1503 if (accessSemantics == null) { |
| 1572 accessSemantics = const DynamicAccess.thisAccess(); | 1504 accessSemantics = const DynamicAccess.thisAccess(); |
| 1573 registry.registerDynamicUse( | 1505 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 1574 new DynamicUse(selector, null)); | |
| 1575 } | 1506 } |
| 1576 registry.registerSendStructure(node, | 1507 registry.registerSendStructure( |
| 1577 new InvokeStructure(accessSemantics, selector)); | 1508 node, new InvokeStructure(accessSemantics, selector)); |
| 1578 // TODO(23998): Remove this when all information goes through | 1509 // TODO(23998): Remove this when all information goes through |
| 1579 // the [SendStructure]. | 1510 // the [SendStructure]. |
| 1580 registry.setSelector(node, selector); | 1511 registry.setSelector(node, selector); |
| 1581 return const NoneResult(); | 1512 return const NoneResult(); |
| 1582 } else { | 1513 } else { |
| 1583 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. | 1514 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. |
| 1584 reporter.internalError( | 1515 reporter.internalError(node, "Unexpected node '$node'."); |
| 1585 node, "Unexpected node '$node'."); | |
| 1586 } | 1516 } |
| 1587 return const NoneResult(); | 1517 return const NoneResult(); |
| 1588 } | 1518 } |
| 1589 | 1519 |
| 1590 /// Handle access of a super property, like `super.foo` and `super.foo()`. | 1520 /// Handle access of a super property, like `super.foo` and `super.foo()`. |
| 1591 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { | 1521 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { |
| 1592 Element target; | 1522 Element target; |
| 1593 Selector selector; | 1523 Selector selector; |
| 1594 CallStructure callStructure; | 1524 CallStructure callStructure; |
| 1595 if (node.isCall) { | 1525 if (node.isCall) { |
| 1596 callStructure = resolveArguments(node.argumentsNode).callStructure; | 1526 callStructure = resolveArguments(node.argumentsNode).callStructure; |
| 1597 selector = new Selector.call(name, callStructure); | 1527 selector = new Selector.call(name, callStructure); |
| 1598 } else { | 1528 } else { |
| 1599 selector = new Selector.getter(name); | 1529 selector = new Selector.getter(name); |
| 1600 } | 1530 } |
| 1601 AccessSemantics semantics = checkSuperAccess(node); | 1531 AccessSemantics semantics = checkSuperAccess(node); |
| 1602 if (semantics == null) { | 1532 if (semantics == null) { |
| 1603 semantics = computeSuperAccessSemanticsForSelector( | 1533 semantics = computeSuperAccessSemanticsForSelector(node, selector, |
| 1604 node, selector, alternateName: name.setter); | 1534 alternateName: name.setter); |
| 1605 } | 1535 } |
| 1606 if (node.isCall) { | 1536 if (node.isCall) { |
| 1607 bool isIncompatibleInvoke = false; | 1537 bool isIncompatibleInvoke = false; |
| 1608 switch (semantics.kind) { | 1538 switch (semantics.kind) { |
| 1609 case AccessKind.SUPER_METHOD: | 1539 case AccessKind.SUPER_METHOD: |
| 1610 MethodElementX superMethod = semantics.element; | 1540 MethodElementX superMethod = semantics.element; |
| 1611 superMethod.computeType(resolution); | 1541 superMethod.computeType(resolution); |
| 1612 if (!callStructure.signatureApplies( | 1542 if (!callStructure.signatureApplies(superMethod.functionSignature)) { |
| 1613 superMethod.functionSignature)) { | |
| 1614 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1543 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 1615 registry.registerDynamicUse( | 1544 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 1616 new DynamicUse(selector, null)); | |
| 1617 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); | 1545 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
| 1618 isIncompatibleInvoke = true; | 1546 isIncompatibleInvoke = true; |
| 1619 } else { | 1547 } else { |
| 1620 registry.registerStaticUse( | 1548 registry.registerStaticUse( |
| 1621 new StaticUse.superInvoke(semantics.element, callStructure)); | 1549 new StaticUse.superInvoke(semantics.element, callStructure)); |
| 1622 } | 1550 } |
| 1623 break; | 1551 break; |
| 1624 case AccessKind.SUPER_FIELD: | 1552 case AccessKind.SUPER_FIELD: |
| 1625 case AccessKind.SUPER_FINAL_FIELD: | 1553 case AccessKind.SUPER_FINAL_FIELD: |
| 1626 case AccessKind.SUPER_GETTER: | 1554 case AccessKind.SUPER_GETTER: |
| 1627 registry.registerStaticUse( | 1555 registry.registerStaticUse(new StaticUse.superGet(semantics.element)); |
| 1628 new StaticUse.superGet(semantics.element)); | |
| 1629 selector = callStructure.callSelector; | 1556 selector = callStructure.callSelector; |
| 1630 registry.registerDynamicUse( | 1557 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 1631 new DynamicUse(selector, null)); | |
| 1632 break; | 1558 break; |
| 1633 case AccessKind.SUPER_SETTER: | 1559 case AccessKind.SUPER_SETTER: |
| 1634 case AccessKind.UNRESOLVED_SUPER: | 1560 case AccessKind.UNRESOLVED_SUPER: |
| 1635 // NoSuchMethod registered in [computeSuperSemantics]. | 1561 // NoSuchMethod registered in [computeSuperSemantics]. |
| 1636 break; | 1562 break; |
| 1637 case AccessKind.INVALID: | 1563 case AccessKind.INVALID: |
| 1638 // 'super' is not allowed. | 1564 // 'super' is not allowed. |
| 1639 break; | 1565 break; |
| 1640 default: | 1566 default: |
| 1641 reporter.internalError( | 1567 reporter.internalError( |
| 1642 node, "Unexpected super property access $semantics."); | 1568 node, "Unexpected super property access $semantics."); |
| 1643 break; | 1569 break; |
| 1644 } | 1570 } |
| 1645 registry.registerSendStructure(node, | 1571 registry.registerSendStructure( |
| 1572 node, |
| 1646 isIncompatibleInvoke | 1573 isIncompatibleInvoke |
| 1647 ? new IncompatibleInvokeStructure(semantics, selector) | 1574 ? new IncompatibleInvokeStructure(semantics, selector) |
| 1648 : new InvokeStructure(semantics, selector)); | 1575 : new InvokeStructure(semantics, selector)); |
| 1649 } else { | 1576 } else { |
| 1650 switch (semantics.kind) { | 1577 switch (semantics.kind) { |
| 1651 case AccessKind.SUPER_METHOD: | 1578 case AccessKind.SUPER_METHOD: |
| 1652 // TODO(johnniwinther): Method this should be registered as a | 1579 // TODO(johnniwinther): Method this should be registered as a |
| 1653 // closurization. | 1580 // closurization. |
| 1654 registry.registerStaticUse( | 1581 registry |
| 1655 new StaticUse.superTearOff(semantics.element)); | 1582 .registerStaticUse(new StaticUse.superTearOff(semantics.element)); |
| 1656 break; | 1583 break; |
| 1657 case AccessKind.SUPER_FIELD: | 1584 case AccessKind.SUPER_FIELD: |
| 1658 case AccessKind.SUPER_FINAL_FIELD: | 1585 case AccessKind.SUPER_FINAL_FIELD: |
| 1659 case AccessKind.SUPER_GETTER: | 1586 case AccessKind.SUPER_GETTER: |
| 1660 registry.registerStaticUse( | 1587 registry.registerStaticUse(new StaticUse.superGet(semantics.element)); |
| 1661 new StaticUse.superGet(semantics.element)); | |
| 1662 break; | 1588 break; |
| 1663 case AccessKind.SUPER_SETTER: | 1589 case AccessKind.SUPER_SETTER: |
| 1664 case AccessKind.UNRESOLVED_SUPER: | 1590 case AccessKind.UNRESOLVED_SUPER: |
| 1665 // NoSuchMethod registered in [computeSuperSemantics]. | 1591 // NoSuchMethod registered in [computeSuperSemantics]. |
| 1666 break; | 1592 break; |
| 1667 case AccessKind.INVALID: | 1593 case AccessKind.INVALID: |
| 1668 // 'super' is not allowed. | 1594 // 'super' is not allowed. |
| 1669 break; | 1595 break; |
| 1670 default: | 1596 default: |
| 1671 reporter.internalError( | 1597 reporter.internalError( |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1682 registry.setSelector(node, selector); | 1608 registry.setSelector(node, selector); |
| 1683 return const NoneResult(); | 1609 return const NoneResult(); |
| 1684 } | 1610 } |
| 1685 | 1611 |
| 1686 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`, | 1612 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`, |
| 1687 /// `a + b`, and `~a`. | 1613 /// `a + b`, and `~a`. |
| 1688 ResolutionResult handleOperatorSend(Send node) { | 1614 ResolutionResult handleOperatorSend(Send node) { |
| 1689 String operatorText = node.selector.asOperator().source; | 1615 String operatorText = node.selector.asOperator().source; |
| 1690 if (operatorText == 'is') { | 1616 if (operatorText == 'is') { |
| 1691 return handleIs(node); | 1617 return handleIs(node); |
| 1692 } else if (operatorText == 'as') { | 1618 } else if (operatorText == 'as') { |
| 1693 return handleAs(node); | 1619 return handleAs(node); |
| 1694 } else if (node.arguments.isEmpty) { | 1620 } else if (node.arguments.isEmpty) { |
| 1695 UnaryOperator operator = UnaryOperator.parse(operatorText); | 1621 UnaryOperator operator = UnaryOperator.parse(operatorText); |
| 1696 if (operator == null) { | 1622 if (operator == null) { |
| 1697 return handleUnresolvedUnary(node, operatorText); | 1623 return handleUnresolvedUnary(node, operatorText); |
| 1698 } else { | 1624 } else { |
| 1699 switch (operator.kind) { | 1625 switch (operator.kind) { |
| 1700 case UnaryOperatorKind.NOT: | 1626 case UnaryOperatorKind.NOT: |
| 1701 return handleNot(node, operator); | 1627 return handleNot(node, operator); |
| 1702 case UnaryOperatorKind.COMPLEMENT: | 1628 case UnaryOperatorKind.COMPLEMENT: |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1753 // a constructor. | 1679 // a constructor. |
| 1754 | 1680 |
| 1755 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1681 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| 1756 // try to resolve injected elements if [currentClass] is in the patch | 1682 // try to resolve injected elements if [currentClass] is in the patch |
| 1757 // library of [receiverClass]. | 1683 // library of [receiverClass]. |
| 1758 | 1684 |
| 1759 // TODO(karlklose): this should be reported by the caller of | 1685 // TODO(karlklose): this should be reported by the caller of |
| 1760 // [resolveSend] to select better warning messages for getters and | 1686 // [resolveSend] to select better warning messages for getters and |
| 1761 // setters. | 1687 // setters. |
| 1762 ErroneousElement error = reportAndCreateErroneousElement( | 1688 ErroneousElement error = reportAndCreateErroneousElement( |
| 1763 node, name.text, MessageKind.UNDEFINED_GETTER, | 1689 node, |
| 1690 name.text, |
| 1691 MessageKind.UNDEFINED_GETTER, |
| 1764 {'className': receiverClass.name, 'memberName': name.text}); | 1692 {'className': receiverClass.name, 'memberName': name.text}); |
| 1765 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1693 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
| 1766 // member access. | 1694 // member access. |
| 1767 return handleErroneousAccess( | 1695 return handleErroneousAccess( |
| 1768 node, name, new StaticAccess.unresolved(error)); | 1696 node, name, new StaticAccess.unresolved(error)); |
| 1769 } | 1697 } |
| 1770 | 1698 |
| 1771 /// Handle qualified update to an unresolved static class member, like | 1699 /// Handle qualified update to an unresolved static class member, like |
| 1772 /// `a.b = c` or `a.b++` where `a` is a class and `b` is unresolved. | 1700 /// `a.b = c` or `a.b++` where `a` is a class and `b` is unresolved. |
| 1773 ResolutionResult handleUnresolvedStaticMemberUpdate( | 1701 ResolutionResult handleUnresolvedStaticMemberUpdate( |
| 1774 SendSet node, Name name, ClassElement receiverClass) { | 1702 SendSet node, Name name, ClassElement receiverClass) { |
| 1775 // TODO(johnniwinther): Share code with [handleStaticInstanceMemberUpdate] | 1703 // TODO(johnniwinther): Share code with [handleStaticInstanceMemberUpdate] |
| 1776 // and [handlePrivateStaticMemberUpdate]. | 1704 // and [handlePrivateStaticMemberUpdate]. |
| 1777 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1705 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 1778 // TODO(johnniwinther): Produce a different error if [name] is resolves to | 1706 // TODO(johnniwinther): Produce a different error if [name] is resolves to |
| 1779 // a constructor. | 1707 // a constructor. |
| 1780 | 1708 |
| 1781 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1709 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| 1782 // try to resolve injected elements if [currentClass] is in the patch | 1710 // try to resolve injected elements if [currentClass] is in the patch |
| 1783 // library of [receiverClass]. | 1711 // library of [receiverClass]. |
| 1784 | 1712 |
| 1785 // TODO(johnniwinther): Produce a different error for complex update. | 1713 // TODO(johnniwinther): Produce a different error for complex update. |
| 1786 ErroneousElement error = reportAndCreateErroneousElement( | 1714 ErroneousElement error = reportAndCreateErroneousElement( |
| 1787 node, name.text, MessageKind.UNDEFINED_GETTER, | 1715 node, |
| 1716 name.text, |
| 1717 MessageKind.UNDEFINED_GETTER, |
| 1788 {'className': receiverClass.name, 'memberName': name.text}); | 1718 {'className': receiverClass.name, 'memberName': name.text}); |
| 1789 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1719 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
| 1790 // member access. | 1720 // member access. |
| 1791 return handleUpdate(node, name, new StaticAccess.unresolved(error)); | 1721 return handleUpdate(node, name, new StaticAccess.unresolved(error)); |
| 1792 } | 1722 } |
| 1793 | 1723 |
| 1794 /// Handle qualified access of an instance member, like `a.b` or `a.b()` where | 1724 /// Handle qualified access of an instance member, like `a.b` or `a.b()` where |
| 1795 /// `a` is a class and `b` is a non-static member. | 1725 /// `a` is a class and `b` is a non-static member. |
| 1796 ResolutionResult handleStaticInstanceMemberAccess( | 1726 ResolutionResult handleStaticInstanceMemberAccess( |
| 1797 Send node, Name name, ClassElement receiverClass, Element member) { | 1727 Send node, Name name, ClassElement receiverClass, Element member) { |
| 1798 | |
| 1799 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1728 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 1800 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1729 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| 1801 // try to resolve injected elements if [currentClass] is in the patch | 1730 // try to resolve injected elements if [currentClass] is in the patch |
| 1802 // library of [receiverClass]. | 1731 // library of [receiverClass]. |
| 1803 | 1732 |
| 1804 // TODO(karlklose): this should be reported by the caller of | 1733 // TODO(karlklose): this should be reported by the caller of |
| 1805 // [resolveSend] to select better warning messages for getters and | 1734 // [resolveSend] to select better warning messages for getters and |
| 1806 // setters. | 1735 // setters. |
| 1807 ErroneousElement error = reportAndCreateErroneousElement( | 1736 ErroneousElement error = reportAndCreateErroneousElement( |
| 1808 node, name.text, MessageKind.MEMBER_NOT_STATIC, | 1737 node, |
| 1738 name.text, |
| 1739 MessageKind.MEMBER_NOT_STATIC, |
| 1809 {'className': receiverClass.name, 'memberName': name}); | 1740 {'className': receiverClass.name, 'memberName': name}); |
| 1810 | 1741 |
| 1811 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed | 1742 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed |
| 1812 // instance members. | 1743 // instance members. |
| 1813 return handleErroneousAccess( | 1744 return handleErroneousAccess( |
| 1814 node, name, new StaticAccess.unresolved(error)); | 1745 node, name, new StaticAccess.unresolved(error)); |
| 1815 } | 1746 } |
| 1816 | 1747 |
| 1817 /// Handle qualified update of an instance member, like `a.b = c` or `a.b++` | 1748 /// Handle qualified update of an instance member, like `a.b = c` or `a.b++` |
| 1818 /// where `a` is a class and `b` is a non-static member. | 1749 /// where `a` is a class and `b` is a non-static member. |
| 1819 ResolutionResult handleStaticInstanceMemberUpdate( | 1750 ResolutionResult handleStaticInstanceMemberUpdate( |
| 1820 SendSet node, Name name, ClassElement receiverClass, Element member) { | 1751 SendSet node, Name name, ClassElement receiverClass, Element member) { |
| 1821 | |
| 1822 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1752 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 1823 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1753 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| 1824 // try to resolve injected elements if [currentClass] is in the patch | 1754 // try to resolve injected elements if [currentClass] is in the patch |
| 1825 // library of [receiverClass]. | 1755 // library of [receiverClass]. |
| 1826 | 1756 |
| 1827 // TODO(johnniwinther): Produce a different error for complex update. | 1757 // TODO(johnniwinther): Produce a different error for complex update. |
| 1828 ErroneousElement error = reportAndCreateErroneousElement( | 1758 ErroneousElement error = reportAndCreateErroneousElement( |
| 1829 node, name.text, MessageKind.MEMBER_NOT_STATIC, | 1759 node, |
| 1760 name.text, |
| 1761 MessageKind.MEMBER_NOT_STATIC, |
| 1830 {'className': receiverClass.name, 'memberName': name}); | 1762 {'className': receiverClass.name, 'memberName': name}); |
| 1831 | 1763 |
| 1832 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed | 1764 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed |
| 1833 // instance members. | 1765 // instance members. |
| 1834 return handleUpdate(node, name, new StaticAccess.unresolved(error)); | 1766 return handleUpdate(node, name, new StaticAccess.unresolved(error)); |
| 1835 } | 1767 } |
| 1836 | 1768 |
| 1837 /// Handle qualified access of an inaccessible private static class member, | 1769 /// Handle qualified access of an inaccessible private static class member, |
| 1838 /// like `a._b` or `a._b()` where `a` is class, `_b` is static member of `a` | 1770 /// like `a._b` or `a._b()` where `a` is class, `_b` is static member of `a` |
| 1839 /// but `a` is not defined in the current library. | 1771 /// but `a` is not defined in the current library. |
| 1840 ResolutionResult handlePrivateStaticMemberAccess( | 1772 ResolutionResult handlePrivateStaticMemberAccess( |
| 1841 Send node, Name name, ClassElement receiverClass, Element member) { | 1773 Send node, Name name, ClassElement receiverClass, Element member) { |
| 1842 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1774 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 1843 ErroneousElement error = reportAndCreateErroneousElement( | 1775 ErroneousElement error = reportAndCreateErroneousElement( |
| 1844 node, name.text, MessageKind.PRIVATE_ACCESS, | 1776 node, |
| 1845 {'libraryName': member.library.libraryOrScriptName, | 1777 name.text, |
| 1846 'name': name}); | 1778 MessageKind.PRIVATE_ACCESS, |
| 1779 {'libraryName': member.library.libraryOrScriptName, 'name': name}); |
| 1847 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1780 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
| 1848 // member access. | 1781 // member access. |
| 1849 return handleErroneousAccess( | 1782 return handleErroneousAccess( |
| 1850 node, name, new StaticAccess.unresolved(error)); | 1783 node, name, new StaticAccess.unresolved(error)); |
| 1851 } | 1784 } |
| 1852 | 1785 |
| 1853 /// Handle qualified update of an inaccessible private static class member, | 1786 /// Handle qualified update of an inaccessible private static class member, |
| 1854 /// like `a._b = c` or `a._b++` where `a` is class, `_b` is static member of | 1787 /// like `a._b = c` or `a._b++` where `a` is class, `_b` is static member of |
| 1855 /// `a` but `a` is not defined in the current library. | 1788 /// `a` but `a` is not defined in the current library. |
| 1856 ResolutionResult handlePrivateStaticMemberUpdate( | 1789 ResolutionResult handlePrivateStaticMemberUpdate( |
| 1857 SendSet node, Name name, ClassElement receiverClass, Element member) { | 1790 SendSet node, Name name, ClassElement receiverClass, Element member) { |
| 1858 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1791 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 1859 ErroneousElement error = reportAndCreateErroneousElement( | 1792 ErroneousElement error = reportAndCreateErroneousElement( |
| 1860 node, name.text, MessageKind.PRIVATE_ACCESS, | 1793 node, |
| 1861 {'libraryName': member.library.libraryOrScriptName, | 1794 name.text, |
| 1862 'name': name}); | 1795 MessageKind.PRIVATE_ACCESS, |
| 1796 {'libraryName': member.library.libraryOrScriptName, 'name': name}); |
| 1863 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1797 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
| 1864 // member access. | 1798 // member access. |
| 1865 return handleUpdate(node, name, new StaticAccess.unresolved(error)); | 1799 return handleUpdate(node, name, new StaticAccess.unresolved(error)); |
| 1866 } | 1800 } |
| 1867 | 1801 |
| 1868 /// Handle qualified access to a static member, like `a.b` or `a.b()` where | 1802 /// Handle qualified access to a static member, like `a.b` or `a.b()` where |
| 1869 /// `a` is a class and `b` is a static member of `a`. | 1803 /// `a` is a class and `b` is a static member of `a`. |
| 1870 ResolutionResult handleStaticMemberAccess( | 1804 ResolutionResult handleStaticMemberAccess( |
| 1871 Send node, Name memberName, ClassElement receiverClass) { | 1805 Send node, Name memberName, ClassElement receiverClass) { |
| 1872 String name = memberName.text; | 1806 String name = memberName.text; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1924 } | 1858 } |
| 1925 } | 1859 } |
| 1926 | 1860 |
| 1927 /// Handle access to a type literal of type variable [element]. Like `T` or | 1861 /// Handle access to a type literal of type variable [element]. Like `T` or |
| 1928 /// `T()` where 'T' is type variable. | 1862 /// `T()` where 'T' is type variable. |
| 1929 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the | 1863 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
| 1930 // the [GetStructure]. | 1864 // the [GetStructure]. |
| 1931 // TODO(johnniwinther): Remove [element] when it is no longer needed for | 1865 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
| 1932 // evaluating constants. | 1866 // evaluating constants. |
| 1933 ResolutionResult handleTypeVariableTypeLiteralAccess( | 1867 ResolutionResult handleTypeVariableTypeLiteralAccess( |
| 1934 Send node, | 1868 Send node, Name name, TypeVariableElement element) { |
| 1935 Name name, | |
| 1936 TypeVariableElement element) { | |
| 1937 AccessSemantics semantics; | 1869 AccessSemantics semantics; |
| 1938 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { | 1870 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { |
| 1939 // TODO(johnniwinther): Add another access semantics for this. | 1871 // TODO(johnniwinther): Add another access semantics for this. |
| 1940 ErroneousElement error = reportAndCreateErroneousElement( | 1872 ErroneousElement error = reportAndCreateErroneousElement( |
| 1941 node, name.text, | 1873 node, |
| 1874 name.text, |
| 1942 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 1875 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
| 1943 {'typeVariableName': name}, | 1876 {'typeVariableName': name}, |
| 1944 isError: true); | 1877 isError: true); |
| 1945 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 1878 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
| 1946 semantics = new StaticAccess.invalid(error); | 1879 semantics = new StaticAccess.invalid(error); |
| 1947 // TODO(johnniwinther): Clean up registration of elements and selectors | 1880 // TODO(johnniwinther): Clean up registration of elements and selectors |
| 1948 // for this case. | 1881 // for this case. |
| 1949 } else { | 1882 } else { |
| 1950 semantics = new StaticAccess.typeParameterTypeLiteral(element); | 1883 semantics = new StaticAccess.typeParameterTypeLiteral(element); |
| 1951 } | 1884 } |
| 1952 | 1885 |
| 1953 registry.useElement(node, element); | 1886 registry.useElement(node, element); |
| 1954 registry.registerTypeLiteral(node, element.type); | 1887 registry.registerTypeLiteral(node, element.type); |
| 1955 | 1888 |
| 1956 if (node.isCall) { | 1889 if (node.isCall) { |
| 1957 CallStructure callStructure = | 1890 CallStructure callStructure = |
| 1958 resolveArguments(node.argumentsNode).callStructure; | 1891 resolveArguments(node.argumentsNode).callStructure; |
| 1959 Selector selector = callStructure.callSelector; | 1892 Selector selector = callStructure.callSelector; |
| 1960 // TODO(23998): Remove this when all information goes through | 1893 // TODO(23998): Remove this when all information goes through |
| 1961 // the [SendStructure]. | 1894 // the [SendStructure]. |
| 1962 registry.setSelector(node, selector); | 1895 registry.setSelector(node, selector); |
| 1963 | 1896 |
| 1964 registry.registerSendStructure(node, | 1897 registry.registerSendStructure( |
| 1965 new InvokeStructure(semantics, selector)); | 1898 node, new InvokeStructure(semantics, selector)); |
| 1966 } else { | 1899 } else { |
| 1967 // TODO(johnniwinther): Avoid the need for a [Selector] here. | 1900 // TODO(johnniwinther): Avoid the need for a [Selector] here. |
| 1968 registry.registerSendStructure(node, new GetStructure(semantics)); | 1901 registry.registerSendStructure(node, new GetStructure(semantics)); |
| 1969 } | 1902 } |
| 1970 return const NoneResult(); | 1903 return const NoneResult(); |
| 1971 } | 1904 } |
| 1972 | 1905 |
| 1973 /// Handle access to a type literal of type variable [element]. Like `T = b`, | 1906 /// Handle access to a type literal of type variable [element]. Like `T = b`, |
| 1974 /// `T++` or `T += b` where 'T' is type variable. | 1907 /// `T++` or `T += b` where 'T' is type variable. |
| 1975 ResolutionResult handleTypeVariableTypeLiteralUpdate( | 1908 ResolutionResult handleTypeVariableTypeLiteralUpdate( |
| 1976 SendSet node, | 1909 SendSet node, Name name, TypeVariableElement element) { |
| 1977 Name name, | |
| 1978 TypeVariableElement element) { | |
| 1979 AccessSemantics semantics; | 1910 AccessSemantics semantics; |
| 1980 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { | 1911 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { |
| 1981 // TODO(johnniwinther): Add another access semantics for this. | 1912 // TODO(johnniwinther): Add another access semantics for this. |
| 1982 ErroneousElement error = reportAndCreateErroneousElement( | 1913 ErroneousElement error = reportAndCreateErroneousElement( |
| 1983 node, name.text, | 1914 node, |
| 1915 name.text, |
| 1984 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 1916 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
| 1985 {'typeVariableName': name}, | 1917 {'typeVariableName': name}, |
| 1986 isError: true); | 1918 isError: true); |
| 1987 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 1919 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
| 1988 semantics = new StaticAccess.invalid(error); | 1920 semantics = new StaticAccess.invalid(error); |
| 1989 } else { | 1921 } else { |
| 1990 ErroneousElement error; | 1922 ErroneousElement error; |
| 1991 if (node.isIfNullAssignment) { | 1923 if (node.isIfNullAssignment) { |
| 1992 error = reportAndCreateErroneousElement( | 1924 error = reportAndCreateErroneousElement(node.selector, name.text, |
| 1993 node.selector, name.text, | |
| 1994 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); | 1925 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); |
| 1995 // TODO(23998): Remove these when all information goes through | 1926 // TODO(23998): Remove these when all information goes through |
| 1996 // the [SendStructure]. | 1927 // the [SendStructure]. |
| 1997 registry.useElement(node.selector, element); | 1928 registry.useElement(node.selector, element); |
| 1998 } else { | 1929 } else { |
| 1999 error = reportAndCreateErroneousElement( | 1930 error = reportAndCreateErroneousElement( |
| 2000 node.selector, name.text, | 1931 node.selector, name.text, MessageKind.ASSIGNING_TYPE, const {}); |
| 2001 MessageKind.ASSIGNING_TYPE, const {}); | |
| 2002 } | 1932 } |
| 2003 | 1933 |
| 2004 // TODO(23998): Remove this when all information goes through | 1934 // TODO(23998): Remove this when all information goes through |
| 2005 // the [SendStructure]. | 1935 // the [SendStructure]. |
| 2006 registry.useElement(node, error); | 1936 registry.useElement(node, error); |
| 2007 // TODO(johnniwinther): Register only on read? | 1937 // TODO(johnniwinther): Register only on read? |
| 2008 registry.registerTypeLiteral(node, element.type); | 1938 registry.registerTypeLiteral(node, element.type); |
| 2009 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1939 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2010 semantics = new StaticAccess.typeParameterTypeLiteral(element); | 1940 semantics = new StaticAccess.typeParameterTypeLiteral(element); |
| 2011 } | 1941 } |
| 2012 return handleUpdate(node, name, semantics); | 1942 return handleUpdate(node, name, semantics); |
| 2013 } | 1943 } |
| 2014 | 1944 |
| 2015 /// Handle access to a constant type literal of [type]. | 1945 /// Handle access to a constant type literal of [type]. |
| 2016 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the | 1946 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
| 2017 // the [GetStructure]. | 1947 // the [GetStructure]. |
| 2018 // TODO(johnniwinther): Remove [element] when it is no longer needed for | 1948 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
| 2019 // evaluating constants. | 1949 // evaluating constants. |
| 2020 ResolutionResult handleConstantTypeLiteralAccess( | 1950 ResolutionResult handleConstantTypeLiteralAccess(Send node, Name name, |
| 2021 Send node, | 1951 TypeDeclarationElement element, DartType type, ConstantAccess semantics) { |
| 2022 Name name, | |
| 2023 TypeDeclarationElement element, | |
| 2024 DartType type, | |
| 2025 ConstantAccess semantics) { | |
| 2026 registry.useElement(node, element); | 1952 registry.useElement(node, element); |
| 2027 registry.registerTypeLiteral(node, type); | 1953 registry.registerTypeLiteral(node, type); |
| 2028 | 1954 |
| 2029 if (node.isCall) { | 1955 if (node.isCall) { |
| 2030 CallStructure callStructure = | 1956 CallStructure callStructure = |
| 2031 resolveArguments(node.argumentsNode).callStructure; | 1957 resolveArguments(node.argumentsNode).callStructure; |
| 2032 Selector selector = callStructure.callSelector; | 1958 Selector selector = callStructure.callSelector; |
| 2033 // TODO(23998): Remove this when all information goes through | 1959 // TODO(23998): Remove this when all information goes through |
| 2034 // the [SendStructure]. | 1960 // the [SendStructure]. |
| 2035 registry.setSelector(node, selector); | 1961 registry.setSelector(node, selector); |
| 2036 | 1962 |
| 2037 // The node itself is not a constant but we register the selector (the | 1963 // The node itself is not a constant but we register the selector (the |
| 2038 // identifier that refers to the class/typedef) as a constant. | 1964 // identifier that refers to the class/typedef) as a constant. |
| 2039 registry.useElement(node.selector, element); | 1965 registry.useElement(node.selector, element); |
| 2040 analyzeConstantDeferred(node.selector, enforceConst: false); | 1966 analyzeConstantDeferred(node.selector, enforceConst: false); |
| 2041 | 1967 |
| 2042 registry.registerSendStructure(node, | 1968 registry.registerSendStructure( |
| 2043 new InvokeStructure(semantics, selector)); | 1969 node, new InvokeStructure(semantics, selector)); |
| 2044 return const NoneResult(); | 1970 return const NoneResult(); |
| 2045 } else { | 1971 } else { |
| 2046 analyzeConstantDeferred(node, enforceConst: false); | 1972 analyzeConstantDeferred(node, enforceConst: false); |
| 2047 | 1973 |
| 2048 registry.setConstant(node, semantics.constant); | 1974 registry.setConstant(node, semantics.constant); |
| 2049 registry.registerSendStructure(node, new GetStructure(semantics)); | 1975 registry.registerSendStructure(node, new GetStructure(semantics)); |
| 2050 return new ConstantResult(node, semantics.constant); | 1976 return new ConstantResult(node, semantics.constant); |
| 2051 } | 1977 } |
| 2052 } | 1978 } |
| 2053 | 1979 |
| 2054 /// Handle access to a constant type literal of [type]. | 1980 /// Handle access to a constant type literal of [type]. |
| 2055 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the | 1981 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
| 2056 // the [GetStructure]. | 1982 // the [GetStructure]. |
| 2057 // TODO(johnniwinther): Remove [element] when it is no longer needed for | 1983 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
| 2058 // evaluating constants. | 1984 // evaluating constants. |
| 2059 ResolutionResult handleConstantTypeLiteralUpdate( | 1985 ResolutionResult handleConstantTypeLiteralUpdate(SendSet node, Name name, |
| 2060 SendSet node, | 1986 TypeDeclarationElement element, DartType type, ConstantAccess semantics) { |
| 2061 Name name, | |
| 2062 TypeDeclarationElement element, | |
| 2063 DartType type, | |
| 2064 ConstantAccess semantics) { | |
| 2065 | |
| 2066 // TODO(johnniwinther): Remove this when all constants are evaluated. | 1987 // TODO(johnniwinther): Remove this when all constants are evaluated. |
| 2067 compiler.resolver.constantCompiler.evaluate(semantics.constant); | 1988 compiler.resolver.constantCompiler.evaluate(semantics.constant); |
| 2068 | 1989 |
| 2069 ErroneousElement error; | 1990 ErroneousElement error; |
| 2070 if (node.isIfNullAssignment) { | 1991 if (node.isIfNullAssignment) { |
| 2071 error = reportAndCreateErroneousElement( | 1992 error = reportAndCreateErroneousElement(node.selector, name.text, |
| 2072 node.selector, name.text, | |
| 2073 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); | 1993 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); |
| 2074 // TODO(23998): Remove these when all information goes through | 1994 // TODO(23998): Remove these when all information goes through |
| 2075 // the [SendStructure]. | 1995 // the [SendStructure]. |
| 2076 registry.setConstant(node.selector, semantics.constant); | 1996 registry.setConstant(node.selector, semantics.constant); |
| 2077 registry.useElement(node.selector, element); | 1997 registry.useElement(node.selector, element); |
| 2078 } else { | 1998 } else { |
| 2079 error = reportAndCreateErroneousElement( | 1999 error = reportAndCreateErroneousElement( |
| 2080 node.selector, name.text, | 2000 node.selector, name.text, MessageKind.ASSIGNING_TYPE, const {}); |
| 2081 MessageKind.ASSIGNING_TYPE, const {}); | |
| 2082 } | 2001 } |
| 2083 | 2002 |
| 2084 // TODO(23998): Remove this when all information goes through | 2003 // TODO(23998): Remove this when all information goes through |
| 2085 // the [SendStructure]. | 2004 // the [SendStructure]. |
| 2086 registry.useElement(node, error); | 2005 registry.useElement(node, error); |
| 2087 registry.registerTypeLiteral(node, type); | 2006 registry.registerTypeLiteral(node, type); |
| 2088 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2007 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2089 | 2008 |
| 2090 return handleUpdate(node, name, semantics); | 2009 return handleUpdate(node, name, semantics); |
| 2091 } | 2010 } |
| 2092 | 2011 |
| 2093 /// Handle access to a type literal of a typedef. Like `F` or | 2012 /// Handle access to a type literal of a typedef. Like `F` or |
| 2094 /// `F()` where 'F' is typedef. | 2013 /// `F()` where 'F' is typedef. |
| 2095 ResolutionResult handleTypedefTypeLiteralAccess( | 2014 ResolutionResult handleTypedefTypeLiteralAccess( |
| 2096 Send node, | 2015 Send node, Name name, TypedefElement typdef) { |
| 2097 Name name, | |
| 2098 TypedefElement typdef) { | |
| 2099 typdef.ensureResolved(resolution); | 2016 typdef.ensureResolved(resolution); |
| 2100 DartType type = typdef.rawType; | 2017 DartType type = typdef.rawType; |
| 2101 ConstantExpression constant = new TypeConstantExpression(type); | 2018 ConstantExpression constant = new TypeConstantExpression(type); |
| 2102 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); | 2019 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); |
| 2103 return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics); | 2020 return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics); |
| 2104 } | 2021 } |
| 2105 | 2022 |
| 2106 /// Handle access to a type literal of a typedef. Like `F = b`, `F++` or | 2023 /// Handle access to a type literal of a typedef. Like `F = b`, `F++` or |
| 2107 /// `F += b` where 'F' is typedef. | 2024 /// `F += b` where 'F' is typedef. |
| 2108 ResolutionResult handleTypedefTypeLiteralUpdate( | 2025 ResolutionResult handleTypedefTypeLiteralUpdate( |
| 2109 SendSet node, | 2026 SendSet node, Name name, TypedefElement typdef) { |
| 2110 Name name, | |
| 2111 TypedefElement typdef) { | |
| 2112 typdef.ensureResolved(resolution); | 2027 typdef.ensureResolved(resolution); |
| 2113 DartType type = typdef.rawType; | 2028 DartType type = typdef.rawType; |
| 2114 ConstantExpression constant = new TypeConstantExpression(type); | 2029 ConstantExpression constant = new TypeConstantExpression(type); |
| 2115 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); | 2030 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); |
| 2116 return handleConstantTypeLiteralUpdate(node, name, typdef, type, semantics); | 2031 return handleConstantTypeLiteralUpdate(node, name, typdef, type, semantics); |
| 2117 } | 2032 } |
| 2118 | 2033 |
| 2119 /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or | 2034 /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or |
| 2120 /// `dynamic()`. | 2035 /// `dynamic()`. |
| 2121 ResolutionResult handleDynamicTypeLiteralAccess(Send node) { | 2036 ResolutionResult handleDynamicTypeLiteralAccess(Send node) { |
| 2122 DartType type = const DynamicType(); | 2037 DartType type = const DynamicType(); |
| 2123 ConstantExpression constant = new TypeConstantExpression( | 2038 ConstantExpression constant = new TypeConstantExpression( |
| 2124 // TODO(johnniwinther): Use [type] when evaluation of constants is done | 2039 // TODO(johnniwinther): Use [type] when evaluation of constants is done |
| 2125 // directly on the constant expressions. | 2040 // directly on the constant expressions. |
| 2126 node.isCall ? coreTypes.typeType : type); | 2041 node.isCall ? coreTypes.typeType : type); |
| 2127 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); | 2042 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); |
| 2128 return handleConstantTypeLiteralAccess( | 2043 return handleConstantTypeLiteralAccess(node, const PublicName('dynamic'), |
| 2129 node, const PublicName('dynamic'), | |
| 2130 coreClasses.typeClass, type, semantics); | 2044 coreClasses.typeClass, type, semantics); |
| 2131 } | 2045 } |
| 2132 | 2046 |
| 2133 /// Handle update to a type literal of the type 'dynamic'. Like `dynamic++` or | 2047 /// Handle update to a type literal of the type 'dynamic'. Like `dynamic++` or |
| 2134 /// `dynamic = 0`. | 2048 /// `dynamic = 0`. |
| 2135 ResolutionResult handleDynamicTypeLiteralUpdate(SendSet node) { | 2049 ResolutionResult handleDynamicTypeLiteralUpdate(SendSet node) { |
| 2136 DartType type = const DynamicType(); | 2050 DartType type = const DynamicType(); |
| 2137 ConstantExpression constant = | 2051 ConstantExpression constant = |
| 2138 new TypeConstantExpression(const DynamicType()); | 2052 new TypeConstantExpression(const DynamicType()); |
| 2139 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); | 2053 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); |
| 2140 return handleConstantTypeLiteralUpdate( | 2054 return handleConstantTypeLiteralUpdate(node, const PublicName('dynamic'), |
| 2141 node, const PublicName('dynamic'), | |
| 2142 coreClasses.typeClass, type, semantics); | 2055 coreClasses.typeClass, type, semantics); |
| 2143 } | 2056 } |
| 2144 | 2057 |
| 2145 /// Handle access to a type literal of a class. Like `C` or | 2058 /// Handle access to a type literal of a class. Like `C` or |
| 2146 /// `C()` where 'C' is class. | 2059 /// `C()` where 'C' is class. |
| 2147 ResolutionResult handleClassTypeLiteralAccess( | 2060 ResolutionResult handleClassTypeLiteralAccess( |
| 2148 Send node, | 2061 Send node, Name name, ClassElement cls) { |
| 2149 Name name, | |
| 2150 ClassElement cls) { | |
| 2151 cls.ensureResolved(resolution); | 2062 cls.ensureResolved(resolution); |
| 2152 DartType type = cls.rawType; | 2063 DartType type = cls.rawType; |
| 2153 ConstantExpression constant = new TypeConstantExpression(type); | 2064 ConstantExpression constant = new TypeConstantExpression(type); |
| 2154 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); | 2065 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); |
| 2155 return handleConstantTypeLiteralAccess(node, name, cls, type, semantics); | 2066 return handleConstantTypeLiteralAccess(node, name, cls, type, semantics); |
| 2156 } | 2067 } |
| 2157 | 2068 |
| 2158 /// Handle access to a type literal of a class. Like `C = b`, `C++` or | 2069 /// Handle access to a type literal of a class. Like `C = b`, `C++` or |
| 2159 /// `C += b` where 'C' is class. | 2070 /// `C += b` where 'C' is class. |
| 2160 ResolutionResult handleClassTypeLiteralUpdate( | 2071 ResolutionResult handleClassTypeLiteralUpdate( |
| 2161 SendSet node, | 2072 SendSet node, Name name, ClassElement cls) { |
| 2162 Name name, | |
| 2163 ClassElement cls) { | |
| 2164 cls.ensureResolved(resolution); | 2073 cls.ensureResolved(resolution); |
| 2165 DartType type = cls.rawType; | 2074 DartType type = cls.rawType; |
| 2166 ConstantExpression constant = new TypeConstantExpression(type); | 2075 ConstantExpression constant = new TypeConstantExpression(type); |
| 2167 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); | 2076 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); |
| 2168 return handleConstantTypeLiteralUpdate(node, name, cls, type, semantics); | 2077 return handleConstantTypeLiteralUpdate(node, name, cls, type, semantics); |
| 2169 } | 2078 } |
| 2170 | 2079 |
| 2171 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in | 2080 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in |
| 2172 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time | 2081 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time |
| 2173 /// error. | 2082 /// error. |
| 2174 ResolutionResult handleClassSend( | 2083 ResolutionResult handleClassSend(Send node, Name name, ClassElement cls) { |
| 2175 Send node, | |
| 2176 Name name, | |
| 2177 ClassElement cls) { | |
| 2178 cls.ensureResolved(resolution); | 2084 cls.ensureResolved(resolution); |
| 2179 if (sendIsMemberAccess) { | 2085 if (sendIsMemberAccess) { |
| 2180 registry.useElement(node, cls); | 2086 registry.useElement(node, cls); |
| 2181 return new PrefixResult(null, cls); | 2087 return new PrefixResult(null, cls); |
| 2182 } else { | 2088 } else { |
| 2183 // `C` or `C()` where 'C' is a class. | 2089 // `C` or `C()` where 'C' is a class. |
| 2184 return handleClassTypeLiteralAccess(node, name, cls); | 2090 return handleClassTypeLiteralAccess(node, name, cls); |
| 2185 } | 2091 } |
| 2186 } | 2092 } |
| 2187 | 2093 |
| 2188 /// Compute a [DeferredPrefixStructure] for [node]. | 2094 /// Compute a [DeferredPrefixStructure] for [node]. |
| 2189 ResolutionResult handleDeferredAccess( | 2095 ResolutionResult handleDeferredAccess( |
| 2190 Send node, | 2096 Send node, PrefixElement prefix, ResolutionResult result) { |
| 2191 PrefixElement prefix, | |
| 2192 ResolutionResult result) { | |
| 2193 assert(invariant(node, prefix.isDeferred, | 2097 assert(invariant(node, prefix.isDeferred, |
| 2194 message: "Prefix $prefix is not deferred.")); | 2098 message: "Prefix $prefix is not deferred.")); |
| 2195 SendStructure sendStructure = registry.getSendStructure(node); | 2099 SendStructure sendStructure = registry.getSendStructure(node); |
| 2196 assert(invariant(node, sendStructure != null, | 2100 assert(invariant(node, sendStructure != null, |
| 2197 message: "No SendStructure for $node.")); | 2101 message: "No SendStructure for $node.")); |
| 2198 registry.registerSendStructure(node, | 2102 registry.registerSendStructure( |
| 2199 new DeferredPrefixStructure(prefix, sendStructure)); | 2103 node, new DeferredPrefixStructure(prefix, sendStructure)); |
| 2200 if (result.isConstant) { | 2104 if (result.isConstant) { |
| 2201 ConstantExpression constant = | 2105 ConstantExpression constant = |
| 2202 new DeferredConstantExpression(result.constant, prefix); | 2106 new DeferredConstantExpression(result.constant, prefix); |
| 2203 registry.setConstant(node, constant); | 2107 registry.setConstant(node, constant); |
| 2204 result = new ConstantResult(node, constant); | 2108 result = new ConstantResult(node, constant); |
| 2205 } | 2109 } |
| 2206 return result; | 2110 return result; |
| 2207 } | 2111 } |
| 2208 | 2112 |
| 2209 /// Handle qualified [Send] where the receiver resolves to a [prefix], | 2113 /// Handle qualified [Send] where the receiver resolves to a [prefix], |
| 2210 /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where | 2114 /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where |
| 2211 /// `prefix` is a library prefix. | 2115 /// `prefix` is a library prefix. |
| 2212 ResolutionResult handleLibraryPrefixSend( | 2116 ResolutionResult handleLibraryPrefixSend( |
| 2213 Send node, Name name, PrefixElement prefix) { | 2117 Send node, Name name, PrefixElement prefix) { |
| 2214 ResolutionResult result; | 2118 ResolutionResult result; |
| 2215 Element member = prefix.lookupLocalMember(name.text); | 2119 Element member = prefix.lookupLocalMember(name.text); |
| 2216 if (member == null) { | 2120 if (member == null) { |
| 2217 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2121 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2218 Element error = reportAndCreateErroneousElement( | 2122 Element error = reportAndCreateErroneousElement( |
| 2219 node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 2123 node, |
| 2124 name.text, |
| 2125 MessageKind.NO_SUCH_LIBRARY_MEMBER, |
| 2220 {'libraryName': prefix.name, 'memberName': name}); | 2126 {'libraryName': prefix.name, 'memberName': name}); |
| 2221 result = handleUnresolvedAccess(node, name, error); | 2127 result = handleUnresolvedAccess(node, name, error); |
| 2222 } else { | 2128 } else { |
| 2223 result = handleResolvedSend(node, name, member); | 2129 result = handleResolvedSend(node, name, member); |
| 2224 } | 2130 } |
| 2225 if (result.kind == ResultKind.PREFIX) { | 2131 if (result.kind == ResultKind.PREFIX) { |
| 2226 // [member] is a class prefix of a static access like `prefix.Class` of | 2132 // [member] is a class prefix of a static access like `prefix.Class` of |
| 2227 // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will | 2133 // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will |
| 2228 // called on the parent `prefix.Class.foo` node. | 2134 // called on the parent `prefix.Class.foo` node. |
| 2229 result = new PrefixResult(prefix, result.element); | 2135 result = new PrefixResult(prefix, result.element); |
| 2230 } else if (prefix.isDeferred && | 2136 } else if (prefix.isDeferred && |
| 2231 (member == null || !member.isDeferredLoaderGetter)) { | 2137 (member == null || !member.isDeferredLoaderGetter)) { |
| 2232 result = handleDeferredAccess(node, prefix, result); | 2138 result = handleDeferredAccess(node, prefix, result); |
| 2233 } | 2139 } |
| 2234 return result; | 2140 return result; |
| 2235 } | 2141 } |
| 2236 | 2142 |
| 2237 /// Handle qualified [SendSet] where the receiver resolves to a [prefix], | 2143 /// Handle qualified [SendSet] where the receiver resolves to a [prefix], |
| 2238 /// like `prefix.toplevelField = b` or `prefix.Class.staticField++` where | 2144 /// like `prefix.toplevelField = b` or `prefix.Class.staticField++` where |
| 2239 /// `prefix` is a library prefix. | 2145 /// `prefix` is a library prefix. |
| 2240 ResolutionResult handleLibraryPrefixSendSet( | 2146 ResolutionResult handleLibraryPrefixSendSet( |
| 2241 SendSet node, Name name, PrefixElement prefix) { | 2147 SendSet node, Name name, PrefixElement prefix) { |
| 2242 ResolutionResult result; | 2148 ResolutionResult result; |
| 2243 Element member = prefix.lookupLocalMember(name.text); | 2149 Element member = prefix.lookupLocalMember(name.text); |
| 2244 if (member == null) { | 2150 if (member == null) { |
| 2245 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2151 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2246 Element error = reportAndCreateErroneousElement( | 2152 Element error = reportAndCreateErroneousElement( |
| 2247 node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 2153 node, |
| 2154 name.text, |
| 2155 MessageKind.NO_SUCH_LIBRARY_MEMBER, |
| 2248 {'libraryName': prefix.name, 'memberName': name}); | 2156 {'libraryName': prefix.name, 'memberName': name}); |
| 2249 return handleUpdate(node, name, new StaticAccess.unresolved(error)); | 2157 return handleUpdate(node, name, new StaticAccess.unresolved(error)); |
| 2250 } else { | 2158 } else { |
| 2251 result = handleResolvedSendSet(node, name, member); | 2159 result = handleResolvedSendSet(node, name, member); |
| 2252 } | 2160 } |
| 2253 if (result.kind == ResultKind.PREFIX) { | 2161 if (result.kind == ResultKind.PREFIX) { |
| 2254 // [member] is a class prefix of a static access like `prefix.Class` of | 2162 // [member] is a class prefix of a static access like `prefix.Class` of |
| 2255 // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will | 2163 // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will |
| 2256 // called on the parent `prefix.Class.foo` node. | 2164 // called on the parent `prefix.Class.foo` node. |
| 2257 result = new PrefixResult(prefix, result.element); | 2165 result = new PrefixResult(prefix, result.element); |
| 2258 } else if (prefix.isDeferred && | 2166 } else if (prefix.isDeferred && |
| 2259 (member == null || !member.isDeferredLoaderGetter)) { | 2167 (member == null || !member.isDeferredLoaderGetter)) { |
| 2260 result = handleDeferredAccess(node, prefix, result); | 2168 result = handleDeferredAccess(node, prefix, result); |
| 2261 } | 2169 } |
| 2262 return result; | 2170 return result; |
| 2263 } | 2171 } |
| 2264 | 2172 |
| 2265 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in | 2173 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in |
| 2266 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time | 2174 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time |
| 2267 /// error. | 2175 /// error. |
| 2268 ResolutionResult handleLibraryPrefix( | 2176 ResolutionResult handleLibraryPrefix( |
| 2269 Send node, | 2177 Send node, Name name, PrefixElement prefix) { |
| 2270 Name name, | |
| 2271 PrefixElement prefix) { | |
| 2272 if ((ElementCategory.PREFIX & allowedCategory) == 0) { | 2178 if ((ElementCategory.PREFIX & allowedCategory) == 0) { |
| 2273 ErroneousElement error = reportAndCreateErroneousElement( | 2179 ErroneousElement error = reportAndCreateErroneousElement( |
| 2274 node, | 2180 node, name.text, MessageKind.PREFIX_AS_EXPRESSION, {'prefix': name}, |
| 2275 name.text, | |
| 2276 MessageKind.PREFIX_AS_EXPRESSION, | |
| 2277 {'prefix': name}, | |
| 2278 isError: true); | 2181 isError: true); |
| 2279 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 2182 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
| 2280 return handleErroneousAccess( | 2183 return handleErroneousAccess(node, name, new StaticAccess.invalid(error)); |
| 2281 node, name, new StaticAccess.invalid(error)); | |
| 2282 } | 2184 } |
| 2283 if (prefix.isDeferred) { | 2185 if (prefix.isDeferred) { |
| 2284 // TODO(23998): Remove this when deferred access is detected | 2186 // TODO(23998): Remove this when deferred access is detected |
| 2285 // through a [SendStructure]. | 2187 // through a [SendStructure]. |
| 2286 registry.useElement(node.selector, prefix); | 2188 registry.useElement(node.selector, prefix); |
| 2287 } | 2189 } |
| 2288 registry.useElement(node, prefix); | 2190 registry.useElement(node, prefix); |
| 2289 return new PrefixResult(prefix, null); | 2191 return new PrefixResult(prefix, null); |
| 2290 } | 2192 } |
| 2291 | 2193 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2333 | 2235 |
| 2334 /// Handle dynamic access of [semantics]. | 2236 /// Handle dynamic access of [semantics]. |
| 2335 ResolutionResult handleDynamicAccessSemantics( | 2237 ResolutionResult handleDynamicAccessSemantics( |
| 2336 Send node, Name name, AccessSemantics semantics) { | 2238 Send node, Name name, AccessSemantics semantics) { |
| 2337 SendStructure sendStructure; | 2239 SendStructure sendStructure; |
| 2338 Selector selector; | 2240 Selector selector; |
| 2339 if (node.isCall) { | 2241 if (node.isCall) { |
| 2340 CallStructure callStructure = | 2242 CallStructure callStructure = |
| 2341 resolveArguments(node.argumentsNode).callStructure; | 2243 resolveArguments(node.argumentsNode).callStructure; |
| 2342 selector = new Selector.call(name, callStructure); | 2244 selector = new Selector.call(name, callStructure); |
| 2343 registry.registerDynamicUse( | 2245 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 2344 new DynamicUse(selector, null)); | |
| 2345 sendStructure = new InvokeStructure(semantics, selector); | 2246 sendStructure = new InvokeStructure(semantics, selector); |
| 2346 } else { | 2247 } else { |
| 2347 assert(invariant(node, node.isPropertyAccess)); | 2248 assert(invariant(node, node.isPropertyAccess)); |
| 2348 selector = new Selector.getter(name); | 2249 selector = new Selector.getter(name); |
| 2349 registry.registerDynamicUse( | 2250 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 2350 new DynamicUse(selector, null)); | |
| 2351 sendStructure = new GetStructure(semantics); | 2251 sendStructure = new GetStructure(semantics); |
| 2352 } | 2252 } |
| 2353 registry.registerSendStructure(node, sendStructure); | 2253 registry.registerSendStructure(node, sendStructure); |
| 2354 // TODO(23998): Remove this when all information goes through | 2254 // TODO(23998): Remove this when all information goes through |
| 2355 // the [SendStructure]. | 2255 // the [SendStructure]. |
| 2356 registry.setSelector(node, selector); | 2256 registry.setSelector(node, selector); |
| 2357 return const NoneResult(); | 2257 return const NoneResult(); |
| 2358 } | 2258 } |
| 2359 | 2259 |
| 2360 /// Handle dynamic update of [semantics]. | 2260 /// Handle dynamic update of [semantics]. |
| 2361 ResolutionResult handleDynamicUpdateSemantics( | 2261 ResolutionResult handleDynamicUpdateSemantics( |
| 2362 SendSet node, Name name, Element element, AccessSemantics semantics) { | 2262 SendSet node, Name name, Element element, AccessSemantics semantics) { |
| 2363 Selector getterSelector = new Selector.getter(name); | 2263 Selector getterSelector = new Selector.getter(name); |
| 2364 Selector setterSelector = new Selector.setter(name.setter); | 2264 Selector setterSelector = new Selector.setter(name.setter); |
| 2365 registry.registerDynamicUse( | 2265 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
| 2366 new DynamicUse(setterSelector, null)); | |
| 2367 if (node.isComplex) { | 2266 if (node.isComplex) { |
| 2368 registry.registerDynamicUse( | 2267 registry.registerDynamicUse(new DynamicUse(getterSelector, null)); |
| 2369 new DynamicUse(getterSelector, null)); | |
| 2370 } | 2268 } |
| 2371 | 2269 |
| 2372 // TODO(23998): Remove these when elements are only accessed through the | 2270 // TODO(23998): Remove these when elements are only accessed through the |
| 2373 // send structure. | 2271 // send structure. |
| 2374 Element getter = element; | 2272 Element getter = element; |
| 2375 Element setter = element; | 2273 Element setter = element; |
| 2376 if (element != null && element.isAbstractField) { | 2274 if (element != null && element.isAbstractField) { |
| 2377 AbstractFieldElement abstractField = element; | 2275 AbstractFieldElement abstractField = element; |
| 2378 getter = abstractField.getter; | 2276 getter = abstractField.getter; |
| 2379 setter = abstractField.setter; | 2277 setter = abstractField.setter; |
| 2380 } | 2278 } |
| 2381 if (setter != null) { | 2279 if (setter != null) { |
| 2382 registry.useElement(node, setter); | 2280 registry.useElement(node, setter); |
| 2383 if (getter != null && node.isComplex) { | 2281 if (getter != null && node.isComplex) { |
| 2384 registry.useElement(node.selector, getter); | 2282 registry.useElement(node.selector, getter); |
| 2385 } | 2283 } |
| 2386 } | 2284 } |
| 2387 | 2285 |
| 2388 return handleUpdate(node, name, semantics); | 2286 return handleUpdate(node, name, semantics); |
| 2389 } | 2287 } |
| 2390 | 2288 |
| 2391 /// Handle `this` as a qualified property, like `a.this`. | 2289 /// Handle `this` as a qualified property, like `a.this`. |
| 2392 ResolutionResult handleQualifiedThisAccess(Send node, Name name) { | 2290 ResolutionResult handleQualifiedThisAccess(Send node, Name name) { |
| 2393 ErroneousElement error = reportAndCreateErroneousElement( | 2291 ErroneousElement error = reportAndCreateErroneousElement( |
| 2394 node.selector, | 2292 node.selector, name.text, MessageKind.THIS_PROPERTY, {}, |
| 2395 name.text, | |
| 2396 MessageKind.THIS_PROPERTY, {}, | |
| 2397 isError: true); | 2293 isError: true); |
| 2398 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 2294 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
| 2399 AccessSemantics accessSemantics = new StaticAccess.invalid(error); | 2295 AccessSemantics accessSemantics = new StaticAccess.invalid(error); |
| 2400 return handleErroneousAccess(node, name, accessSemantics); | 2296 return handleErroneousAccess(node, name, accessSemantics); |
| 2401 } | 2297 } |
| 2402 | 2298 |
| 2403 /// Handle a qualified [Send], that is where the receiver is non-null, like | 2299 /// Handle a qualified [Send], that is where the receiver is non-null, like |
| 2404 /// `a.b`, `a.b()`, `this.a()` and `super.a()`. | 2300 /// `a.b`, `a.b()`, `this.a()` and `super.a()`. |
| 2405 ResolutionResult handleQualifiedSend(Send node) { | 2301 ResolutionResult handleQualifiedSend(Send node) { |
| 2406 Identifier selector = node.selector.asIdentifier(); | 2302 Identifier selector = node.selector.asIdentifier(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2463 // Handle dynamic property access, like `a.b = c`, `a.b++` or `a.b += c` | 2359 // Handle dynamic property access, like `a.b = c`, `a.b++` or `a.b += c` |
| 2464 // where `a` is not a prefix or class. | 2360 // where `a` is not a prefix or class. |
| 2465 // TODO(johnniwinther): Use the `element` of [result]. | 2361 // TODO(johnniwinther): Use the `element` of [result]. |
| 2466 return handleDynamicUpdateSemantics( | 2362 return handleDynamicUpdateSemantics( |
| 2467 node, name, null, new DynamicAccess.dynamicProperty(name)); | 2363 node, name, null, new DynamicAccess.dynamicProperty(name)); |
| 2468 } | 2364 } |
| 2469 } | 2365 } |
| 2470 | 2366 |
| 2471 /// Handle access unresolved access to [name] in a non-instance context. | 2367 /// Handle access unresolved access to [name] in a non-instance context. |
| 2472 ResolutionResult handleUnresolvedAccess( | 2368 ResolutionResult handleUnresolvedAccess( |
| 2473 Send node, Name name, Element element) { | 2369 Send node, Name name, Element element) { |
| 2474 // TODO(johnniwinther): Support unresolved top level access as an | 2370 // TODO(johnniwinther): Support unresolved top level access as an |
| 2475 // [AccessSemantics]. | 2371 // [AccessSemantics]. |
| 2476 AccessSemantics semantics = new StaticAccess.unresolved(element); | 2372 AccessSemantics semantics = new StaticAccess.unresolved(element); |
| 2477 return handleErroneousAccess(node, name, semantics); | 2373 return handleErroneousAccess(node, name, semantics); |
| 2478 } | 2374 } |
| 2479 | 2375 |
| 2480 /// Handle erroneous access of [element] of the given [semantics]. | 2376 /// Handle erroneous access of [element] of the given [semantics]. |
| 2481 ResolutionResult handleErroneousAccess( | 2377 ResolutionResult handleErroneousAccess( |
| 2482 Send node, Name name, AccessSemantics semantics) { | 2378 Send node, Name name, AccessSemantics semantics) { |
| 2483 SendStructure sendStructure; | 2379 SendStructure sendStructure; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2497 // TODO(23998): Remove this when all information goes through | 2393 // TODO(23998): Remove this when all information goes through |
| 2498 // the [SendStructure]. | 2394 // the [SendStructure]. |
| 2499 registry.setSelector(node, selector); | 2395 registry.setSelector(node, selector); |
| 2500 registry.useElement(node, semantics.element); | 2396 registry.useElement(node, semantics.element); |
| 2501 registry.registerSendStructure(node, sendStructure); | 2397 registry.registerSendStructure(node, sendStructure); |
| 2502 return const NoneResult(); | 2398 return const NoneResult(); |
| 2503 } | 2399 } |
| 2504 | 2400 |
| 2505 /// Handle access to an ambiguous element, that is, a name imported twice. | 2401 /// Handle access to an ambiguous element, that is, a name imported twice. |
| 2506 ResolutionResult handleAmbiguousSend( | 2402 ResolutionResult handleAmbiguousSend( |
| 2507 Send node, | 2403 Send node, Name name, AmbiguousElement element) { |
| 2508 Name name, | |
| 2509 AmbiguousElement element) { | |
| 2510 | |
| 2511 ErroneousElement error = reportAndCreateErroneousElement( | 2404 ErroneousElement error = reportAndCreateErroneousElement( |
| 2512 node, | 2405 node, name.text, element.messageKind, element.messageArguments, |
| 2513 name.text, | |
| 2514 element.messageKind, | |
| 2515 element.messageArguments, | |
| 2516 infos: element.computeInfos(enclosingElement, reporter)); | 2406 infos: element.computeInfos(enclosingElement, reporter)); |
| 2517 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2407 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2518 | 2408 |
| 2519 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | 2409 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. |
| 2520 AccessSemantics semantics = new StaticAccess.unresolved(error); | 2410 AccessSemantics semantics = new StaticAccess.unresolved(error); |
| 2521 return handleErroneousAccess(node, name, semantics); | 2411 return handleErroneousAccess(node, name, semantics); |
| 2522 } | 2412 } |
| 2523 | 2413 |
| 2524 /// Handle update to an ambiguous element, that is, a name imported twice. | 2414 /// Handle update to an ambiguous element, that is, a name imported twice. |
| 2525 ResolutionResult handleAmbiguousUpdate( | 2415 ResolutionResult handleAmbiguousUpdate( |
| 2526 SendSet node, | 2416 SendSet node, Name name, AmbiguousElement element) { |
| 2527 Name name, | |
| 2528 AmbiguousElement element) { | |
| 2529 | |
| 2530 ErroneousElement error = reportAndCreateErroneousElement( | 2417 ErroneousElement error = reportAndCreateErroneousElement( |
| 2531 node, | 2418 node, name.text, element.messageKind, element.messageArguments, |
| 2532 name.text, | |
| 2533 element.messageKind, | |
| 2534 element.messageArguments, | |
| 2535 infos: element.computeInfos(enclosingElement, reporter)); | 2419 infos: element.computeInfos(enclosingElement, reporter)); |
| 2536 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2420 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2537 | 2421 |
| 2538 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | 2422 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. |
| 2539 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); | 2423 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); |
| 2540 return handleUpdate(node, name, accessSemantics); | 2424 return handleUpdate(node, name, accessSemantics); |
| 2541 } | 2425 } |
| 2542 | 2426 |
| 2543 /// Report access of an instance [member] from a non-instance context. | 2427 /// Report access of an instance [member] from a non-instance context. |
| 2544 AccessSemantics reportStaticInstanceAccess(Send node, Name name) { | 2428 AccessSemantics reportStaticInstanceAccess(Send node, Name name) { |
| 2545 ErroneousElement error = reportAndCreateErroneousElement( | 2429 ErroneousElement error = reportAndCreateErroneousElement( |
| 2546 node, name.text, | 2430 node, name.text, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}, |
| 2547 MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}, | |
| 2548 isError: true); | 2431 isError: true); |
| 2549 // TODO(johnniwinther): Support static instance access as an | 2432 // TODO(johnniwinther): Support static instance access as an |
| 2550 // [AccessSemantics]. | 2433 // [AccessSemantics]. |
| 2551 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 2434 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
| 2552 return new StaticAccess.invalid(error); | 2435 return new StaticAccess.invalid(error); |
| 2553 } | 2436 } |
| 2554 | 2437 |
| 2555 /// Handle access of a parameter, local variable or local function. | 2438 /// Handle access of a parameter, local variable or local function. |
| 2556 ResolutionResult handleLocalAccess(Send node, Name name, Element element) { | 2439 ResolutionResult handleLocalAccess(Send node, Name name, Element element) { |
| 2557 ResolutionResult result = const NoneResult(); | 2440 ResolutionResult result = const NoneResult(); |
| 2558 AccessSemantics semantics = computeLocalAccessSemantics(node, element); | 2441 AccessSemantics semantics = computeLocalAccessSemantics(node, element); |
| 2559 Selector selector; | 2442 Selector selector; |
| 2560 if (node.isCall) { | 2443 if (node.isCall) { |
| 2561 CallStructure callStructure = | 2444 CallStructure callStructure = |
| 2562 resolveArguments(node.argumentsNode).callStructure; | 2445 resolveArguments(node.argumentsNode).callStructure; |
| 2563 selector = new Selector.call(name, callStructure); | 2446 selector = new Selector.call(name, callStructure); |
| 2564 bool isIncompatibleInvoke = false; | 2447 bool isIncompatibleInvoke = false; |
| 2565 switch (semantics.kind) { | 2448 switch (semantics.kind) { |
| 2566 case AccessKind.LOCAL_FUNCTION: | 2449 case AccessKind.LOCAL_FUNCTION: |
| 2567 LocalFunctionElementX function = semantics.element; | 2450 LocalFunctionElementX function = semantics.element; |
| 2568 function.computeType(resolution); | 2451 function.computeType(resolution); |
| 2569 if (!callStructure.signatureApplies(function.functionSignature)) { | 2452 if (!callStructure.signatureApplies(function.functionSignature)) { |
| 2570 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2453 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2571 registry.registerDynamicUse( | 2454 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 2572 new DynamicUse(selector, null)); | |
| 2573 isIncompatibleInvoke = true; | 2455 isIncompatibleInvoke = true; |
| 2574 } | 2456 } |
| 2575 break; | 2457 break; |
| 2576 case AccessKind.PARAMETER: | 2458 case AccessKind.PARAMETER: |
| 2577 case AccessKind.FINAL_PARAMETER: | 2459 case AccessKind.FINAL_PARAMETER: |
| 2578 case AccessKind.LOCAL_VARIABLE: | 2460 case AccessKind.LOCAL_VARIABLE: |
| 2579 case AccessKind.FINAL_LOCAL_VARIABLE: | 2461 case AccessKind.FINAL_LOCAL_VARIABLE: |
| 2580 selector = callStructure.callSelector; | 2462 selector = callStructure.callSelector; |
| 2581 registry.registerDynamicUse( | 2463 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 2582 new DynamicUse(selector, null)); | |
| 2583 break; | 2464 break; |
| 2584 default: | 2465 default: |
| 2585 reporter.internalError(node, | 2466 reporter.internalError(node, "Unexpected local access $semantics."); |
| 2586 "Unexpected local access $semantics."); | |
| 2587 break; | 2467 break; |
| 2588 } | 2468 } |
| 2589 registry.registerSendStructure(node, | 2469 registry.registerSendStructure( |
| 2470 node, |
| 2590 isIncompatibleInvoke | 2471 isIncompatibleInvoke |
| 2591 ? new IncompatibleInvokeStructure(semantics, selector) | 2472 ? new IncompatibleInvokeStructure(semantics, selector) |
| 2592 : new InvokeStructure(semantics, selector)); | 2473 : new InvokeStructure(semantics, selector)); |
| 2593 } else { | 2474 } else { |
| 2594 switch (semantics.kind) { | 2475 switch (semantics.kind) { |
| 2595 case AccessKind.LOCAL_VARIABLE: | 2476 case AccessKind.LOCAL_VARIABLE: |
| 2596 case AccessKind.LOCAL_FUNCTION: | 2477 case AccessKind.LOCAL_FUNCTION: |
| 2597 result = new ElementResult(element); | 2478 result = new ElementResult(element); |
| 2598 break; | 2479 break; |
| 2599 case AccessKind.PARAMETER: | 2480 case AccessKind.PARAMETER: |
| 2600 case AccessKind.FINAL_PARAMETER: | 2481 case AccessKind.FINAL_PARAMETER: |
| 2601 if (constantState == ConstantState.CONSTANT_INITIALIZER) { | 2482 if (constantState == ConstantState.CONSTANT_INITIALIZER) { |
| 2602 ParameterElement parameter = element; | 2483 ParameterElement parameter = element; |
| 2603 if (parameter.isNamed) { | 2484 if (parameter.isNamed) { |
| 2604 result = new ConstantResult( | 2485 result = new ConstantResult( |
| 2605 node, | 2486 node, new NamedArgumentReference(parameter.name), |
| 2606 new NamedArgumentReference(parameter.name), | |
| 2607 element: element); | 2487 element: element); |
| 2608 } else { | 2488 } else { |
| 2609 result = new ConstantResult( | 2489 result = new ConstantResult( |
| 2610 node, | 2490 node, |
| 2611 new PositionalArgumentReference( | 2491 new PositionalArgumentReference(parameter |
| 2612 parameter.functionDeclaration.parameters.indexOf( | 2492 .functionDeclaration.parameters |
| 2613 parameter)), | 2493 .indexOf(parameter)), |
| 2614 element: element); | 2494 element: element); |
| 2615 } | 2495 } |
| 2616 } else { | 2496 } else { |
| 2617 result = new ElementResult(element); | 2497 result = new ElementResult(element); |
| 2618 } | 2498 } |
| 2619 break; | 2499 break; |
| 2620 case AccessKind.FINAL_LOCAL_VARIABLE: | 2500 case AccessKind.FINAL_LOCAL_VARIABLE: |
| 2621 if (element.isConst) { | 2501 if (element.isConst) { |
| 2622 result = new ConstantResult( | 2502 result = new ConstantResult( |
| 2623 node, | 2503 node, new VariableConstantExpression(element), |
| 2624 new VariableConstantExpression(element), | |
| 2625 element: element); | 2504 element: element); |
| 2626 } else { | 2505 } else { |
| 2627 result = new ElementResult(element); | 2506 result = new ElementResult(element); |
| 2628 } | 2507 } |
| 2629 break; | 2508 break; |
| 2630 default: | 2509 default: |
| 2631 reporter.internalError(node, | 2510 reporter.internalError(node, "Unexpected local access $semantics."); |
| 2632 "Unexpected local access $semantics."); | |
| 2633 break; | 2511 break; |
| 2634 } | 2512 } |
| 2635 selector = new Selector.getter(name); | 2513 selector = new Selector.getter(name); |
| 2636 registry.registerSendStructure(node, new GetStructure(semantics)); | 2514 registry.registerSendStructure(node, new GetStructure(semantics)); |
| 2637 } | 2515 } |
| 2638 | 2516 |
| 2639 // TODO(23998): Remove these when all information goes through | 2517 // TODO(23998): Remove these when all information goes through |
| 2640 // the [SendStructure]. | 2518 // the [SendStructure]. |
| 2641 registry.useElement(node, element); | 2519 registry.useElement(node, element); |
| 2642 registry.setSelector(node, selector); | 2520 registry.setSelector(node, selector); |
| 2643 | 2521 |
| 2644 registerPotentialAccessInClosure(node, element); | 2522 registerPotentialAccessInClosure(node, element); |
| 2645 | 2523 |
| 2646 return result; | 2524 return result; |
| 2647 } | 2525 } |
| 2648 | 2526 |
| 2649 /// Handle update of a parameter, local variable or local function. | 2527 /// Handle update of a parameter, local variable or local function. |
| 2650 ResolutionResult handleLocalUpdate(Send node, Name name, Element element) { | 2528 ResolutionResult handleLocalUpdate(Send node, Name name, Element element) { |
| 2651 AccessSemantics semantics; | 2529 AccessSemantics semantics; |
| 2652 ErroneousElement error; | 2530 ErroneousElement error; |
| 2653 if (element.isParameter) { | 2531 if (element.isParameter) { |
| 2654 if (element.isFinal) { | 2532 if (element.isFinal) { |
| 2655 error = reportAndCreateErroneousElement( | 2533 error = reportAndCreateErroneousElement(node.selector, name.text, |
| 2656 node.selector, name.text, | 2534 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); |
| 2657 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, | |
| 2658 {'name': name}); | |
| 2659 semantics = new StaticAccess.finalParameter(element); | 2535 semantics = new StaticAccess.finalParameter(element); |
| 2660 } else { | 2536 } else { |
| 2661 semantics = new StaticAccess.parameter(element); | 2537 semantics = new StaticAccess.parameter(element); |
| 2662 } | 2538 } |
| 2663 } else if (element.isVariable) { | 2539 } else if (element.isVariable) { |
| 2664 if (element.isFinal || element.isConst) { | 2540 if (element.isFinal || element.isConst) { |
| 2665 error = reportAndCreateErroneousElement( | 2541 error = reportAndCreateErroneousElement(node.selector, name.text, |
| 2666 node.selector, name.text, | 2542 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); |
| 2667 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, | |
| 2668 {'name': name}); | |
| 2669 semantics = new StaticAccess.finalLocalVariable(element); | 2543 semantics = new StaticAccess.finalLocalVariable(element); |
| 2670 } else { | 2544 } else { |
| 2671 semantics = new StaticAccess.localVariable(element); | 2545 semantics = new StaticAccess.localVariable(element); |
| 2672 } | 2546 } |
| 2673 } else { | 2547 } else { |
| 2674 assert(invariant(node, element.isFunction, | 2548 assert(invariant(node, element.isFunction, |
| 2675 message: "Unexpected local $element.")); | 2549 message: "Unexpected local $element.")); |
| 2676 error = reportAndCreateErroneousElement( | 2550 error = reportAndCreateErroneousElement( |
| 2677 node.selector, name.text, | 2551 node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {}); |
| 2678 MessageKind.ASSIGNING_METHOD, const {}); | |
| 2679 semantics = new StaticAccess.localFunction(element); | 2552 semantics = new StaticAccess.localFunction(element); |
| 2680 } | 2553 } |
| 2681 if (isPotentiallyMutableTarget(element)) { | 2554 if (isPotentiallyMutableTarget(element)) { |
| 2682 registry.registerPotentialMutation(element, node); | 2555 registry.registerPotentialMutation(element, node); |
| 2683 if (enclosingElement != element.enclosingElement) { | 2556 if (enclosingElement != element.enclosingElement) { |
| 2684 registry.registerPotentialMutationInClosure(element, node); | 2557 registry.registerPotentialMutationInClosure(element, node); |
| 2685 } | 2558 } |
| 2686 for (Node scope in promotionScope) { | 2559 for (Node scope in promotionScope) { |
| 2687 registry.registerPotentialMutationIn(scope, element, node); | 2560 registry.registerPotentialMutationIn(scope, element, node); |
| 2688 } | 2561 } |
| 2689 } | 2562 } |
| 2690 | 2563 |
| 2691 ResolutionResult result = handleUpdate(node, name, semantics); | 2564 ResolutionResult result = handleUpdate(node, name, semantics); |
| 2692 if (error != null) { | 2565 if (error != null) { |
| 2693 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2566 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2694 // TODO(23998): Remove this when all information goes through | 2567 // TODO(23998): Remove this when all information goes through |
| 2695 // the [SendStructure]. | 2568 // the [SendStructure]. |
| 2696 registry.useElement(node, error); | 2569 registry.useElement(node, error); |
| 2697 } | 2570 } |
| 2698 return result; | 2571 return result; |
| 2699 } | 2572 } |
| 2700 | 2573 |
| 2701 /// Handle access of a static or top level [element]. | 2574 /// Handle access of a static or top level [element]. |
| 2702 ResolutionResult handleStaticOrTopLevelAccess( | 2575 ResolutionResult handleStaticOrTopLevelAccess( |
| 2703 Send node, Name name, Element element) { | 2576 Send node, Name name, Element element) { |
| 2704 ResolutionResult result = const NoneResult(); | 2577 ResolutionResult result = const NoneResult(); |
| 2705 MemberElement member; | 2578 MemberElement member; |
| 2706 if (element.isAbstractField) { | 2579 if (element.isAbstractField) { |
| 2707 AbstractFieldElement abstractField = element; | 2580 AbstractFieldElement abstractField = element; |
| 2708 if (abstractField.getter != null) { | 2581 if (abstractField.getter != null) { |
| 2709 member = abstractField.getter; | 2582 member = abstractField.getter; |
| 2710 } else { | 2583 } else { |
| 2711 member = abstractField.setter; | 2584 member = abstractField.setter; |
| 2712 } | 2585 } |
| 2713 } else { | 2586 } else { |
| 2714 member = element; | 2587 member = element; |
| 2715 } | 2588 } |
| 2716 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2589 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
| 2717 // of parse errors to make [element] erroneous. Fix this! | 2590 // of parse errors to make [element] erroneous. Fix this! |
| 2718 member.computeType(resolution); | 2591 member.computeType(resolution); |
| 2719 | 2592 |
| 2720 | |
| 2721 if (member == compiler.mirrorSystemGetNameFunction && | 2593 if (member == compiler.mirrorSystemGetNameFunction && |
| 2722 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 2594 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
| 2723 reporter.reportHintMessage( | 2595 reporter |
| 2724 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, | 2596 .reportHintMessage(node.selector, MessageKind.STATIC_FUNCTION_BLOAT, { |
| 2725 {'class': compiler.mirrorSystemClass.name, | 2597 'class': compiler.mirrorSystemClass.name, |
| 2726 'name': compiler.mirrorSystemGetNameFunction.name}); | 2598 'name': compiler.mirrorSystemGetNameFunction.name |
| 2599 }); |
| 2727 } | 2600 } |
| 2728 | 2601 |
| 2729 Selector selector; | 2602 Selector selector; |
| 2730 AccessSemantics semantics = | 2603 AccessSemantics semantics = |
| 2731 computeStaticOrTopLevelAccessSemantics(node, member); | 2604 computeStaticOrTopLevelAccessSemantics(node, member); |
| 2732 if (node.isCall) { | 2605 if (node.isCall) { |
| 2733 ArgumentsResult argumentsResult = | 2606 ArgumentsResult argumentsResult = resolveArguments(node.argumentsNode); |
| 2734 resolveArguments(node.argumentsNode); | |
| 2735 CallStructure callStructure = argumentsResult.callStructure; | 2607 CallStructure callStructure = argumentsResult.callStructure; |
| 2736 selector = new Selector.call(name, callStructure); | 2608 selector = new Selector.call(name, callStructure); |
| 2737 | 2609 |
| 2738 bool isIncompatibleInvoke = false; | 2610 bool isIncompatibleInvoke = false; |
| 2739 switch (semantics.kind) { | 2611 switch (semantics.kind) { |
| 2740 case AccessKind.STATIC_METHOD: | 2612 case AccessKind.STATIC_METHOD: |
| 2741 case AccessKind.TOPLEVEL_METHOD: | 2613 case AccessKind.TOPLEVEL_METHOD: |
| 2742 MethodElement method = semantics.element; | 2614 MethodElement method = semantics.element; |
| 2743 method.computeType(resolution); | 2615 method.computeType(resolution); |
| 2744 if (!callStructure.signatureApplies(method.functionSignature)) { | 2616 if (!callStructure.signatureApplies(method.functionSignature)) { |
| 2745 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2617 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2746 registry.registerDynamicUse( | 2618 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 2747 new DynamicUse(selector, null)); | |
| 2748 isIncompatibleInvoke = true; | 2619 isIncompatibleInvoke = true; |
| 2749 } else { | 2620 } else { |
| 2750 registry.registerStaticUse( | 2621 registry.registerStaticUse( |
| 2751 new StaticUse.staticInvoke(semantics.element, callStructure)); | 2622 new StaticUse.staticInvoke(semantics.element, callStructure)); |
| 2752 handleForeignCall(node, semantics.element, callStructure); | 2623 handleForeignCall(node, semantics.element, callStructure); |
| 2753 if (method == compiler.identicalFunction && | 2624 if (method == compiler.identicalFunction && |
| 2754 argumentsResult.isValidAsConstant) { | 2625 argumentsResult.isValidAsConstant) { |
| 2755 result = new ConstantResult(node, | 2626 result = new ConstantResult( |
| 2627 node, |
| 2756 new IdenticalConstantExpression( | 2628 new IdenticalConstantExpression( |
| 2757 argumentsResult.argumentResults[0].constant, | 2629 argumentsResult.argumentResults[0].constant, |
| 2758 argumentsResult.argumentResults[1].constant)); | 2630 argumentsResult.argumentResults[1].constant)); |
| 2759 } | 2631 } |
| 2760 } | 2632 } |
| 2761 break; | 2633 break; |
| 2762 case AccessKind.STATIC_FIELD: | 2634 case AccessKind.STATIC_FIELD: |
| 2763 case AccessKind.FINAL_STATIC_FIELD: | 2635 case AccessKind.FINAL_STATIC_FIELD: |
| 2764 case AccessKind.STATIC_GETTER: | 2636 case AccessKind.STATIC_GETTER: |
| 2765 case AccessKind.TOPLEVEL_FIELD: | 2637 case AccessKind.TOPLEVEL_FIELD: |
| 2766 case AccessKind.FINAL_TOPLEVEL_FIELD: | 2638 case AccessKind.FINAL_TOPLEVEL_FIELD: |
| 2767 case AccessKind.TOPLEVEL_GETTER: | 2639 case AccessKind.TOPLEVEL_GETTER: |
| 2768 registry.registerStaticUse( | 2640 registry |
| 2769 new StaticUse.staticGet(semantics.element)); | 2641 .registerStaticUse(new StaticUse.staticGet(semantics.element)); |
| 2770 selector = callStructure.callSelector; | 2642 selector = callStructure.callSelector; |
| 2771 registry.registerDynamicUse( | 2643 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 2772 new DynamicUse(selector, null)); | |
| 2773 break; | 2644 break; |
| 2774 case AccessKind.STATIC_SETTER: | 2645 case AccessKind.STATIC_SETTER: |
| 2775 case AccessKind.TOPLEVEL_SETTER: | 2646 case AccessKind.TOPLEVEL_SETTER: |
| 2776 case AccessKind.UNRESOLVED: | 2647 case AccessKind.UNRESOLVED: |
| 2777 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2648 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2778 member = reportAndCreateErroneousElement( | 2649 member = reportAndCreateErroneousElement(node.selector, name.text, |
| 2779 node.selector, name.text, | 2650 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, {'name': name}); |
| 2780 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, | |
| 2781 {'name': name}); | |
| 2782 break; | 2651 break; |
| 2783 default: | 2652 default: |
| 2784 reporter.internalError(node, | 2653 reporter.internalError( |
| 2785 "Unexpected statically resolved access $semantics."); | 2654 node, "Unexpected statically resolved access $semantics."); |
| 2786 break; | 2655 break; |
| 2787 } | 2656 } |
| 2788 registry.registerSendStructure(node, | 2657 registry.registerSendStructure( |
| 2658 node, |
| 2789 isIncompatibleInvoke | 2659 isIncompatibleInvoke |
| 2790 ? new IncompatibleInvokeStructure(semantics, selector) | 2660 ? new IncompatibleInvokeStructure(semantics, selector) |
| 2791 : new InvokeStructure(semantics, selector)); | 2661 : new InvokeStructure(semantics, selector)); |
| 2792 } else { | 2662 } else { |
| 2793 selector = new Selector.getter(name); | 2663 selector = new Selector.getter(name); |
| 2794 switch (semantics.kind) { | 2664 switch (semantics.kind) { |
| 2795 case AccessKind.STATIC_METHOD: | 2665 case AccessKind.STATIC_METHOD: |
| 2796 case AccessKind.TOPLEVEL_METHOD: | 2666 case AccessKind.TOPLEVEL_METHOD: |
| 2797 registry.registerStaticUse( | 2667 registry.registerStaticUse( |
| 2798 new StaticUse.staticTearOff(semantics.element)); | 2668 new StaticUse.staticTearOff(semantics.element)); |
| 2799 break; | 2669 break; |
| 2800 case AccessKind.STATIC_FIELD: | 2670 case AccessKind.STATIC_FIELD: |
| 2801 case AccessKind.FINAL_STATIC_FIELD: | 2671 case AccessKind.FINAL_STATIC_FIELD: |
| 2802 case AccessKind.STATIC_GETTER: | 2672 case AccessKind.STATIC_GETTER: |
| 2803 case AccessKind.TOPLEVEL_FIELD: | 2673 case AccessKind.TOPLEVEL_FIELD: |
| 2804 case AccessKind.FINAL_TOPLEVEL_FIELD: | 2674 case AccessKind.FINAL_TOPLEVEL_FIELD: |
| 2805 case AccessKind.TOPLEVEL_GETTER: | 2675 case AccessKind.TOPLEVEL_GETTER: |
| 2806 registry.registerStaticUse( | 2676 registry |
| 2807 new StaticUse.staticGet(semantics.element)); | 2677 .registerStaticUse(new StaticUse.staticGet(semantics.element)); |
| 2808 break; | 2678 break; |
| 2809 case AccessKind.STATIC_SETTER: | 2679 case AccessKind.STATIC_SETTER: |
| 2810 case AccessKind.TOPLEVEL_SETTER: | 2680 case AccessKind.TOPLEVEL_SETTER: |
| 2811 case AccessKind.UNRESOLVED: | 2681 case AccessKind.UNRESOLVED: |
| 2812 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2682 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2813 member = reportAndCreateErroneousElement( | 2683 member = reportAndCreateErroneousElement(node.selector, name.text, |
| 2814 node.selector, name.text, | 2684 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, {'name': name}); |
| 2815 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, | |
| 2816 {'name': name}); | |
| 2817 break; | 2685 break; |
| 2818 default: | 2686 default: |
| 2819 reporter.internalError(node, | 2687 reporter.internalError( |
| 2820 "Unexpected statically resolved access $semantics."); | 2688 node, "Unexpected statically resolved access $semantics."); |
| 2821 break; | 2689 break; |
| 2822 } | 2690 } |
| 2823 registry.registerSendStructure(node, new GetStructure(semantics)); | 2691 registry.registerSendStructure(node, new GetStructure(semantics)); |
| 2824 if (member.isConst) { | 2692 if (member.isConst) { |
| 2825 FieldElement field = member; | 2693 FieldElement field = member; |
| 2826 result = new ConstantResult( | 2694 result = new ConstantResult(node, new VariableConstantExpression(field), |
| 2827 node, new VariableConstantExpression(field), element: field); | 2695 element: field); |
| 2828 } else { | 2696 } else { |
| 2829 result = new ElementResult(member); | 2697 result = new ElementResult(member); |
| 2830 } | 2698 } |
| 2831 } | 2699 } |
| 2832 | 2700 |
| 2833 // TODO(23998): Remove these when all information goes through | 2701 // TODO(23998): Remove these when all information goes through |
| 2834 // the [SendStructure]. | 2702 // the [SendStructure]. |
| 2835 registry.useElement(node, member); | 2703 registry.useElement(node, member); |
| 2836 registry.setSelector(node, selector); | 2704 registry.setSelector(node, selector); |
| 2837 | 2705 |
| 2838 return result; | 2706 return result; |
| 2839 } | 2707 } |
| 2840 | 2708 |
| 2841 /// Handle update of a static or top level [element]. | 2709 /// Handle update of a static or top level [element]. |
| 2842 ResolutionResult handleStaticOrTopLevelUpdate( | 2710 ResolutionResult handleStaticOrTopLevelUpdate( |
| 2843 SendSet node, Name name, Element element) { | 2711 SendSet node, Name name, Element element) { |
| 2844 AccessSemantics semantics; | 2712 AccessSemantics semantics; |
| 2845 if (element.isAbstractField) { | 2713 if (element.isAbstractField) { |
| 2846 AbstractFieldElement abstractField = element; | 2714 AbstractFieldElement abstractField = element; |
| 2847 if (abstractField.setter == null) { | 2715 if (abstractField.setter == null) { |
| 2848 ErroneousElement error = reportAndCreateErroneousElement( | 2716 ErroneousElement error = reportAndCreateErroneousElement( |
| 2849 node.selector, name.text, | 2717 node.selector, |
| 2718 name.text, |
| 2850 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, | 2719 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, |
| 2851 {'name': name}); | 2720 {'name': name}); |
| 2852 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2721 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2853 | 2722 |
| 2854 if (node.isComplex) { | 2723 if (node.isComplex) { |
| 2855 // `a++` or `a += b` where `a` has no setter. | 2724 // `a++` or `a += b` where `a` has no setter. |
| 2856 semantics = new CompoundAccessSemantics( | 2725 semantics = new CompoundAccessSemantics( |
| 2857 element.isTopLevel | 2726 element.isTopLevel |
| 2858 ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER | 2727 ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER |
| 2859 : CompoundAccessKind.UNRESOLVED_STATIC_SETTER, | 2728 : CompoundAccessKind.UNRESOLVED_STATIC_SETTER, |
| 2860 abstractField.getter, | 2729 abstractField.getter, |
| 2861 error); | 2730 error); |
| 2862 } else { | 2731 } else { |
| 2863 // `a = b` where `a` has no setter. | 2732 // `a = b` where `a` has no setter. |
| 2864 semantics = element.isTopLevel | 2733 semantics = element.isTopLevel |
| 2865 ? new StaticAccess.topLevelGetter(abstractField.getter) | 2734 ? new StaticAccess.topLevelGetter(abstractField.getter) |
| 2866 : new StaticAccess.staticGetter(abstractField.getter); | 2735 : new StaticAccess.staticGetter(abstractField.getter); |
| 2867 } | 2736 } |
| 2868 registry.registerStaticUse( | 2737 registry |
| 2869 new StaticUse.staticGet(abstractField.getter)); | 2738 .registerStaticUse(new StaticUse.staticGet(abstractField.getter)); |
| 2870 } else if (node.isComplex) { | 2739 } else if (node.isComplex) { |
| 2871 if (abstractField.getter == null) { | 2740 if (abstractField.getter == null) { |
| 2872 ErroneousElement error = reportAndCreateErroneousElement( | 2741 ErroneousElement error = reportAndCreateErroneousElement( |
| 2873 node.selector, name.text, | 2742 node.selector, |
| 2743 name.text, |
| 2874 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, | 2744 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, |
| 2875 {'name': name}); | 2745 {'name': name}); |
| 2876 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2746 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2877 // `a++` or `a += b` where `a` has no getter. | 2747 // `a++` or `a += b` where `a` has no getter. |
| 2878 semantics = new CompoundAccessSemantics( | 2748 semantics = new CompoundAccessSemantics( |
| 2879 element.isTopLevel | 2749 element.isTopLevel |
| 2880 ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER | 2750 ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER |
| 2881 : CompoundAccessKind.UNRESOLVED_STATIC_GETTER, | 2751 : CompoundAccessKind.UNRESOLVED_STATIC_GETTER, |
| 2882 error, | 2752 error, |
| 2883 abstractField.setter); | 2753 abstractField.setter); |
| 2884 registry.registerStaticUse( | 2754 registry |
| 2885 new StaticUse.staticSet(abstractField.setter)); | 2755 .registerStaticUse(new StaticUse.staticSet(abstractField.setter)); |
| 2886 } else { | 2756 } else { |
| 2887 // `a++` or `a += b` where `a` has both a getter and a setter. | 2757 // `a++` or `a += b` where `a` has both a getter and a setter. |
| 2888 semantics = new CompoundAccessSemantics( | 2758 semantics = new CompoundAccessSemantics( |
| 2889 element.isTopLevel | 2759 element.isTopLevel |
| 2890 ? CompoundAccessKind.TOPLEVEL_GETTER_SETTER | 2760 ? CompoundAccessKind.TOPLEVEL_GETTER_SETTER |
| 2891 : CompoundAccessKind.STATIC_GETTER_SETTER, | 2761 : CompoundAccessKind.STATIC_GETTER_SETTER, |
| 2892 abstractField.getter, | 2762 abstractField.getter, |
| 2893 abstractField.setter); | 2763 abstractField.setter); |
| 2894 registry.registerStaticUse( | 2764 registry |
| 2895 new StaticUse.staticGet(abstractField.getter)); | 2765 .registerStaticUse(new StaticUse.staticGet(abstractField.getter)); |
| 2896 registry.registerStaticUse( | 2766 registry |
| 2897 new StaticUse.staticSet(abstractField.setter)); | 2767 .registerStaticUse(new StaticUse.staticSet(abstractField.setter)); |
| 2898 } | 2768 } |
| 2899 } else { | 2769 } else { |
| 2900 // `a = b` where `a` has a setter. | 2770 // `a = b` where `a` has a setter. |
| 2901 semantics = element.isTopLevel | 2771 semantics = element.isTopLevel |
| 2902 ? new StaticAccess.topLevelSetter(abstractField.setter) | 2772 ? new StaticAccess.topLevelSetter(abstractField.setter) |
| 2903 : new StaticAccess.staticSetter(abstractField.setter); | 2773 : new StaticAccess.staticSetter(abstractField.setter); |
| 2904 registry.registerStaticUse( | 2774 registry |
| 2905 new StaticUse.staticSet(abstractField.setter)); | 2775 .registerStaticUse(new StaticUse.staticSet(abstractField.setter)); |
| 2906 } | 2776 } |
| 2907 } else { | 2777 } else { |
| 2908 MemberElement member = element; | 2778 MemberElement member = element; |
| 2909 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2779 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
| 2910 // of parse errors to make [element] erroneous. Fix this! | 2780 // of parse errors to make [element] erroneous. Fix this! |
| 2911 member.computeType(resolution); | 2781 member.computeType(resolution); |
| 2912 if (member.isMalformed) { | 2782 if (member.isMalformed) { |
| 2913 // [member] has parse errors. | 2783 // [member] has parse errors. |
| 2914 semantics = new StaticAccess.unresolved(member); | 2784 semantics = new StaticAccess.unresolved(member); |
| 2915 } else if (member.isFunction) { | 2785 } else if (member.isFunction) { |
| 2916 // `a = b`, `a++` or `a += b` where `a` is a function. | 2786 // `a = b`, `a++` or `a += b` where `a` is a function. |
| 2917 ErroneousElement error = reportAndCreateErroneousElement( | 2787 ErroneousElement error = reportAndCreateErroneousElement( |
| 2918 node.selector, name.text, | 2788 node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {}); |
| 2919 MessageKind.ASSIGNING_METHOD, const {}); | |
| 2920 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2789 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2921 if (node.isComplex) { | 2790 if (node.isComplex) { |
| 2922 // `a++` or `a += b` where `a` is a function. | 2791 // `a++` or `a += b` where `a` is a function. |
| 2923 registry.registerStaticUse( | 2792 registry.registerStaticUse(new StaticUse.staticTearOff(element)); |
| 2924 new StaticUse.staticTearOff(element)); | |
| 2925 } | 2793 } |
| 2926 semantics = member.isTopLevel | 2794 semantics = member.isTopLevel |
| 2927 ? new StaticAccess.topLevelMethod(member) | 2795 ? new StaticAccess.topLevelMethod(member) |
| 2928 : new StaticAccess.staticMethod(member); | 2796 : new StaticAccess.staticMethod(member); |
| 2929 } else { | 2797 } else { |
| 2930 // `a = b`, `a++` or `a += b` where `a` is a field. | 2798 // `a = b`, `a++` or `a += b` where `a` is a field. |
| 2931 assert(invariant(node, member.isField, | 2799 assert(invariant(node, member.isField, |
| 2932 message: "Unexpected element: $member.")); | 2800 message: "Unexpected element: $member.")); |
| 2933 if (node.isComplex) { | 2801 if (node.isComplex) { |
| 2934 // `a++` or `a += b` where `a` is a field. | 2802 // `a++` or `a += b` where `a` is a field. |
| 2935 registry.registerStaticUse(new StaticUse.staticGet(member)); | 2803 registry.registerStaticUse(new StaticUse.staticGet(member)); |
| 2936 } | 2804 } |
| 2937 if (member.isFinal || member.isConst) { | 2805 if (member.isFinal || member.isConst) { |
| 2938 ErroneousElement error = reportAndCreateErroneousElement( | 2806 ErroneousElement error = reportAndCreateErroneousElement( |
| 2939 node.selector, name.text, | 2807 node.selector, |
| 2940 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, | 2808 name.text, |
| 2941 {'name': name}); | 2809 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, |
| 2810 {'name': name}); |
| 2942 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2811 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2943 semantics = member.isTopLevel | 2812 semantics = member.isTopLevel |
| 2944 ? new StaticAccess.finalTopLevelField(member) | 2813 ? new StaticAccess.finalTopLevelField(member) |
| 2945 : new StaticAccess.finalStaticField(member); | 2814 : new StaticAccess.finalStaticField(member); |
| 2946 } else { | 2815 } else { |
| 2947 registry.registerStaticUse(new StaticUse.staticSet(member)); | 2816 registry.registerStaticUse(new StaticUse.staticSet(member)); |
| 2948 semantics = member.isTopLevel | 2817 semantics = member.isTopLevel |
| 2949 ? new StaticAccess.topLevelField(member) | 2818 ? new StaticAccess.topLevelField(member) |
| 2950 : new StaticAccess.staticField(member); | 2819 : new StaticAccess.staticField(member); |
| 2951 } | 2820 } |
| 2952 } | 2821 } |
| 2953 } | 2822 } |
| 2954 return handleUpdate(node, name, semantics); | 2823 return handleUpdate(node, name, semantics); |
| 2955 } | 2824 } |
| 2956 | 2825 |
| 2957 /// Handle access to resolved [element]. | 2826 /// Handle access to resolved [element]. |
| 2958 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { | 2827 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { |
| 2959 if (element.isAmbiguous) { | 2828 if (element.isAmbiguous) { |
| 2960 return handleAmbiguousSend(node, name, element); | 2829 return handleAmbiguousSend(node, name, element); |
| 2961 } | 2830 } |
| 2962 if (element.isMalformed) { | 2831 if (element.isMalformed) { |
| 2963 // This handles elements with parser errors. | 2832 // This handles elements with parser errors. |
| 2964 assert(invariant(node, element is! ErroneousElement, | 2833 assert(invariant(node, element is! ErroneousElement, |
| 2965 message: "Unexpected erroneous element $element.")); | 2834 message: "Unexpected erroneous element $element.")); |
| 2966 return handleErroneousAccess(node, name, | 2835 return handleErroneousAccess( |
| 2967 new StaticAccess.unresolved(element)); | 2836 node, name, new StaticAccess.unresolved(element)); |
| 2968 } | 2837 } |
| 2969 if (element.isInstanceMember) { | 2838 if (element.isInstanceMember) { |
| 2970 if (inInstanceContext) { | 2839 if (inInstanceContext) { |
| 2971 // TODO(johnniwinther): Maybe use the found [element]. | 2840 // TODO(johnniwinther): Maybe use the found [element]. |
| 2972 return handleThisPropertyAccess(node, name); | 2841 return handleThisPropertyAccess(node, name); |
| 2973 } else { | 2842 } else { |
| 2974 return handleErroneousAccess( | 2843 return handleErroneousAccess( |
| 2975 node, name, reportStaticInstanceAccess(node, name)); | 2844 node, name, reportStaticInstanceAccess(node, name)); |
| 2976 } | 2845 } |
| 2977 } | 2846 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2996 /// Handle update to resolved [element]. | 2865 /// Handle update to resolved [element]. |
| 2997 ResolutionResult handleResolvedSendSet( | 2866 ResolutionResult handleResolvedSendSet( |
| 2998 SendSet node, Name name, Element element) { | 2867 SendSet node, Name name, Element element) { |
| 2999 if (element.isAmbiguous) { | 2868 if (element.isAmbiguous) { |
| 3000 return handleAmbiguousUpdate(node, name, element); | 2869 return handleAmbiguousUpdate(node, name, element); |
| 3001 } | 2870 } |
| 3002 if (element.isMalformed) { | 2871 if (element.isMalformed) { |
| 3003 // This handles elements with parser errors.. | 2872 // This handles elements with parser errors.. |
| 3004 assert(invariant(node, element is! ErroneousElement, | 2873 assert(invariant(node, element is! ErroneousElement, |
| 3005 message: "Unexpected erroneous element $element.")); | 2874 message: "Unexpected erroneous element $element.")); |
| 3006 return handleUpdate(node, name,new StaticAccess.unresolved(element)); | 2875 return handleUpdate(node, name, new StaticAccess.unresolved(element)); |
| 3007 } | 2876 } |
| 3008 if (element.isInstanceMember) { | 2877 if (element.isInstanceMember) { |
| 3009 if (inInstanceContext) { | 2878 if (inInstanceContext) { |
| 3010 return handleThisPropertyUpdate(node, name, element); | 2879 return handleThisPropertyUpdate(node, name, element); |
| 3011 } else { | 2880 } else { |
| 3012 return handleUpdate(node, name, reportStaticInstanceAccess(node, name)); | 2881 return handleUpdate(node, name, reportStaticInstanceAccess(node, name)); |
| 3013 } | 2882 } |
| 3014 } | 2883 } |
| 3015 if (element.isClass) { | 2884 if (element.isClass) { |
| 3016 // `C = b`, `C++`, or 'C += b` where 'C' is a class. | 2885 // `C = b`, `C++`, or 'C += b` where 'C' is a class. |
| 3017 return handleClassTypeLiteralUpdate(node, name, element); | 2886 return handleClassTypeLiteralUpdate(node, name, element); |
| 3018 } else if (element.isTypedef) { | 2887 } else if (element.isTypedef) { |
| 3019 // `C = b`, `C++`, or 'C += b` where 'F' is a typedef. | 2888 // `C = b`, `C++`, or 'C += b` where 'F' is a typedef. |
| 3020 return handleTypedefTypeLiteralUpdate(node, name, element); | 2889 return handleTypedefTypeLiteralUpdate(node, name, element); |
| 3021 } else if (element.isTypeVariable) { | 2890 } else if (element.isTypeVariable) { |
| 3022 // `T = b`, `T++`, or 'T += b` where 'T' is a type variable. | 2891 // `T = b`, `T++`, or 'T += b` where 'T' is a type variable. |
| 3023 return handleTypeVariableTypeLiteralUpdate(node, name, element); | 2892 return handleTypeVariableTypeLiteralUpdate(node, name, element); |
| 3024 } else if (element.isPrefix) { | 2893 } else if (element.isPrefix) { |
| 3025 // `p = b` where `p` is a prefix. | 2894 // `p = b` where `p` is a prefix. |
| 3026 ErroneousElement error = reportAndCreateErroneousElement( | 2895 ErroneousElement error = reportAndCreateErroneousElement( |
| 3027 node, | 2896 node, name.text, MessageKind.PREFIX_AS_EXPRESSION, {'prefix': name}, |
| 3028 name.text, | 2897 isError: true); |
| 3029 MessageKind.PREFIX_AS_EXPRESSION, | |
| 3030 {'prefix': name}, | |
| 3031 isError: true); | |
| 3032 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 2898 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
| 3033 return handleUpdate( | 2899 return handleUpdate(node, name, new StaticAccess.invalid(error)); |
| 3034 node, name, new StaticAccess.invalid(error)); | |
| 3035 } else if (element.isLocal) { | 2900 } else if (element.isLocal) { |
| 3036 return handleLocalUpdate(node, name, element); | 2901 return handleLocalUpdate(node, name, element); |
| 3037 } else if (element.isStatic || element.isTopLevel) { | 2902 } else if (element.isStatic || element.isTopLevel) { |
| 3038 return handleStaticOrTopLevelUpdate(node, name, element); | 2903 return handleStaticOrTopLevelUpdate(node, name, element); |
| 3039 } | 2904 } |
| 3040 return reporter.internalError(node, "Unexpected resolved send: $element"); | 2905 return reporter.internalError(node, "Unexpected resolved send: $element"); |
| 3041 } | 2906 } |
| 3042 | 2907 |
| 3043 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 2908 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
| 3044 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 2909 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3117 if (isPotentiallyMutableTarget(target)) { | 2982 if (isPotentiallyMutableTarget(target)) { |
| 3118 if (enclosingElement != target.enclosingElement) { | 2983 if (enclosingElement != target.enclosingElement) { |
| 3119 for (Node scope in promotionScope) { | 2984 for (Node scope in promotionScope) { |
| 3120 registry.setAccessedByClosureIn(scope, target, node); | 2985 registry.setAccessedByClosureIn(scope, target, node); |
| 3121 } | 2986 } |
| 3122 } | 2987 } |
| 3123 } | 2988 } |
| 3124 } | 2989 } |
| 3125 | 2990 |
| 3126 // TODO(johnniwinther): Move this to the backend resolution callbacks. | 2991 // TODO(johnniwinther): Move this to the backend resolution callbacks. |
| 3127 void handleForeignCall(Send node, | 2992 void handleForeignCall( |
| 3128 Element target, | 2993 Send node, Element target, CallStructure callStructure) { |
| 3129 CallStructure callStructure) { | |
| 3130 if (target != null && compiler.backend.isForeign(target)) { | 2994 if (target != null && compiler.backend.isForeign(target)) { |
| 3131 registry.registerForeignCall(node, target, callStructure, this); | 2995 registry.registerForeignCall(node, target, callStructure, this); |
| 3132 } | 2996 } |
| 3133 } | 2997 } |
| 3134 | 2998 |
| 3135 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. | 2999 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. |
| 3136 DartType resolveTypeFromString(Node node, String typeName) { | 3000 DartType resolveTypeFromString(Node node, String typeName) { |
| 3137 Element element = lookupInScope(reporter, node, scope, typeName); | 3001 Element element = lookupInScope(reporter, node, scope, typeName); |
| 3138 if (element == null) return null; | 3002 if (element == null) return null; |
| 3139 if (element is! ClassElement) return null; | 3003 if (element is! ClassElement) return null; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3157 Selector setterSelector = new Selector.indexSet(); | 3021 Selector setterSelector = new Selector.indexSet(); |
| 3158 Selector operatorSelector = | 3022 Selector operatorSelector = |
| 3159 new Selector.binaryOperator(operator.selectorName); | 3023 new Selector.binaryOperator(operator.selectorName); |
| 3160 | 3024 |
| 3161 // TODO(23998): Remove these when selectors are only accessed | 3025 // TODO(23998): Remove these when selectors are only accessed |
| 3162 // through the send structure. | 3026 // through the send structure. |
| 3163 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3027 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 3164 registry.setSelector(node, setterSelector); | 3028 registry.setSelector(node, setterSelector); |
| 3165 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3029 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| 3166 | 3030 |
| 3167 registry.registerDynamicUse( | 3031 registry.registerDynamicUse(new DynamicUse(getterSelector, null)); |
| 3168 new DynamicUse(getterSelector, null)); | 3032 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
| 3169 registry.registerDynamicUse( | 3033 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
| 3170 new DynamicUse(setterSelector, null)); | |
| 3171 registry.registerDynamicUse( | |
| 3172 new DynamicUse(operatorSelector, null)); | |
| 3173 | 3034 |
| 3174 SendStructure sendStructure = node.isPrefix | 3035 SendStructure sendStructure = node.isPrefix |
| 3175 ? new IndexPrefixStructure(semantics, operator) | 3036 ? new IndexPrefixStructure(semantics, operator) |
| 3176 : new IndexPostfixStructure(semantics, operator); | 3037 : new IndexPostfixStructure(semantics, operator); |
| 3177 registry.registerSendStructure(node, sendStructure); | 3038 registry.registerSendStructure(node, sendStructure); |
| 3178 return const NoneResult(); | 3039 return const NoneResult(); |
| 3179 } else { | 3040 } else { |
| 3180 Node rhs = node.arguments.tail.head; | 3041 Node rhs = node.arguments.tail.head; |
| 3181 visitExpression(rhs); | 3042 visitExpression(rhs); |
| 3182 | 3043 |
| 3183 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 3044 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
| 3184 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 3045 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
| 3185 // `a[b] = c`. | 3046 // `a[b] = c`. |
| 3186 Selector setterSelector = new Selector.indexSet(); | 3047 Selector setterSelector = new Selector.indexSet(); |
| 3187 | 3048 |
| 3188 // TODO(23998): Remove this when selectors are only accessed | 3049 // TODO(23998): Remove this when selectors are only accessed |
| 3189 // through the send structure. | 3050 // through the send structure. |
| 3190 registry.setSelector(node, setterSelector); | 3051 registry.setSelector(node, setterSelector); |
| 3191 registry.registerDynamicUse( | 3052 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
| 3192 new DynamicUse(setterSelector, null)); | |
| 3193 | 3053 |
| 3194 SendStructure sendStructure = new IndexSetStructure(semantics); | 3054 SendStructure sendStructure = new IndexSetStructure(semantics); |
| 3195 registry.registerSendStructure(node, sendStructure); | 3055 registry.registerSendStructure(node, sendStructure); |
| 3196 return const NoneResult(); | 3056 return const NoneResult(); |
| 3197 } else { | 3057 } else { |
| 3198 // `a[b] += c`. | 3058 // `a[b] += c`. |
| 3199 Selector getterSelector = new Selector.index(); | 3059 Selector getterSelector = new Selector.index(); |
| 3200 Selector setterSelector = new Selector.indexSet(); | 3060 Selector setterSelector = new Selector.indexSet(); |
| 3201 Selector operatorSelector = | 3061 Selector operatorSelector = |
| 3202 new Selector.binaryOperator(operator.selectorName); | 3062 new Selector.binaryOperator(operator.selectorName); |
| 3203 | 3063 |
| 3204 // TODO(23998): Remove these when selectors are only accessed | 3064 // TODO(23998): Remove these when selectors are only accessed |
| 3205 // through the send structure. | 3065 // through the send structure. |
| 3206 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3066 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 3207 registry.setSelector(node, setterSelector); | 3067 registry.setSelector(node, setterSelector); |
| 3208 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3068 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| 3209 | 3069 |
| 3210 registry.registerDynamicUse( | 3070 registry.registerDynamicUse(new DynamicUse(getterSelector, null)); |
| 3211 new DynamicUse(getterSelector, null)); | 3071 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
| 3212 registry.registerDynamicUse( | 3072 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
| 3213 new DynamicUse(setterSelector, null)); | |
| 3214 registry.registerDynamicUse( | |
| 3215 new DynamicUse(operatorSelector, null)); | |
| 3216 | 3073 |
| 3217 SendStructure sendStructure; | 3074 SendStructure sendStructure; |
| 3218 if (operator.kind == AssignmentOperatorKind.IF_NULL) { | 3075 if (operator.kind == AssignmentOperatorKind.IF_NULL) { |
| 3219 sendStructure = new IndexSetIfNullStructure(semantics); | 3076 sendStructure = new IndexSetIfNullStructure(semantics); |
| 3220 } else { | 3077 } else { |
| 3221 sendStructure = new CompoundIndexSetStructure(semantics, operator); | 3078 sendStructure = new CompoundIndexSetStructure(semantics, operator); |
| 3222 } | 3079 } |
| 3223 registry.registerSendStructure(node, sendStructure); | 3080 registry.registerSendStructure(node, sendStructure); |
| 3224 return const NoneResult(); | 3081 return const NoneResult(); |
| 3225 } | 3082 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3244 new Selector.binaryOperator(operator.selectorName); | 3101 new Selector.binaryOperator(operator.selectorName); |
| 3245 | 3102 |
| 3246 // TODO(23998): Remove these when selectors are only accessed | 3103 // TODO(23998): Remove these when selectors are only accessed |
| 3247 // through the send structure. | 3104 // through the send structure. |
| 3248 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3105 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 3249 registry.setSelector(node, setterSelector); | 3106 registry.setSelector(node, setterSelector); |
| 3250 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3107 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| 3251 | 3108 |
| 3252 if (semantics == null) { | 3109 if (semantics == null) { |
| 3253 semantics = computeSuperAccessSemanticsForSelectors( | 3110 semantics = computeSuperAccessSemanticsForSelectors( |
| 3254 node, getterSelector, setterSelector, isIndex: true); | 3111 node, getterSelector, setterSelector, |
| 3112 isIndex: true); |
| 3255 | 3113 |
| 3256 if (!semantics.getter.isError) { | 3114 if (!semantics.getter.isError) { |
| 3257 registry.registerStaticUse( | 3115 registry.registerStaticUse(new StaticUse.superInvoke( |
| 3258 new StaticUse.superInvoke( | 3116 semantics.getter, getterSelector.callStructure)); |
| 3259 semantics.getter, getterSelector.callStructure)); | |
| 3260 } | 3117 } |
| 3261 if (!semantics.setter.isError) { | 3118 if (!semantics.setter.isError) { |
| 3262 registry.registerStaticUse( | 3119 registry.registerStaticUse(new StaticUse.superInvoke( |
| 3263 new StaticUse.superInvoke( | 3120 semantics.setter, setterSelector.callStructure)); |
| 3264 semantics.setter, setterSelector.callStructure)); | |
| 3265 } | 3121 } |
| 3266 | 3122 |
| 3267 // TODO(23998): Remove these when elements are only accessed | 3123 // TODO(23998): Remove these when elements are only accessed |
| 3268 // through the send structure. | 3124 // through the send structure. |
| 3269 registry.useElement(node, semantics.setter); | 3125 registry.useElement(node, semantics.setter); |
| 3270 registry.useElement(node.selector, semantics.getter); | 3126 registry.useElement(node.selector, semantics.getter); |
| 3271 } | 3127 } |
| 3272 registry.registerDynamicUse( | 3128 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
| 3273 new DynamicUse(operatorSelector, null)); | |
| 3274 | 3129 |
| 3275 SendStructure sendStructure = node.isPrefix | 3130 SendStructure sendStructure = node.isPrefix |
| 3276 ? new IndexPrefixStructure(semantics, operator) | 3131 ? new IndexPrefixStructure(semantics, operator) |
| 3277 : new IndexPostfixStructure(semantics, operator); | 3132 : new IndexPostfixStructure(semantics, operator); |
| 3278 registry.registerSendStructure(node, sendStructure); | 3133 registry.registerSendStructure(node, sendStructure); |
| 3279 return const NoneResult(); | 3134 return const NoneResult(); |
| 3280 } else { | 3135 } else { |
| 3281 Node rhs = node.arguments.tail.head; | 3136 Node rhs = node.arguments.tail.head; |
| 3282 visitExpression(rhs); | 3137 visitExpression(rhs); |
| 3283 | 3138 |
| 3284 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 3139 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
| 3285 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 3140 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
| 3286 // `super[a] = b`. | 3141 // `super[a] = b`. |
| 3287 Selector setterSelector = new Selector.indexSet(); | 3142 Selector setterSelector = new Selector.indexSet(); |
| 3288 if (semantics == null) { | 3143 if (semantics == null) { |
| 3289 semantics = | 3144 semantics = |
| 3290 computeSuperAccessSemanticsForSelector(node, setterSelector); | 3145 computeSuperAccessSemanticsForSelector(node, setterSelector); |
| 3291 | 3146 |
| 3292 // TODO(23998): Remove these when elements are only accessed | 3147 // TODO(23998): Remove these when elements are only accessed |
| 3293 // through the send structure. | 3148 // through the send structure. |
| 3294 registry.useElement(node, semantics.setter); | 3149 registry.useElement(node, semantics.setter); |
| 3295 } | 3150 } |
| 3296 | 3151 |
| 3297 // TODO(23998): Remove this when selectors are only accessed | 3152 // TODO(23998): Remove this when selectors are only accessed |
| 3298 // through the send structure. | 3153 // through the send structure. |
| 3299 registry.setSelector(node, setterSelector); | 3154 registry.setSelector(node, setterSelector); |
| 3300 if (!semantics.setter.isError) { | 3155 if (!semantics.setter.isError) { |
| 3301 registry.registerStaticUse( | 3156 registry.registerStaticUse(new StaticUse.superInvoke( |
| 3302 new StaticUse.superInvoke( | 3157 semantics.setter, setterSelector.callStructure)); |
| 3303 semantics.setter, setterSelector.callStructure)); | |
| 3304 } | 3158 } |
| 3305 | 3159 |
| 3306 SendStructure sendStructure = new IndexSetStructure(semantics); | 3160 SendStructure sendStructure = new IndexSetStructure(semantics); |
| 3307 registry.registerSendStructure(node, sendStructure); | 3161 registry.registerSendStructure(node, sendStructure); |
| 3308 return const NoneResult(); | 3162 return const NoneResult(); |
| 3309 } else { | 3163 } else { |
| 3310 // `super[a] += b`. | 3164 // `super[a] += b`. |
| 3311 Selector getterSelector = new Selector.index(); | 3165 Selector getterSelector = new Selector.index(); |
| 3312 Selector setterSelector = new Selector.indexSet(); | 3166 Selector setterSelector = new Selector.indexSet(); |
| 3313 Selector operatorSelector = | 3167 Selector operatorSelector = |
| 3314 new Selector.binaryOperator(operator.selectorName); | 3168 new Selector.binaryOperator(operator.selectorName); |
| 3315 if (semantics == null) { | 3169 if (semantics == null) { |
| 3316 semantics = computeSuperAccessSemanticsForSelectors( | 3170 semantics = computeSuperAccessSemanticsForSelectors( |
| 3317 node, getterSelector, setterSelector, isIndex: true); | 3171 node, getterSelector, setterSelector, |
| 3172 isIndex: true); |
| 3318 | 3173 |
| 3319 if (!semantics.getter.isError) { | 3174 if (!semantics.getter.isError) { |
| 3320 registry.registerStaticUse( | 3175 registry.registerStaticUse(new StaticUse.superInvoke( |
| 3321 new StaticUse.superInvoke( | 3176 semantics.getter, getterSelector.callStructure)); |
| 3322 semantics.getter, getterSelector.callStructure)); | |
| 3323 } | 3177 } |
| 3324 if (!semantics.setter.isError) { | 3178 if (!semantics.setter.isError) { |
| 3325 registry.registerStaticUse( | 3179 registry.registerStaticUse(new StaticUse.superInvoke( |
| 3326 new StaticUse.superInvoke( | 3180 semantics.setter, setterSelector.callStructure)); |
| 3327 semantics.setter, setterSelector.callStructure)); | |
| 3328 } | 3181 } |
| 3329 | 3182 |
| 3330 // TODO(23998): Remove these when elements are only accessed | 3183 // TODO(23998): Remove these when elements are only accessed |
| 3331 // through the send structure. | 3184 // through the send structure. |
| 3332 registry.useElement(node, semantics.setter); | 3185 registry.useElement(node, semantics.setter); |
| 3333 registry.useElement(node.selector, semantics.getter); | 3186 registry.useElement(node.selector, semantics.getter); |
| 3334 } | 3187 } |
| 3335 | 3188 |
| 3336 // TODO(23998): Remove these when selectors are only accessed | 3189 // TODO(23998): Remove these when selectors are only accessed |
| 3337 // through the send structure. | 3190 // through the send structure. |
| 3338 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3191 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 3339 registry.setSelector(node, setterSelector); | 3192 registry.setSelector(node, setterSelector); |
| 3340 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3193 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| 3341 | 3194 |
| 3342 registry.registerDynamicUse( | 3195 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
| 3343 new DynamicUse(operatorSelector, null)); | |
| 3344 | 3196 |
| 3345 SendStructure sendStructure; | 3197 SendStructure sendStructure; |
| 3346 if (operator.kind == AssignmentOperatorKind.IF_NULL) { | 3198 if (operator.kind == AssignmentOperatorKind.IF_NULL) { |
| 3347 sendStructure = new IndexSetIfNullStructure(semantics); | 3199 sendStructure = new IndexSetIfNullStructure(semantics); |
| 3348 } else { | 3200 } else { |
| 3349 sendStructure = new CompoundIndexSetStructure(semantics, operator); | 3201 sendStructure = new CompoundIndexSetStructure(semantics, operator); |
| 3350 } | 3202 } |
| 3351 registry.registerSendStructure(node, sendStructure); | 3203 registry.registerSendStructure(node, sendStructure); |
| 3352 return const NoneResult(); | 3204 return const NoneResult(); |
| 3353 } | 3205 } |
| 3354 } | 3206 } |
| 3355 } | 3207 } |
| 3356 | 3208 |
| 3357 /// Handle super index operations like `super.a = b`, `super.a += b`, and | 3209 /// Handle super index operations like `super.a = b`, `super.a += b`, and |
| 3358 /// `super.a++`. | 3210 /// `super.a++`. |
| 3359 // TODO(johnniwinther): Share code with [handleSuperIndexSendSet]. | 3211 // TODO(johnniwinther): Share code with [handleSuperIndexSendSet]. |
| 3360 ResolutionResult handleSuperSendSet(SendSet node) { | 3212 ResolutionResult handleSuperSendSet(SendSet node) { |
| 3361 Identifier selector = node.selector.asIdentifier(); | 3213 Identifier selector = node.selector.asIdentifier(); |
| 3362 String text = selector.source; | 3214 String text = selector.source; |
| 3363 Name name = new Name(text, enclosingElement.library); | 3215 Name name = new Name(text, enclosingElement.library); |
| 3364 String operatorText = node.assignmentOperator.source; | 3216 String operatorText = node.assignmentOperator.source; |
| 3365 Selector getterSelector = new Selector.getter(name); | 3217 Selector getterSelector = new Selector.getter(name); |
| 3366 Selector setterSelector = new Selector.setter(name); | 3218 Selector setterSelector = new Selector.setter(name); |
| 3367 | 3219 |
| 3368 void registerStaticUses(AccessSemantics semantics) { | 3220 void registerStaticUses(AccessSemantics semantics) { |
| 3369 switch (semantics.kind) { | 3221 switch (semantics.kind) { |
| 3370 case AccessKind.SUPER_METHOD: | 3222 case AccessKind.SUPER_METHOD: |
| 3371 registry.registerStaticUse( | 3223 registry |
| 3372 new StaticUse.superTearOff(semantics.element)); | 3224 .registerStaticUse(new StaticUse.superTearOff(semantics.element)); |
| 3373 break; | 3225 break; |
| 3374 case AccessKind.SUPER_GETTER: | 3226 case AccessKind.SUPER_GETTER: |
| 3375 registry.registerStaticUse(new StaticUse.superGet(semantics.getter)); | 3227 registry.registerStaticUse(new StaticUse.superGet(semantics.getter)); |
| 3376 break; | 3228 break; |
| 3377 case AccessKind.SUPER_SETTER: | 3229 case AccessKind.SUPER_SETTER: |
| 3378 registry.registerStaticUse( | 3230 registry.registerStaticUse( |
| 3379 new StaticUse.superSetterSet(semantics.setter)); | 3231 new StaticUse.superSetterSet(semantics.setter)); |
| 3380 break; | 3232 break; |
| 3381 case AccessKind.SUPER_FIELD: | 3233 case AccessKind.SUPER_FIELD: |
| 3382 registry.registerStaticUse( | 3234 registry.registerStaticUse(new StaticUse.superGet(semantics.element)); |
| 3383 new StaticUse.superGet(semantics.element)); | |
| 3384 registry.registerStaticUse( | 3235 registry.registerStaticUse( |
| 3385 new StaticUse.superFieldSet(semantics.element)); | 3236 new StaticUse.superFieldSet(semantics.element)); |
| 3386 break; | 3237 break; |
| 3387 case AccessKind.SUPER_FINAL_FIELD: | 3238 case AccessKind.SUPER_FINAL_FIELD: |
| 3388 registry.registerStaticUse( | 3239 registry.registerStaticUse(new StaticUse.superGet(semantics.element)); |
| 3389 new StaticUse.superGet(semantics.element)); | |
| 3390 break; | 3240 break; |
| 3391 case AccessKind.COMPOUND: | 3241 case AccessKind.COMPOUND: |
| 3392 CompoundAccessSemantics compoundSemantics = semantics; | 3242 CompoundAccessSemantics compoundSemantics = semantics; |
| 3393 switch (compoundSemantics.compoundAccessKind) { | 3243 switch (compoundSemantics.compoundAccessKind) { |
| 3394 case CompoundAccessKind.SUPER_GETTER_FIELD: | 3244 case CompoundAccessKind.SUPER_GETTER_FIELD: |
| 3395 case CompoundAccessKind.SUPER_FIELD_FIELD: | 3245 case CompoundAccessKind.SUPER_FIELD_FIELD: |
| 3396 registry.registerStaticUse( | 3246 registry |
| 3397 new StaticUse.superGet(semantics.getter)); | 3247 .registerStaticUse(new StaticUse.superGet(semantics.getter)); |
| 3398 registry.registerStaticUse( | 3248 registry.registerStaticUse( |
| 3399 new StaticUse.superFieldSet(semantics.setter)); | 3249 new StaticUse.superFieldSet(semantics.setter)); |
| 3400 break; | 3250 break; |
| 3401 case CompoundAccessKind.SUPER_FIELD_SETTER: | 3251 case CompoundAccessKind.SUPER_FIELD_SETTER: |
| 3402 case CompoundAccessKind.SUPER_GETTER_SETTER: | 3252 case CompoundAccessKind.SUPER_GETTER_SETTER: |
| 3403 registry.registerStaticUse( | 3253 registry |
| 3404 new StaticUse.superGet(semantics.getter)); | 3254 .registerStaticUse(new StaticUse.superGet(semantics.getter)); |
| 3405 registry.registerStaticUse( | 3255 registry.registerStaticUse( |
| 3406 new StaticUse.superSetterSet(semantics.setter)); | 3256 new StaticUse.superSetterSet(semantics.setter)); |
| 3407 break; | 3257 break; |
| 3408 case CompoundAccessKind.SUPER_METHOD_SETTER: | 3258 case CompoundAccessKind.SUPER_METHOD_SETTER: |
| 3409 registry.registerStaticUse( | 3259 registry.registerStaticUse( |
| 3410 new StaticUse.superSetterSet(semantics.setter)); | 3260 new StaticUse.superSetterSet(semantics.setter)); |
| 3411 break; | 3261 break; |
| 3412 case CompoundAccessKind.UNRESOLVED_SUPER_GETTER: | 3262 case CompoundAccessKind.UNRESOLVED_SUPER_GETTER: |
| 3413 registry.registerStaticUse( | 3263 registry.registerStaticUse( |
| 3414 new StaticUse.superSetterSet(semantics.setter)); | 3264 new StaticUse.superSetterSet(semantics.setter)); |
| 3415 break; | 3265 break; |
| 3416 case CompoundAccessKind.UNRESOLVED_SUPER_SETTER: | 3266 case CompoundAccessKind.UNRESOLVED_SUPER_SETTER: |
| 3417 registry.registerStaticUse( | 3267 registry |
| 3418 new StaticUse.superGet(semantics.getter)); | 3268 .registerStaticUse(new StaticUse.superGet(semantics.getter)); |
| 3419 break; | 3269 break; |
| 3420 default: | 3270 default: |
| 3421 break; | 3271 break; |
| 3422 } | 3272 } |
| 3423 break; | 3273 break; |
| 3424 default: | 3274 default: |
| 3425 break; | 3275 break; |
| 3426 } | 3276 } |
| 3427 } | 3277 } |
| 3428 | 3278 |
| 3429 AccessSemantics semantics = checkSuperAccess(node); | 3279 AccessSemantics semantics = checkSuperAccess(node); |
| 3430 if (node.isPrefix || node.isPostfix) { | 3280 if (node.isPrefix || node.isPostfix) { |
| 3431 // `super.a++` or `++super.a`. | 3281 // `super.a++` or `++super.a`. |
| 3432 if (semantics == null) { | 3282 if (semantics == null) { |
| 3433 semantics = computeSuperAccessSemanticsForSelectors( | 3283 semantics = computeSuperAccessSemanticsForSelectors( |
| 3434 node, getterSelector, setterSelector); | 3284 node, getterSelector, setterSelector); |
| 3435 registerStaticUses(semantics); | 3285 registerStaticUses(semantics); |
| 3436 } | 3286 } |
| 3437 return handleUpdate(node, name, semantics); | 3287 return handleUpdate(node, name, semantics); |
| 3438 } else { | 3288 } else { |
| 3439 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 3289 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
| 3440 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 3290 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
| 3441 // `super.a = b`. | 3291 // `super.a = b`. |
| 3442 if (semantics == null) { | 3292 if (semantics == null) { |
| 3443 semantics = | 3293 semantics = computeSuperAccessSemanticsForSelector( |
| 3444 computeSuperAccessSemanticsForSelector( | 3294 node, setterSelector, |
| 3445 node, setterSelector, alternateName: name); | 3295 alternateName: name); |
| 3446 switch (semantics.kind) { | 3296 switch (semantics.kind) { |
| 3447 case AccessKind.SUPER_FINAL_FIELD: | 3297 case AccessKind.SUPER_FINAL_FIELD: |
| 3448 reporter.reportWarningMessage( | 3298 reporter.reportWarningMessage( |
| 3449 node, | 3299 node, MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, { |
| 3450 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 3300 'name': name, |
| 3451 {'name': name, | 3301 'superclassName': semantics.setter.enclosingClass.name |
| 3452 'superclassName': semantics.setter.enclosingClass.name}); | 3302 }); |
| 3453 // TODO(johnniwinther): This shouldn't be needed. | 3303 // TODO(johnniwinther): This shouldn't be needed. |
| 3454 registry.registerDynamicUse( | 3304 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
| 3455 new DynamicUse(setterSelector, null)); | |
| 3456 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); | 3305 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
| 3457 break; | 3306 break; |
| 3458 case AccessKind.SUPER_METHOD: | 3307 case AccessKind.SUPER_METHOD: |
| 3459 reporter.reportWarningMessage( | 3308 reporter.reportWarningMessage( |
| 3460 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, | 3309 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, { |
| 3461 {'name': name, | 3310 'name': name, |
| 3462 'superclassName': semantics.setter.enclosingClass.name}); | 3311 'superclassName': semantics.setter.enclosingClass.name |
| 3312 }); |
| 3463 // TODO(johnniwinther): This shouldn't be needed. | 3313 // TODO(johnniwinther): This shouldn't be needed. |
| 3464 registry.registerDynamicUse( | 3314 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
| 3465 new DynamicUse(setterSelector, null)); | |
| 3466 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); | 3315 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
| 3467 break; | 3316 break; |
| 3468 case AccessKind.SUPER_FIELD: | 3317 case AccessKind.SUPER_FIELD: |
| 3469 registry.registerStaticUse( | 3318 registry.registerStaticUse( |
| 3470 new StaticUse.superFieldSet(semantics.setter)); | 3319 new StaticUse.superFieldSet(semantics.setter)); |
| 3471 break; | 3320 break; |
| 3472 case AccessKind.SUPER_SETTER: | 3321 case AccessKind.SUPER_SETTER: |
| 3473 registry.registerStaticUse( | 3322 registry.registerStaticUse( |
| 3474 new StaticUse.superSetterSet(semantics.setter)); | 3323 new StaticUse.superSetterSet(semantics.setter)); |
| 3475 break; | 3324 break; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3486 registerStaticUses(semantics); | 3335 registerStaticUses(semantics); |
| 3487 } | 3336 } |
| 3488 return handleUpdate(node, name, semantics); | 3337 return handleUpdate(node, name, semantics); |
| 3489 } | 3338 } |
| 3490 } | 3339 } |
| 3491 } | 3340 } |
| 3492 | 3341 |
| 3493 /// Handle update of an entity defined by [semantics]. For instance `a = b`, | 3342 /// Handle update of an entity defined by [semantics]. For instance `a = b`, |
| 3494 /// `a++` or `a += b` where [semantics] describe `a`. | 3343 /// `a++` or `a += b` where [semantics] describe `a`. |
| 3495 ResolutionResult handleUpdate( | 3344 ResolutionResult handleUpdate( |
| 3496 SendSet node, | 3345 SendSet node, Name name, AccessSemantics semantics) { |
| 3497 Name name, | |
| 3498 AccessSemantics semantics) { | |
| 3499 SendStructure sendStructure; | 3346 SendStructure sendStructure; |
| 3500 String operatorText = node.assignmentOperator.source; | 3347 String operatorText = node.assignmentOperator.source; |
| 3501 Selector getterSelector = new Selector.getter(name); | 3348 Selector getterSelector = new Selector.getter(name); |
| 3502 Selector setterSelector = new Selector.setter(name); | 3349 Selector setterSelector = new Selector.setter(name); |
| 3503 if (node.isPrefix || node.isPostfix) { | 3350 if (node.isPrefix || node.isPostfix) { |
| 3504 // `e++` or `++e`. | 3351 // `e++` or `++e`. |
| 3505 IncDecOperator operator = IncDecOperator.parse(operatorText); | 3352 IncDecOperator operator = IncDecOperator.parse(operatorText); |
| 3506 Selector operatorSelector = | 3353 Selector operatorSelector = |
| 3507 new Selector.binaryOperator(operator.selectorName); | 3354 new Selector.binaryOperator(operator.selectorName); |
| 3508 | 3355 |
| 3509 // TODO(23998): Remove these when selectors are only accessed | 3356 // TODO(23998): Remove these when selectors are only accessed |
| 3510 // through the send structure. | 3357 // through the send structure. |
| 3511 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3358 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 3512 registry.setSelector(node, setterSelector); | 3359 registry.setSelector(node, setterSelector); |
| 3513 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3360 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| 3514 | 3361 |
| 3515 // TODO(23998): Remove these when elements are only accessed | 3362 // TODO(23998): Remove these when elements are only accessed |
| 3516 // through the send structure. | 3363 // through the send structure. |
| 3517 registry.useElement(node, semantics.setter); | 3364 registry.useElement(node, semantics.setter); |
| 3518 registry.useElement(node.selector, semantics.getter); | 3365 registry.useElement(node.selector, semantics.getter); |
| 3519 | 3366 |
| 3520 registry.registerDynamicUse( | 3367 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
| 3521 new DynamicUse(operatorSelector, null)); | |
| 3522 | 3368 |
| 3523 SendStructure sendStructure = node.isPrefix | 3369 SendStructure sendStructure = node.isPrefix |
| 3524 ? new PrefixStructure(semantics, operator) | 3370 ? new PrefixStructure(semantics, operator) |
| 3525 : new PostfixStructure(semantics, operator); | 3371 : new PostfixStructure(semantics, operator); |
| 3526 registry.registerSendStructure(node, sendStructure); | 3372 registry.registerSendStructure(node, sendStructure); |
| 3527 registry.registerFeature(Feature.INC_DEC_OPERATION); | 3373 registry.registerFeature(Feature.INC_DEC_OPERATION); |
| 3528 } else { | 3374 } else { |
| 3529 Node rhs = node.arguments.head; | 3375 Node rhs = node.arguments.head; |
| 3530 visitExpression(rhs); | 3376 visitExpression(rhs); |
| 3531 | 3377 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3552 // through the send structure. | 3398 // through the send structure. |
| 3553 registry.useElement(node, semantics.setter); | 3399 registry.useElement(node, semantics.setter); |
| 3554 registry.useElement(node.selector, semantics.getter); | 3400 registry.useElement(node.selector, semantics.getter); |
| 3555 | 3401 |
| 3556 // TODO(23998): Remove these when selectors are only accessed | 3402 // TODO(23998): Remove these when selectors are only accessed |
| 3557 // through the send structure. | 3403 // through the send structure. |
| 3558 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3404 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 3559 registry.setSelector(node, setterSelector); | 3405 registry.setSelector(node, setterSelector); |
| 3560 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3406 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| 3561 | 3407 |
| 3562 registry.registerDynamicUse( | 3408 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
| 3563 new DynamicUse(operatorSelector, null)); | |
| 3564 | 3409 |
| 3565 SendStructure sendStructure; | 3410 SendStructure sendStructure; |
| 3566 if (operator.kind == AssignmentOperatorKind.IF_NULL) { | 3411 if (operator.kind == AssignmentOperatorKind.IF_NULL) { |
| 3567 sendStructure = new SetIfNullStructure(semantics); | 3412 sendStructure = new SetIfNullStructure(semantics); |
| 3568 } else { | 3413 } else { |
| 3569 sendStructure = new CompoundStructure(semantics, operator); | 3414 sendStructure = new CompoundStructure(semantics, operator); |
| 3570 } | 3415 } |
| 3571 registry.registerSendStructure(node, sendStructure); | 3416 registry.registerSendStructure(node, sendStructure); |
| 3572 } | 3417 } |
| 3573 } | 3418 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3634 registry.setConstant(node, constant); | 3479 registry.setConstant(node, constant); |
| 3635 return new ConstantResult(node, constant); | 3480 return new ConstantResult(node, constant); |
| 3636 } | 3481 } |
| 3637 | 3482 |
| 3638 ConstantResult visitLiteralSymbol(LiteralSymbol node) { | 3483 ConstantResult visitLiteralSymbol(LiteralSymbol node) { |
| 3639 String name = node.slowNameString; | 3484 String name = node.slowNameString; |
| 3640 // TODO(johnniwinther): Use [registerConstantLiteral] instead. | 3485 // TODO(johnniwinther): Use [registerConstantLiteral] instead. |
| 3641 registry.registerConstSymbol(name); | 3486 registry.registerConstSymbol(name); |
| 3642 if (!validateSymbol(node, name, reportError: false)) { | 3487 if (!validateSymbol(node, name, reportError: false)) { |
| 3643 reporter.reportErrorMessage( | 3488 reporter.reportErrorMessage( |
| 3644 node, | 3489 node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL, {'value': name}); |
| 3645 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, | |
| 3646 {'value': name}); | |
| 3647 } | 3490 } |
| 3648 analyzeConstantDeferred(node); | 3491 analyzeConstantDeferred(node); |
| 3649 ConstantExpression constant = new SymbolConstantExpression(name); | 3492 ConstantExpression constant = new SymbolConstantExpression(name); |
| 3650 registry.setConstant(node, constant); | 3493 registry.setConstant(node, constant); |
| 3651 return new ConstantResult(node, constant); | 3494 return new ConstantResult(node, constant); |
| 3652 } | 3495 } |
| 3653 | 3496 |
| 3654 ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) { | 3497 ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) { |
| 3655 registry.registerFeature(Feature.STRING_JUXTAPOSITION); | 3498 registry.registerFeature(Feature.STRING_JUXTAPOSITION); |
| 3656 ResolutionResult first = visit(node.first); | 3499 ResolutionResult first = visit(node.first); |
| 3657 ResolutionResult second = visit(node.second); | 3500 ResolutionResult second = visit(node.second); |
| 3658 if (first.isConstant && second.isConstant) { | 3501 if (first.isConstant && second.isConstant) { |
| 3659 ConstantExpression constant = new ConcatenateConstantExpression( | 3502 ConstantExpression constant = new ConcatenateConstantExpression( |
| 3660 <ConstantExpression>[first.constant, second.constant]); | 3503 <ConstantExpression>[first.constant, second.constant]); |
| 3661 registry.setConstant(node, constant); | 3504 registry.setConstant(node, constant); |
| 3662 return new ConstantResult(node, constant); | 3505 return new ConstantResult(node, constant); |
| 3663 } | 3506 } |
| 3664 return const NoneResult(); | 3507 return const NoneResult(); |
| 3665 } | 3508 } |
| 3666 | 3509 |
| 3667 ResolutionResult visitNodeList(NodeList node) { | 3510 ResolutionResult visitNodeList(NodeList node) { |
| 3668 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 3511 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 3669 visit(link.head); | 3512 visit(link.head); |
| 3670 } | 3513 } |
| 3671 return const NoneResult(); | 3514 return const NoneResult(); |
| 3672 } | 3515 } |
| 3673 | 3516 |
| 3674 ResolutionResult visitRethrow(Rethrow node) { | 3517 ResolutionResult visitRethrow(Rethrow node) { |
| 3675 if (!inCatchBlock && node.throwToken.stringValue == 'rethrow') { | 3518 if (!inCatchBlock && node.throwToken.stringValue == 'rethrow') { |
| 3676 reporter.reportErrorMessage( | 3519 reporter.reportErrorMessage(node, MessageKind.RETHROW_OUTSIDE_CATCH); |
| 3677 node, MessageKind.RETHROW_OUTSIDE_CATCH); | |
| 3678 } | 3520 } |
| 3679 return const NoneResult(); | 3521 return const NoneResult(); |
| 3680 } | 3522 } |
| 3681 | 3523 |
| 3682 ResolutionResult visitReturn(Return node) { | 3524 ResolutionResult visitReturn(Return node) { |
| 3683 Node expression = node.expression; | 3525 Node expression = node.expression; |
| 3684 if (expression != null) { | 3526 if (expression != null) { |
| 3685 if (enclosingElement.isGenerativeConstructor) { | 3527 if (enclosingElement.isGenerativeConstructor) { |
| 3686 // It is a compile-time error if a return statement of the form | 3528 // It is a compile-time error if a return statement of the form |
| 3687 // `return e;` appears in a generative constructor. (Dart Language | 3529 // `return e;` appears in a generative constructor. (Dart Language |
| 3688 // Specification 13.12.) | 3530 // Specification 13.12.) |
| 3689 reporter.reportErrorMessage( | 3531 reporter.reportErrorMessage( |
| 3690 expression, | 3532 expression, MessageKind.RETURN_IN_GENERATIVE_CONSTRUCTOR); |
| 3691 MessageKind.RETURN_IN_GENERATIVE_CONSTRUCTOR); | |
| 3692 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { | 3533 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { |
| 3693 reporter.reportErrorMessage( | 3534 reporter.reportErrorMessage(node, MessageKind.RETURN_IN_GENERATOR, |
| 3694 node, | |
| 3695 MessageKind.RETURN_IN_GENERATOR, | |
| 3696 {'modifier': currentAsyncMarker}); | 3535 {'modifier': currentAsyncMarker}); |
| 3697 } | 3536 } |
| 3698 } | 3537 } |
| 3699 visit(node.expression); | 3538 visit(node.expression); |
| 3700 return const NoneResult(); | 3539 return const NoneResult(); |
| 3701 } | 3540 } |
| 3702 | 3541 |
| 3703 ResolutionResult visitYield(Yield node) { | 3542 ResolutionResult visitYield(Yield node) { |
| 3704 if (!currentAsyncMarker.isYielding) { | 3543 if (!currentAsyncMarker.isYielding) { |
| 3705 reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD); | 3544 reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3717 if (!enclosingElement.isFactoryConstructor) { | 3556 if (!enclosingElement.isFactoryConstructor) { |
| 3718 reporter.reportErrorMessage( | 3557 reporter.reportErrorMessage( |
| 3719 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 3558 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
| 3720 reporter.reportHintMessage( | 3559 reporter.reportHintMessage( |
| 3721 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); | 3560 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
| 3722 } | 3561 } |
| 3723 | 3562 |
| 3724 ConstructorElementX constructor = enclosingElement; | 3563 ConstructorElementX constructor = enclosingElement; |
| 3725 bool isConstConstructor = constructor.isConst; | 3564 bool isConstConstructor = constructor.isConst; |
| 3726 bool isValidAsConstant = isConstConstructor; | 3565 bool isValidAsConstant = isConstConstructor; |
| 3727 ConstructorResult result = resolveRedirectingFactory( | 3566 ConstructorResult result = |
| 3728 node, inConstContext: isConstConstructor); | 3567 resolveRedirectingFactory(node, inConstContext: isConstConstructor); |
| 3729 ConstructorElement redirectionTarget = result.element; | 3568 ConstructorElement redirectionTarget = result.element; |
| 3730 constructor.immediateRedirectionTarget = redirectionTarget; | 3569 constructor.immediateRedirectionTarget = redirectionTarget; |
| 3731 | 3570 |
| 3732 Node constructorReference = node.constructorReference; | 3571 Node constructorReference = node.constructorReference; |
| 3733 if (result.isDeferred) { | 3572 if (result.isDeferred) { |
| 3734 constructor.redirectionDeferredPrefix = result.prefix; | 3573 constructor.redirectionDeferredPrefix = result.prefix; |
| 3735 } | 3574 } |
| 3736 | 3575 |
| 3737 registry.setRedirectingTargetConstructor(node, redirectionTarget); | 3576 registry.setRedirectingTargetConstructor(node, redirectionTarget); |
| 3738 switch (result.kind) { | 3577 switch (result.kind) { |
| 3739 case ConstructorResultKind.GENERATIVE: | 3578 case ConstructorResultKind.GENERATIVE: |
| 3740 case ConstructorResultKind.FACTORY: | 3579 case ConstructorResultKind.FACTORY: |
| 3741 // Register a post process to check for cycles in the redirection chain | 3580 // Register a post process to check for cycles in the redirection chain |
| 3742 // and set the actual generative constructor at the end of the chain. | 3581 // and set the actual generative constructor at the end of the chain. |
| 3743 addDeferredAction(constructor, () { | 3582 addDeferredAction(constructor, () { |
| 3744 compiler.resolver.resolveRedirectionChain(constructor, node); | 3583 compiler.resolver.resolveRedirectionChain(constructor, node); |
| 3745 }); | 3584 }); |
| 3746 break; | 3585 break; |
| 3747 case ConstructorResultKind.ABSTRACT: | 3586 case ConstructorResultKind.ABSTRACT: |
| 3748 case ConstructorResultKind.INVALID_TYPE: | 3587 case ConstructorResultKind.INVALID_TYPE: |
| 3749 case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR: | 3588 case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR: |
| 3750 case ConstructorResultKind.NON_CONSTANT: | 3589 case ConstructorResultKind.NON_CONSTANT: |
| 3751 isValidAsConstant = false; | 3590 isValidAsConstant = false; |
| 3752 constructor.setEffectiveTarget( | 3591 constructor.setEffectiveTarget(result.element, result.type, |
| 3753 result.element, result.type, isMalformed: true); | 3592 isMalformed: true); |
| 3754 break; | 3593 break; |
| 3755 } | 3594 } |
| 3756 if (Elements.isUnresolved(redirectionTarget)) { | 3595 if (Elements.isUnresolved(redirectionTarget)) { |
| 3757 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 3596 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 3758 return const NoneResult(); | 3597 return const NoneResult(); |
| 3759 } else { | 3598 } else { |
| 3760 if (isConstConstructor && | 3599 if (isConstConstructor && !redirectionTarget.isConst) { |
| 3761 !redirectionTarget.isConst) { | 3600 reporter.reportErrorMessage(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 3762 reporter.reportErrorMessage( | |
| 3763 node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | |
| 3764 isValidAsConstant = false; | 3601 isValidAsConstant = false; |
| 3765 } | 3602 } |
| 3766 if (redirectionTarget == constructor) { | 3603 if (redirectionTarget == constructor) { |
| 3767 reporter.reportErrorMessage( | 3604 reporter.reportErrorMessage( |
| 3768 node, MessageKind.CYCLIC_REDIRECTING_FACTORY); | 3605 node, MessageKind.CYCLIC_REDIRECTING_FACTORY); |
| 3769 // TODO(johnniwinther): Create constant constructor for this case and | 3606 // TODO(johnniwinther): Create constant constructor for this case and |
| 3770 // let evaluation detect the cyclicity. | 3607 // let evaluation detect the cyclicity. |
| 3771 isValidAsConstant = false; | 3608 isValidAsConstant = false; |
| 3772 } | 3609 } |
| 3773 } | 3610 } |
| 3774 | 3611 |
| 3775 // Check that the target constructor is type compatible with the | 3612 // Check that the target constructor is type compatible with the |
| 3776 // redirecting constructor. | 3613 // redirecting constructor. |
| 3777 ClassElement targetClass = redirectionTarget.enclosingClass; | 3614 ClassElement targetClass = redirectionTarget.enclosingClass; |
| 3778 InterfaceType type = registry.getType(node); | 3615 InterfaceType type = registry.getType(node); |
| 3779 FunctionType targetConstructorType = | 3616 FunctionType targetConstructorType = redirectionTarget |
| 3780 redirectionTarget.computeType(resolution) | 3617 .computeType(resolution) |
| 3781 .subst(type.typeArguments, targetClass.typeVariables); | 3618 .subst(type.typeArguments, targetClass.typeVariables); |
| 3782 FunctionType constructorType = constructor.computeType(resolution); | 3619 FunctionType constructorType = constructor.computeType(resolution); |
| 3783 bool isSubtype = compiler.types.isSubtype( | 3620 bool isSubtype = |
| 3784 targetConstructorType, constructorType); | 3621 compiler.types.isSubtype(targetConstructorType, constructorType); |
| 3785 if (!isSubtype) { | 3622 if (!isSubtype) { |
| 3786 reporter.reportWarningMessage( | 3623 reporter.reportWarningMessage(node, MessageKind.NOT_ASSIGNABLE, |
| 3787 node, | |
| 3788 MessageKind.NOT_ASSIGNABLE, | |
| 3789 {'fromType': targetConstructorType, 'toType': constructorType}); | 3624 {'fromType': targetConstructorType, 'toType': constructorType}); |
| 3790 // TODO(johnniwinther): Handle this (potentially) erroneous case. | 3625 // TODO(johnniwinther): Handle this (potentially) erroneous case. |
| 3791 isValidAsConstant = false; | 3626 isValidAsConstant = false; |
| 3792 } | 3627 } |
| 3793 | 3628 |
| 3794 redirectionTarget.computeType(resolution); | 3629 redirectionTarget.computeType(resolution); |
| 3795 FunctionSignature targetSignature = redirectionTarget.functionSignature; | 3630 FunctionSignature targetSignature = redirectionTarget.functionSignature; |
| 3796 constructor.computeType(resolution); | 3631 constructor.computeType(resolution); |
| 3797 FunctionSignature constructorSignature = constructor.functionSignature; | 3632 FunctionSignature constructorSignature = constructor.functionSignature; |
| 3798 if (!targetSignature.isCompatibleWith(constructorSignature)) { | 3633 if (!targetSignature.isCompatibleWith(constructorSignature)) { |
| 3799 assert(!isSubtype); | 3634 assert(!isSubtype); |
| 3800 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 3635 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 3801 isValidAsConstant = false; | 3636 isValidAsConstant = false; |
| 3802 } | 3637 } |
| 3803 | 3638 |
| 3804 registry.registerStaticUse( | 3639 registry.registerStaticUse( |
| 3805 new StaticUse.constructorRedirect(redirectionTarget)); | 3640 new StaticUse.constructorRedirect(redirectionTarget)); |
| 3806 // TODO(johnniwinther): Register the effective target type as part of the | 3641 // TODO(johnniwinther): Register the effective target type as part of the |
| 3807 // static use instead. | 3642 // static use instead. |
| 3808 registry.registerTypeUse(new TypeUse.instantiation( | 3643 registry.registerTypeUse(new TypeUse.instantiation(redirectionTarget |
| 3809 redirectionTarget.enclosingClass.thisType | 3644 .enclosingClass.thisType |
| 3810 .subst(type.typeArguments, targetClass.typeVariables))); | 3645 .subst(type.typeArguments, targetClass.typeVariables))); |
| 3811 if (enclosingElement == compiler.symbolConstructor) { | 3646 if (enclosingElement == compiler.symbolConstructor) { |
| 3812 registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR); | 3647 registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR); |
| 3813 } | 3648 } |
| 3814 if (isValidAsConstant) { | 3649 if (isValidAsConstant) { |
| 3815 List<String> names = <String>[]; | 3650 List<String> names = <String>[]; |
| 3816 List<ConstantExpression> arguments = <ConstantExpression>[]; | 3651 List<ConstantExpression> arguments = <ConstantExpression>[]; |
| 3817 int index = 0; | 3652 int index = 0; |
| 3818 constructorSignature.forEachParameter((ParameterElement parameter) { | 3653 constructorSignature.forEachParameter((ParameterElement parameter) { |
| 3819 if (parameter.isNamed) { | 3654 if (parameter.isNamed) { |
| 3820 String name = parameter.name; | 3655 String name = parameter.name; |
| 3821 names.add(name); | 3656 names.add(name); |
| 3822 arguments.add(new NamedArgumentReference(name)); | 3657 arguments.add(new NamedArgumentReference(name)); |
| 3823 } else { | 3658 } else { |
| 3824 arguments.add(new PositionalArgumentReference(index)); | 3659 arguments.add(new PositionalArgumentReference(index)); |
| 3825 } | 3660 } |
| 3826 index++; | 3661 index++; |
| 3827 }); | 3662 }); |
| 3828 CallStructure callStructure = | 3663 CallStructure callStructure = |
| 3829 new CallStructure(constructorSignature.parameterCount, names); | 3664 new CallStructure(constructorSignature.parameterCount, names); |
| 3830 constructor.constantConstructor = | 3665 constructor.constantConstructor = |
| 3831 new RedirectingFactoryConstantConstructor( | 3666 new RedirectingFactoryConstantConstructor( |
| 3832 new ConstructedConstantExpression( | 3667 new ConstructedConstantExpression( |
| 3833 type, | 3668 type, redirectionTarget, callStructure, arguments)); |
| 3834 redirectionTarget, | |
| 3835 callStructure, | |
| 3836 arguments)); | |
| 3837 } | 3669 } |
| 3838 return const NoneResult(); | 3670 return const NoneResult(); |
| 3839 } | 3671 } |
| 3840 | 3672 |
| 3841 ResolutionResult visitThrow(Throw node) { | 3673 ResolutionResult visitThrow(Throw node) { |
| 3842 registry.registerFeature(Feature.THROW_EXPRESSION); | 3674 registry.registerFeature(Feature.THROW_EXPRESSION); |
| 3843 visit(node.expression); | 3675 visit(node.expression); |
| 3844 return const NoneResult(); | 3676 return const NoneResult(); |
| 3845 } | 3677 } |
| 3846 | 3678 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3861 type = const DynamicType(); | 3693 type = const DynamicType(); |
| 3862 } | 3694 } |
| 3863 VariableList variables = new VariableList.node(node, type); | 3695 VariableList variables = new VariableList.node(node, type); |
| 3864 VariableDefinitionsVisitor visitor = | 3696 VariableDefinitionsVisitor visitor = |
| 3865 new VariableDefinitionsVisitor(compiler, node, this, variables); | 3697 new VariableDefinitionsVisitor(compiler, node, this, variables); |
| 3866 | 3698 |
| 3867 Modifiers modifiers = node.modifiers; | 3699 Modifiers modifiers = node.modifiers; |
| 3868 void reportExtraModifier(String modifier) { | 3700 void reportExtraModifier(String modifier) { |
| 3869 Node modifierNode; | 3701 Node modifierNode; |
| 3870 for (Link<Node> nodes = modifiers.nodes.nodes; | 3702 for (Link<Node> nodes = modifiers.nodes.nodes; |
| 3871 !nodes.isEmpty; | 3703 !nodes.isEmpty; |
| 3872 nodes = nodes.tail) { | 3704 nodes = nodes.tail) { |
| 3873 if (modifier == nodes.head.asIdentifier().source) { | 3705 if (modifier == nodes.head.asIdentifier().source) { |
| 3874 modifierNode = nodes.head; | 3706 modifierNode = nodes.head; |
| 3875 break; | 3707 break; |
| 3876 } | 3708 } |
| 3877 } | 3709 } |
| 3878 assert(modifierNode != null); | 3710 assert(modifierNode != null); |
| 3879 reporter.reportErrorMessage( | 3711 reporter.reportErrorMessage(modifierNode, MessageKind.EXTRANEOUS_MODIFIER, |
| 3880 modifierNode, MessageKind.EXTRANEOUS_MODIFIER, | |
| 3881 {'modifier': modifier}); | 3712 {'modifier': modifier}); |
| 3882 } | 3713 } |
| 3883 if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) { | 3714 if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) { |
| 3884 reportExtraModifier('final'); | 3715 reportExtraModifier('final'); |
| 3885 } | 3716 } |
| 3886 if (modifiers.isVar && (modifiers.isConst || node.type != null)) { | 3717 if (modifiers.isVar && (modifiers.isConst || node.type != null)) { |
| 3887 reportExtraModifier('var'); | 3718 reportExtraModifier('var'); |
| 3888 } | 3719 } |
| 3889 if (enclosingElement.isFunction || enclosingElement.isConstructor) { | 3720 if (enclosingElement.isFunction || enclosingElement.isConstructor) { |
| 3890 if (modifiers.isAbstract) { | 3721 if (modifiers.isAbstract) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3905 ResolutionResult visitWhile(While node) { | 3736 ResolutionResult visitWhile(While node) { |
| 3906 visit(node.condition); | 3737 visit(node.condition); |
| 3907 visitLoopBodyIn(node, node.body, new BlockScope(scope)); | 3738 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
| 3908 return const NoneResult(); | 3739 return const NoneResult(); |
| 3909 } | 3740 } |
| 3910 | 3741 |
| 3911 ResolutionResult visitParenthesizedExpression(ParenthesizedExpression node) { | 3742 ResolutionResult visitParenthesizedExpression(ParenthesizedExpression node) { |
| 3912 bool oldSendIsMemberAccess = sendIsMemberAccess; | 3743 bool oldSendIsMemberAccess = sendIsMemberAccess; |
| 3913 sendIsMemberAccess = false; | 3744 sendIsMemberAccess = false; |
| 3914 var oldCategory = allowedCategory; | 3745 var oldCategory = allowedCategory; |
| 3915 allowedCategory = | 3746 allowedCategory = ElementCategory.VARIABLE | |
| 3916 ElementCategory.VARIABLE | | |
| 3917 ElementCategory.FUNCTION | | 3747 ElementCategory.FUNCTION | |
| 3918 ElementCategory.IMPLIES_TYPE; | 3748 ElementCategory.IMPLIES_TYPE; |
| 3919 ResolutionResult result = visit(node.expression); | 3749 ResolutionResult result = visit(node.expression); |
| 3920 allowedCategory = oldCategory; | 3750 allowedCategory = oldCategory; |
| 3921 sendIsMemberAccess = oldSendIsMemberAccess; | 3751 sendIsMemberAccess = oldSendIsMemberAccess; |
| 3922 if (result.kind == ResultKind.CONSTANT) { | 3752 if (result.kind == ResultKind.CONSTANT) { |
| 3923 return result; | 3753 return result; |
| 3924 } | 3754 } |
| 3925 return const NoneResult(); | 3755 return const NoneResult(); |
| 3926 } | 3756 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3976 case ConstructorResultKind.ABSTRACT: | 3806 case ConstructorResultKind.ABSTRACT: |
| 3977 isInvalid = true; | 3807 isInvalid = true; |
| 3978 kind = ConstructorAccessKind.ABSTRACT; | 3808 kind = ConstructorAccessKind.ABSTRACT; |
| 3979 break; | 3809 break; |
| 3980 case ConstructorResultKind.INVALID_TYPE: | 3810 case ConstructorResultKind.INVALID_TYPE: |
| 3981 isInvalid = true; | 3811 isInvalid = true; |
| 3982 kind = ConstructorAccessKind.UNRESOLVED_TYPE; | 3812 kind = ConstructorAccessKind.UNRESOLVED_TYPE; |
| 3983 break; | 3813 break; |
| 3984 case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR: | 3814 case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR: |
| 3985 // TODO(johnniwinther): Unify codepaths to only have one return. | 3815 // TODO(johnniwinther): Unify codepaths to only have one return. |
| 3986 registry.registerNewStructure(node, | 3816 registry.registerNewStructure( |
| 3817 node, |
| 3987 new NewInvokeStructure( | 3818 new NewInvokeStructure( |
| 3988 new ConstructorAccessSemantics( | 3819 new ConstructorAccessSemantics( |
| 3989 ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, | 3820 ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, |
| 3990 constructor, | 3821 constructor, |
| 3991 type), | 3822 type), |
| 3992 selector)); | 3823 selector)); |
| 3993 return new ResolutionResult.forElement(constructor); | 3824 return new ResolutionResult.forElement(constructor); |
| 3994 case ConstructorResultKind.NON_CONSTANT: | 3825 case ConstructorResultKind.NON_CONSTANT: |
| 3995 registry.registerNewStructure(node, | 3826 registry.registerNewStructure( |
| 3827 node, |
| 3996 new NewInvokeStructure( | 3828 new NewInvokeStructure( |
| 3997 new ConstructorAccessSemantics( | 3829 new ConstructorAccessSemantics( |
| 3998 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, | 3830 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, |
| 3999 constructor, | 3831 constructor, |
| 4000 type), | 3832 type), |
| 4001 selector)); | 3833 selector)); |
| 4002 return new ResolutionResult.forElement(constructor); | 3834 return new ResolutionResult.forElement(constructor); |
| 4003 } | 3835 } |
| 4004 | 3836 |
| 4005 if (!isInvalid) { | 3837 if (!isInvalid) { |
| 4006 // [constructor] might be the implementation element | 3838 // [constructor] might be the implementation element |
| 4007 // and only declaration elements may be registered. | 3839 // and only declaration elements may be registered. |
| 4008 registry.registerStaticUse( | 3840 registry.registerStaticUse(new StaticUse.constructorInvoke( |
| 4009 new StaticUse.constructorInvoke( | 3841 constructor.declaration, callStructure)); |
| 4010 constructor.declaration, callStructure)); | |
| 4011 // TODO(johniwinther): Avoid registration of `type` in face of redirecting | 3842 // TODO(johniwinther): Avoid registration of `type` in face of redirecting |
| 4012 // factory constructors. | 3843 // factory constructors. |
| 4013 registry.registerTypeUse(new TypeUse.instantiation(type)); | 3844 registry.registerTypeUse(new TypeUse.instantiation(type)); |
| 4014 } | 3845 } |
| 4015 | 3846 |
| 4016 if (node.isConst) { | 3847 if (node.isConst) { |
| 4017 bool isValidAsConstant = !isInvalid && constructor.isConst; | 3848 bool isValidAsConstant = !isInvalid && constructor.isConst; |
| 4018 | 3849 |
| 4019 if (constructor == compiler.symbolConstructor) { | 3850 if (constructor == compiler.symbolConstructor) { |
| 4020 Node argumentNode = node.send.arguments.head; | 3851 Node argumentNode = node.send.arguments.head; |
| 4021 ConstantExpression constant = | 3852 ConstantExpression constant = compiler.resolver.constantCompiler |
| 4022 compiler.resolver.constantCompiler.compileNode( | 3853 .compileNode(argumentNode, registry.mapping); |
| 4023 argumentNode, registry.mapping); | |
| 4024 ConstantValue name = compiler.constants.getConstantValue(constant); | 3854 ConstantValue name = compiler.constants.getConstantValue(constant); |
| 4025 if (!name.isString) { | 3855 if (!name.isString) { |
| 4026 DartType type = name.getType(coreTypes); | 3856 DartType type = name.getType(coreTypes); |
| 4027 reporter.reportErrorMessage( | 3857 reporter.reportErrorMessage( |
| 4028 argumentNode, | 3858 argumentNode, MessageKind.STRING_EXPECTED, {'type': type}); |
| 4029 MessageKind.STRING_EXPECTED, | |
| 4030 {'type': type}); | |
| 4031 } else { | 3859 } else { |
| 4032 StringConstantValue stringConstant = name; | 3860 StringConstantValue stringConstant = name; |
| 4033 String nameString = stringConstant.toDartString().slowToString(); | 3861 String nameString = stringConstant.toDartString().slowToString(); |
| 4034 if (validateSymbol(argumentNode, nameString)) { | 3862 if (validateSymbol(argumentNode, nameString)) { |
| 4035 registry.registerConstSymbol(nameString); | 3863 registry.registerConstSymbol(nameString); |
| 4036 } | 3864 } |
| 4037 } | 3865 } |
| 4038 } else if (constructor == compiler.mirrorsUsedConstructor) { | 3866 } else if (constructor == compiler.mirrorsUsedConstructor) { |
| 4039 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); | 3867 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); |
| 4040 } | 3868 } |
| 4041 | 3869 |
| 4042 analyzeConstantDeferred(node); | 3870 analyzeConstantDeferred(node); |
| 4043 | 3871 |
| 4044 if (type.containsTypeVariables) { | 3872 if (type.containsTypeVariables) { |
| 4045 reporter.reportErrorMessage( | 3873 reporter.reportErrorMessage( |
| 4046 node.send.selector, | 3874 node.send.selector, MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 4047 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | |
| 4048 isValidAsConstant = false; | 3875 isValidAsConstant = false; |
| 4049 isInvalid = true; | 3876 isInvalid = true; |
| 4050 } | 3877 } |
| 4051 | 3878 |
| 4052 if (result.isDeferred) { | 3879 if (result.isDeferred) { |
| 4053 isValidAsConstant = false; | 3880 isValidAsConstant = false; |
| 4054 } | 3881 } |
| 4055 | 3882 |
| 4056 if (isValidAsConstant && | 3883 if (isValidAsConstant && |
| 4057 argumentsResult.isValidAsConstant && | 3884 argumentsResult.isValidAsConstant && |
| 4058 // TODO(johnniwinther): Remove this when all constants are computed | 3885 // TODO(johnniwinther): Remove this when all constants are computed |
| 4059 // in resolution. | 3886 // in resolution. |
| 4060 !constructor.isFromEnvironmentConstructor) { | 3887 !constructor.isFromEnvironmentConstructor) { |
| 4061 CallStructure callStructure = argumentsResult.callStructure; | 3888 CallStructure callStructure = argumentsResult.callStructure; |
| 4062 List<ConstantExpression> arguments = argumentsResult.constantArguments; | 3889 List<ConstantExpression> arguments = argumentsResult.constantArguments; |
| 4063 | 3890 |
| 4064 ConstructedConstantExpression constant = | 3891 ConstructedConstantExpression constant = |
| 4065 new ConstructedConstantExpression( | 3892 new ConstructedConstantExpression( |
| 4066 type, | 3893 type, constructor, callStructure, arguments); |
| 4067 constructor, | |
| 4068 callStructure, | |
| 4069 arguments); | |
| 4070 registry.registerNewStructure(node, | 3894 registry.registerNewStructure(node, |
| 4071 new ConstInvokeStructure(ConstantInvokeKind.CONSTRUCTED, constant)); | 3895 new ConstInvokeStructure(ConstantInvokeKind.CONSTRUCTED, constant)); |
| 4072 return new ConstantResult(node, constant); | 3896 return new ConstantResult(node, constant); |
| 4073 } else if (isInvalid) { | 3897 } else if (isInvalid) { |
| 4074 // Known to be non-constant. | 3898 // Known to be non-constant. |
| 4075 kind == ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR; | 3899 kind == ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR; |
| 4076 registry.registerNewStructure(node, | 3900 registry.registerNewStructure( |
| 3901 node, |
| 4077 new NewInvokeStructure( | 3902 new NewInvokeStructure( |
| 4078 new ConstructorAccessSemantics(kind, constructor, type), | 3903 new ConstructorAccessSemantics(kind, constructor, type), |
| 4079 selector)); | 3904 selector)); |
| 4080 } else { | 3905 } else { |
| 4081 // Might be valid but we don't know for sure. The compile-time constant | 3906 // Might be valid but we don't know for sure. The compile-time constant |
| 4082 // evaluator will compute the actual constant as a deferred action. | 3907 // evaluator will compute the actual constant as a deferred action. |
| 4083 registry.registerNewStructure(node, | 3908 registry.registerNewStructure( |
| 4084 new LateConstInvokeStructure(registry.mapping)); | 3909 node, new LateConstInvokeStructure(registry.mapping)); |
| 4085 } | 3910 } |
| 4086 | |
| 4087 } else { | 3911 } else { |
| 4088 // Not constant. | 3912 // Not constant. |
| 4089 if (constructor == compiler.symbolConstructor && | 3913 if (constructor == compiler.symbolConstructor && |
| 4090 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 3914 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
| 4091 reporter.reportHintMessage( | 3915 reporter.reportHintMessage(node.newToken, MessageKind.NON_CONST_BLOAT, |
| 4092 node.newToken, MessageKind.NON_CONST_BLOAT, | 3916 {'name': coreClasses.symbolClass.name}); |
| 4093 {'name': coreClasses.symbolClass.name}); | |
| 4094 } | 3917 } |
| 4095 registry.registerNewStructure(node, | 3918 registry.registerNewStructure( |
| 3919 node, |
| 4096 new NewInvokeStructure( | 3920 new NewInvokeStructure( |
| 4097 new ConstructorAccessSemantics(kind, constructor, type), | 3921 new ConstructorAccessSemantics(kind, constructor, type), |
| 4098 selector)); | 3922 selector)); |
| 4099 } | 3923 } |
| 4100 | 3924 |
| 4101 return const NoneResult(); | 3925 return const NoneResult(); |
| 4102 } | 3926 } |
| 4103 | 3927 |
| 4104 void checkConstMapKeysDontOverrideEquals(Spannable spannable, | 3928 void checkConstMapKeysDontOverrideEquals( |
| 4105 MapConstantValue map) { | 3929 Spannable spannable, MapConstantValue map) { |
| 4106 for (ConstantValue key in map.keys) { | 3930 for (ConstantValue key in map.keys) { |
| 4107 if (!key.isObject) continue; | 3931 if (!key.isObject) continue; |
| 4108 ObjectConstantValue objectConstant = key; | 3932 ObjectConstantValue objectConstant = key; |
| 4109 DartType keyType = objectConstant.type; | 3933 DartType keyType = objectConstant.type; |
| 4110 ClassElement cls = keyType.element; | 3934 ClassElement cls = keyType.element; |
| 4111 if (cls == coreClasses.stringClass) continue; | 3935 if (cls == coreClasses.stringClass) continue; |
| 4112 Element equals = cls.lookupMember('=='); | 3936 Element equals = cls.lookupMember('=='); |
| 4113 if (equals.enclosingClass != coreClasses.objectClass) { | 3937 if (equals.enclosingClass != coreClasses.objectClass) { |
| 4114 reporter.reportErrorMessage( | 3938 reporter.reportErrorMessage(spannable, |
| 4115 spannable, | 3939 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, {'type': keyType}); |
| 4116 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, | |
| 4117 {'type': keyType}); | |
| 4118 } | 3940 } |
| 4119 } | 3941 } |
| 4120 } | 3942 } |
| 4121 | 3943 |
| 4122 void analyzeConstant(Node node, {enforceConst: true}) { | 3944 void analyzeConstant(Node node, {enforceConst: true}) { |
| 4123 ConstantExpression constant = | 3945 ConstantExpression constant = compiler.resolver.constantCompiler |
| 4124 compiler.resolver.constantCompiler.compileNode( | 3946 .compileNode(node, registry.mapping, enforceConst: enforceConst); |
| 4125 node, registry.mapping, enforceConst: enforceConst); | |
| 4126 | 3947 |
| 4127 if (constant == null) { | 3948 if (constant == null) { |
| 4128 assert(invariant(node, compiler.compilationFailed)); | 3949 assert(invariant(node, compiler.compilationFailed)); |
| 4129 return; | 3950 return; |
| 4130 } | 3951 } |
| 4131 | 3952 |
| 4132 ConstantValue value = compiler.constants.getConstantValue(constant); | 3953 ConstantValue value = compiler.constants.getConstantValue(constant); |
| 4133 if (value.isMap) { | 3954 if (value.isMap) { |
| 4134 checkConstMapKeysDontOverrideEquals(node, value); | 3955 checkConstMapKeysDontOverrideEquals(node, value); |
| 4135 } | 3956 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 4159 } | 3980 } |
| 4160 return true; | 3981 return true; |
| 4161 } | 3982 } |
| 4162 | 3983 |
| 4163 /** | 3984 /** |
| 4164 * Try to resolve the constructor that is referred to by [node]. | 3985 * Try to resolve the constructor that is referred to by [node]. |
| 4165 * Note: this function may return an ErroneousFunctionElement instead of | 3986 * Note: this function may return an ErroneousFunctionElement instead of |
| 4166 * [:null:], if there is no corresponding constructor, class or library. | 3987 * [:null:], if there is no corresponding constructor, class or library. |
| 4167 */ | 3988 */ |
| 4168 ConstructorResult resolveConstructor(NewExpression node) { | 3989 ConstructorResult resolveConstructor(NewExpression node) { |
| 4169 return node.accept(new ConstructorResolver( | 3990 return node.accept( |
| 4170 compiler, this, inConstContext: node.isConst)); | 3991 new ConstructorResolver(compiler, this, inConstContext: node.isConst)); |
| 4171 } | 3992 } |
| 4172 | 3993 |
| 4173 ConstructorResult resolveRedirectingFactory(RedirectingFactoryBody node, | 3994 ConstructorResult resolveRedirectingFactory(RedirectingFactoryBody node, |
| 4174 {bool inConstContext: false}) { | 3995 {bool inConstContext: false}) { |
| 4175 return node.accept(new ConstructorResolver( | 3996 return node.accept(new ConstructorResolver(compiler, this, |
| 4176 compiler, this, inConstContext: inConstContext)); | 3997 inConstContext: inConstContext)); |
| 4177 } | 3998 } |
| 4178 | 3999 |
| 4179 DartType resolveTypeAnnotation(TypeAnnotation node, | 4000 DartType resolveTypeAnnotation(TypeAnnotation node, |
| 4180 {bool malformedIsError: false, | 4001 {bool malformedIsError: false, bool deferredIsMalformed: true}) { |
| 4181 bool deferredIsMalformed: true}) { | 4002 DartType type = typeResolver.resolveTypeAnnotation(this, node, |
| 4182 DartType type = typeResolver.resolveTypeAnnotation( | 4003 malformedIsError: malformedIsError, |
| 4183 this, node, malformedIsError: malformedIsError, | |
| 4184 deferredIsMalformed: deferredIsMalformed); | 4004 deferredIsMalformed: deferredIsMalformed); |
| 4185 if (inCheckContext) { | 4005 if (inCheckContext) { |
| 4186 registry.registerTypeUse(new TypeUse.checkedModeCheck(type)); | 4006 registry.registerTypeUse(new TypeUse.checkedModeCheck(type)); |
| 4187 } | 4007 } |
| 4188 return type; | 4008 return type; |
| 4189 } | 4009 } |
| 4190 | 4010 |
| 4191 ResolutionResult visitLiteralList(LiteralList node) { | 4011 ResolutionResult visitLiteralList(LiteralList node) { |
| 4192 bool isValidAsConstant = true; | 4012 bool isValidAsConstant = true; |
| 4193 sendIsMemberAccess = false; | 4013 sendIsMemberAccess = false; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4207 reporter.reportWarningMessage( | 4027 reporter.reportWarningMessage( |
| 4208 nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 4028 nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
| 4209 resolveTypeAnnotation(nodes.head); | 4029 resolveTypeAnnotation(nodes.head); |
| 4210 } | 4030 } |
| 4211 } | 4031 } |
| 4212 } | 4032 } |
| 4213 DartType listType; | 4033 DartType listType; |
| 4214 if (typeArgument != null) { | 4034 if (typeArgument != null) { |
| 4215 if (node.isConst && typeArgument.containsTypeVariables) { | 4035 if (node.isConst && typeArgument.containsTypeVariables) { |
| 4216 reporter.reportErrorMessage( | 4036 reporter.reportErrorMessage( |
| 4217 arguments.nodes.head, | 4037 arguments.nodes.head, MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 4218 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | |
| 4219 isValidAsConstant = false; | 4038 isValidAsConstant = false; |
| 4220 } | 4039 } |
| 4221 listType = coreTypes.listType(typeArgument); | 4040 listType = coreTypes.listType(typeArgument); |
| 4222 } else { | 4041 } else { |
| 4223 listType = coreTypes.listType(); | 4042 listType = coreTypes.listType(); |
| 4224 } | 4043 } |
| 4225 registry.registerLiteralList( | 4044 registry.registerLiteralList(node, listType, |
| 4226 node, | 4045 isConstant: node.isConst, isEmpty: node.elements.isEmpty); |
| 4227 listType, | |
| 4228 isConstant: node.isConst, | |
| 4229 isEmpty: node.elements.isEmpty); | |
| 4230 if (node.isConst) { | 4046 if (node.isConst) { |
| 4231 List<ConstantExpression> constantExpressions = <ConstantExpression>[]; | 4047 List<ConstantExpression> constantExpressions = <ConstantExpression>[]; |
| 4232 inConstantContext(() { | 4048 inConstantContext(() { |
| 4233 for (Node element in node.elements) { | 4049 for (Node element in node.elements) { |
| 4234 ResolutionResult elementResult = visit(element); | 4050 ResolutionResult elementResult = visit(element); |
| 4235 if (isValidAsConstant && elementResult.isConstant) { | 4051 if (isValidAsConstant && elementResult.isConstant) { |
| 4236 constantExpressions.add(elementResult.constant); | 4052 constantExpressions.add(elementResult.constant); |
| 4237 } else { | 4053 } else { |
| 4238 isValidAsConstant = false; | 4054 isValidAsConstant = false; |
| 4239 } | 4055 } |
| 4240 } | 4056 } |
| 4241 }); | 4057 }); |
| 4242 analyzeConstantDeferred(node); | 4058 analyzeConstantDeferred(node); |
| 4243 sendIsMemberAccess = false; | 4059 sendIsMemberAccess = false; |
| 4244 if (isValidAsConstant) { | 4060 if (isValidAsConstant) { |
| 4245 ConstantExpression constant = | 4061 ConstantExpression constant = |
| 4246 new ListConstantExpression(listType, constantExpressions); | 4062 new ListConstantExpression(listType, constantExpressions); |
| 4247 registry.setConstant(node, constant); | 4063 registry.setConstant(node, constant); |
| 4248 return new ConstantResult(node, constant); | 4064 return new ConstantResult(node, constant); |
| 4249 } | 4065 } |
| 4250 } else { | 4066 } else { |
| 4251 visit(node.elements); | 4067 visit(node.elements); |
| 4252 sendIsMemberAccess = false; | 4068 sendIsMemberAccess = false; |
| 4253 } | 4069 } |
| 4254 return const NoneResult(); | 4070 return const NoneResult(); |
| 4255 | |
| 4256 } | 4071 } |
| 4257 | 4072 |
| 4258 ResolutionResult visitConditional(Conditional node) { | 4073 ResolutionResult visitConditional(Conditional node) { |
| 4259 ResolutionResult conditionResult = | 4074 ResolutionResult conditionResult = |
| 4260 doInPromotionScope(node.condition, () => visit(node.condition)); | 4075 doInPromotionScope(node.condition, () => visit(node.condition)); |
| 4261 ResolutionResult thenResult = | 4076 ResolutionResult thenResult = doInPromotionScope( |
| 4262 doInPromotionScope(node.thenExpression, () => visit(node.thenExpression)
); | 4077 node.thenExpression, () => visit(node.thenExpression)); |
| 4263 ResolutionResult elseResult = visit(node.elseExpression); | 4078 ResolutionResult elseResult = visit(node.elseExpression); |
| 4264 if (conditionResult.isConstant && | 4079 if (conditionResult.isConstant && |
| 4265 thenResult.isConstant && | 4080 thenResult.isConstant && |
| 4266 elseResult.isConstant) { | 4081 elseResult.isConstant) { |
| 4267 ConstantExpression constant = new ConditionalConstantExpression( | 4082 ConstantExpression constant = new ConditionalConstantExpression( |
| 4268 conditionResult.constant, | 4083 conditionResult.constant, thenResult.constant, elseResult.constant); |
| 4269 thenResult.constant, | |
| 4270 elseResult.constant); | |
| 4271 registry.setConstant(node, constant); | 4084 registry.setConstant(node, constant); |
| 4272 return new ConstantResult(node, constant); | 4085 return new ConstantResult(node, constant); |
| 4273 } | 4086 } |
| 4274 return const NoneResult(); | 4087 return const NoneResult(); |
| 4275 } | 4088 } |
| 4276 | 4089 |
| 4277 ResolutionResult visitStringInterpolation(StringInterpolation node) { | 4090 ResolutionResult visitStringInterpolation(StringInterpolation node) { |
| 4278 // TODO(johnniwinther): This should be a consequence of the registration | 4091 // TODO(johnniwinther): This should be a consequence of the registration |
| 4279 // of [registerStringInterpolation]. | 4092 // of [registerStringInterpolation]. |
| 4280 registry.registerTypeUse(new TypeUse.instantiation(coreTypes.stringType)); | 4093 registry.registerTypeUse(new TypeUse.instantiation(coreTypes.stringType)); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4305 return new ConstantResult(node, constant); | 4118 return new ConstantResult(node, constant); |
| 4306 } | 4119 } |
| 4307 return const NoneResult(); | 4120 return const NoneResult(); |
| 4308 } | 4121 } |
| 4309 | 4122 |
| 4310 ResolutionResult visitBreakStatement(BreakStatement node) { | 4123 ResolutionResult visitBreakStatement(BreakStatement node) { |
| 4311 JumpTarget target; | 4124 JumpTarget target; |
| 4312 if (node.target == null) { | 4125 if (node.target == null) { |
| 4313 target = statementScope.currentBreakTarget(); | 4126 target = statementScope.currentBreakTarget(); |
| 4314 if (target == null) { | 4127 if (target == null) { |
| 4315 reporter.reportErrorMessage( | 4128 reporter.reportErrorMessage(node, MessageKind.NO_BREAK_TARGET); |
| 4316 node, MessageKind.NO_BREAK_TARGET); | |
| 4317 return const NoneResult(); | 4129 return const NoneResult(); |
| 4318 } | 4130 } |
| 4319 target.isBreakTarget = true; | 4131 target.isBreakTarget = true; |
| 4320 } else { | 4132 } else { |
| 4321 String labelName = node.target.source; | 4133 String labelName = node.target.source; |
| 4322 LabelDefinition label = statementScope.lookupLabel(labelName); | 4134 LabelDefinition label = statementScope.lookupLabel(labelName); |
| 4323 if (label == null) { | 4135 if (label == null) { |
| 4324 reporter.reportErrorMessage( | 4136 reporter.reportErrorMessage( |
| 4325 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 4137 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
| 4326 return const NoneResult(); | 4138 return const NoneResult(); |
| 4327 } | 4139 } |
| 4328 target = label.target; | 4140 target = label.target; |
| 4329 if (!target.statement.isValidBreakTarget()) { | 4141 if (!target.statement.isValidBreakTarget()) { |
| 4330 reporter.reportErrorMessage( | 4142 reporter.reportErrorMessage(node.target, MessageKind.INVALID_BREAK); |
| 4331 node.target, MessageKind.INVALID_BREAK); | |
| 4332 return const NoneResult(); | 4143 return const NoneResult(); |
| 4333 } | 4144 } |
| 4334 label.setBreakTarget(); | 4145 label.setBreakTarget(); |
| 4335 registry.useLabel(node, label); | 4146 registry.useLabel(node, label); |
| 4336 } | 4147 } |
| 4337 registry.registerTargetOf(node, target); | 4148 registry.registerTargetOf(node, target); |
| 4338 return const NoneResult(); | 4149 return const NoneResult(); |
| 4339 } | 4150 } |
| 4340 | 4151 |
| 4341 ResolutionResult visitContinueStatement(ContinueStatement node) { | 4152 ResolutionResult visitContinueStatement(ContinueStatement node) { |
| 4342 JumpTarget target; | 4153 JumpTarget target; |
| 4343 if (node.target == null) { | 4154 if (node.target == null) { |
| 4344 target = statementScope.currentContinueTarget(); | 4155 target = statementScope.currentContinueTarget(); |
| 4345 if (target == null) { | 4156 if (target == null) { |
| 4346 reporter.reportErrorMessage( | 4157 reporter.reportErrorMessage(node, MessageKind.NO_CONTINUE_TARGET); |
| 4347 node, MessageKind.NO_CONTINUE_TARGET); | |
| 4348 return const NoneResult(); | 4158 return const NoneResult(); |
| 4349 } | 4159 } |
| 4350 target.isContinueTarget = true; | 4160 target.isContinueTarget = true; |
| 4351 } else { | 4161 } else { |
| 4352 String labelName = node.target.source; | 4162 String labelName = node.target.source; |
| 4353 LabelDefinition label = statementScope.lookupLabel(labelName); | 4163 LabelDefinition label = statementScope.lookupLabel(labelName); |
| 4354 if (label == null) { | 4164 if (label == null) { |
| 4355 reporter.reportErrorMessage( | 4165 reporter.reportErrorMessage( |
| 4356 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 4166 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
| 4357 return const NoneResult(); | 4167 return const NoneResult(); |
| 4358 } | 4168 } |
| 4359 target = label.target; | 4169 target = label.target; |
| 4360 if (!target.statement.isValidContinueTarget()) { | 4170 if (!target.statement.isValidContinueTarget()) { |
| 4361 reporter.reportErrorMessage( | 4171 reporter.reportErrorMessage(node.target, MessageKind.INVALID_CONTINUE); |
| 4362 node.target, MessageKind.INVALID_CONTINUE); | |
| 4363 } | 4172 } |
| 4364 label.setContinueTarget(); | 4173 label.setContinueTarget(); |
| 4365 registry.useLabel(node, label); | 4174 registry.useLabel(node, label); |
| 4366 } | 4175 } |
| 4367 registry.registerTargetOf(node, target); | 4176 registry.registerTargetOf(node, target); |
| 4368 return const NoneResult(); | 4177 return const NoneResult(); |
| 4369 } | 4178 } |
| 4370 | 4179 |
| 4371 registerImplicitInvocation(Selector selector) { | 4180 registerImplicitInvocation(Selector selector) { |
| 4372 registry.registerDynamicUse(new DynamicUse(selector, null)); | 4181 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 4373 } | 4182 } |
| 4374 | 4183 |
| 4375 ResolutionResult visitAsyncForIn(AsyncForIn node) { | 4184 ResolutionResult visitAsyncForIn(AsyncForIn node) { |
| 4376 if (!currentAsyncMarker.isAsync) { | 4185 if (!currentAsyncMarker.isAsync) { |
| 4377 reporter.reportErrorMessage( | 4186 reporter.reportErrorMessage( |
| 4378 node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN); | 4187 node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN); |
| 4379 } | 4188 } |
| 4380 registry.registerFeature(Feature.ASYNC_FOR_IN); | 4189 registry.registerFeature(Feature.ASYNC_FOR_IN); |
| 4381 registry.registerDynamicUse( | 4190 registry.registerDynamicUse(new DynamicUse(Selectors.current, null)); |
| 4382 new DynamicUse(Selectors.current, null)); | 4191 registry.registerDynamicUse(new DynamicUse(Selectors.moveNext, null)); |
| 4383 registry.registerDynamicUse( | |
| 4384 new DynamicUse(Selectors.moveNext, null)); | |
| 4385 | 4192 |
| 4386 visit(node.expression); | 4193 visit(node.expression); |
| 4387 | 4194 |
| 4388 Scope blockScope = new BlockScope(scope); | 4195 Scope blockScope = new BlockScope(scope); |
| 4389 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); | 4196 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); |
| 4390 visitLoopBodyIn(node, node.body, blockScope); | 4197 visitLoopBodyIn(node, node.body, blockScope); |
| 4391 return const NoneResult(); | 4198 return const NoneResult(); |
| 4392 } | 4199 } |
| 4393 | 4200 |
| 4394 ResolutionResult visitSyncForIn(SyncForIn node) { | 4201 ResolutionResult visitSyncForIn(SyncForIn node) { |
| 4395 registry.registerFeature(Feature.SYNC_FOR_IN); | 4202 registry.registerFeature(Feature.SYNC_FOR_IN); |
| 4396 registry.registerDynamicUse( | 4203 registry.registerDynamicUse(new DynamicUse(Selectors.iterator, null)); |
| 4397 new DynamicUse(Selectors.iterator, null)); | 4204 registry.registerDynamicUse(new DynamicUse(Selectors.current, null)); |
| 4398 registry.registerDynamicUse( | 4205 registry.registerDynamicUse(new DynamicUse(Selectors.moveNext, null)); |
| 4399 new DynamicUse(Selectors.current, null)); | |
| 4400 registry.registerDynamicUse( | |
| 4401 new DynamicUse(Selectors.moveNext, null)); | |
| 4402 | 4206 |
| 4403 visit(node.expression); | 4207 visit(node.expression); |
| 4404 | 4208 |
| 4405 Scope blockScope = new BlockScope(scope); | 4209 Scope blockScope = new BlockScope(scope); |
| 4406 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); | 4210 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); |
| 4407 visitLoopBodyIn(node, node.body, blockScope); | 4211 visitLoopBodyIn(node, node.body, blockScope); |
| 4408 return const NoneResult(); | 4212 return const NoneResult(); |
| 4409 } | 4213 } |
| 4410 | 4214 |
| 4411 void visitForInDeclaredIdentifierIn( | 4215 void visitForInDeclaredIdentifierIn( |
| 4412 Node declaration, | 4216 Node declaration, ForIn node, Scope blockScope) { |
| 4413 ForIn node, | |
| 4414 Scope blockScope) { | |
| 4415 LibraryElement library = enclosingElement.library; | 4217 LibraryElement library = enclosingElement.library; |
| 4416 | 4218 |
| 4417 bool oldAllowFinalWithoutInitializer = inLoopVariable; | 4219 bool oldAllowFinalWithoutInitializer = inLoopVariable; |
| 4418 inLoopVariable = true; | 4220 inLoopVariable = true; |
| 4419 visitIn(declaration, blockScope); | 4221 visitIn(declaration, blockScope); |
| 4420 inLoopVariable = oldAllowFinalWithoutInitializer; | 4222 inLoopVariable = oldAllowFinalWithoutInitializer; |
| 4421 | 4223 |
| 4422 Send send = declaration.asSend(); | 4224 Send send = declaration.asSend(); |
| 4423 VariableDefinitions variableDefinitions = | 4225 VariableDefinitions variableDefinitions = |
| 4424 declaration.asVariableDefinitions(); | 4226 declaration.asVariableDefinitions(); |
| 4425 Element loopVariable; | 4227 Element loopVariable; |
| 4426 Selector loopVariableSelector; | 4228 Selector loopVariableSelector; |
| 4427 if (send != null) { | 4229 if (send != null) { |
| 4428 loopVariable = registry.getDefinition(send); | 4230 loopVariable = registry.getDefinition(send); |
| 4429 Identifier identifier = send.selector.asIdentifier(); | 4231 Identifier identifier = send.selector.asIdentifier(); |
| 4430 if (identifier == null) { | 4232 if (identifier == null) { |
| 4431 reporter.reportErrorMessage( | 4233 reporter.reportErrorMessage(send.selector, MessageKind.INVALID_FOR_IN); |
| 4432 send.selector, MessageKind.INVALID_FOR_IN); | |
| 4433 } else { | 4234 } else { |
| 4434 loopVariableSelector = new Selector.setter( | 4235 loopVariableSelector = |
| 4435 new Name(identifier.source, library)); | 4236 new Selector.setter(new Name(identifier.source, library)); |
| 4436 } | 4237 } |
| 4437 if (send.receiver != null) { | 4238 if (send.receiver != null) { |
| 4438 reporter.reportErrorMessage( | 4239 reporter.reportErrorMessage(send.receiver, MessageKind.INVALID_FOR_IN); |
| 4439 send.receiver, MessageKind.INVALID_FOR_IN); | |
| 4440 } | 4240 } |
| 4441 } else if (variableDefinitions != null) { | 4241 } else if (variableDefinitions != null) { |
| 4442 Link<Node> nodes = variableDefinitions.definitions.nodes; | 4242 Link<Node> nodes = variableDefinitions.definitions.nodes; |
| 4443 if (!nodes.tail.isEmpty) { | 4243 if (!nodes.tail.isEmpty) { |
| 4444 reporter.reportErrorMessage( | 4244 reporter.reportErrorMessage( |
| 4445 nodes.tail.head, MessageKind.INVALID_FOR_IN); | 4245 nodes.tail.head, MessageKind.INVALID_FOR_IN); |
| 4446 } | 4246 } |
| 4447 Node first = nodes.head; | 4247 Node first = nodes.head; |
| 4448 Identifier identifier = first.asIdentifier(); | 4248 Identifier identifier = first.asIdentifier(); |
| 4449 if (identifier == null) { | 4249 if (identifier == null) { |
| 4450 reporter.reportErrorMessage( | 4250 reporter.reportErrorMessage(first, MessageKind.INVALID_FOR_IN); |
| 4451 first, MessageKind.INVALID_FOR_IN); | |
| 4452 } else { | 4251 } else { |
| 4453 loopVariableSelector = new Selector.setter( | 4252 loopVariableSelector = |
| 4454 new Name(identifier.source, library)); | 4253 new Selector.setter(new Name(identifier.source, library)); |
| 4455 loopVariable = registry.getDefinition(identifier); | 4254 loopVariable = registry.getDefinition(identifier); |
| 4456 } | 4255 } |
| 4457 } else { | 4256 } else { |
| 4458 reporter.reportErrorMessage( | 4257 reporter.reportErrorMessage(declaration, MessageKind.INVALID_FOR_IN); |
| 4459 declaration, MessageKind.INVALID_FOR_IN); | |
| 4460 } | 4258 } |
| 4461 if (loopVariableSelector != null) { | 4259 if (loopVariableSelector != null) { |
| 4462 registry.setSelector(declaration, loopVariableSelector); | 4260 registry.setSelector(declaration, loopVariableSelector); |
| 4463 if (loopVariable == null || loopVariable.isInstanceMember) { | 4261 if (loopVariable == null || loopVariable.isInstanceMember) { |
| 4464 registry.registerDynamicUse( | 4262 registry.registerDynamicUse(new DynamicUse(loopVariableSelector, null)); |
| 4465 new DynamicUse(loopVariableSelector, null)); | |
| 4466 } else if (loopVariable.isStatic || loopVariable.isTopLevel) { | 4263 } else if (loopVariable.isStatic || loopVariable.isTopLevel) { |
| 4467 registry.registerStaticUse( | 4264 registry.registerStaticUse( |
| 4468 new StaticUse.staticSet(loopVariable.declaration)); | 4265 new StaticUse.staticSet(loopVariable.declaration)); |
| 4469 } | 4266 } |
| 4470 } else { | 4267 } else { |
| 4471 // The selector may only be null if we reported an error. | 4268 // The selector may only be null if we reported an error. |
| 4472 assert(invariant(declaration, compiler.compilationFailed)); | 4269 assert(invariant(declaration, compiler.compilationFailed)); |
| 4473 } | 4270 } |
| 4474 if (loopVariable != null) { | 4271 if (loopVariable != null) { |
| 4475 // loopVariable may be null if it could not be resolved. | 4272 // loopVariable may be null if it could not be resolved. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4492 labelElements[labelName] = element; | 4289 labelElements[labelName] = element; |
| 4493 } | 4290 } |
| 4494 statementScope.enterLabelScope(labelElements); | 4291 statementScope.enterLabelScope(labelElements); |
| 4495 visit(node.statement); | 4292 visit(node.statement); |
| 4496 statementScope.exitLabelScope(); | 4293 statementScope.exitLabelScope(); |
| 4497 labelElements.forEach((String labelName, LabelDefinition element) { | 4294 labelElements.forEach((String labelName, LabelDefinition element) { |
| 4498 if (element.isTarget) { | 4295 if (element.isTarget) { |
| 4499 registry.defineLabel(element.label, element); | 4296 registry.defineLabel(element.label, element); |
| 4500 } else { | 4297 } else { |
| 4501 reporter.reportWarningMessage( | 4298 reporter.reportWarningMessage( |
| 4502 element.label, | 4299 element.label, MessageKind.UNUSED_LABEL, {'labelName': labelName}); |
| 4503 MessageKind.UNUSED_LABEL, | |
| 4504 {'labelName': labelName}); | |
| 4505 } | 4300 } |
| 4506 }); | 4301 }); |
| 4507 if (!targetElement.isTarget) { | 4302 if (!targetElement.isTarget) { |
| 4508 registry.undefineTarget(body); | 4303 registry.undefineTarget(body); |
| 4509 } | 4304 } |
| 4510 return const NoneResult(); | 4305 return const NoneResult(); |
| 4511 } | 4306 } |
| 4512 | 4307 |
| 4513 ResolutionResult visitLiteralMap(LiteralMap node) { | 4308 ResolutionResult visitLiteralMap(LiteralMap node) { |
| 4514 bool isValidAsConstant = true; | 4309 bool isValidAsConstant = true; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 4541 } | 4336 } |
| 4542 } | 4337 } |
| 4543 DartType mapType; | 4338 DartType mapType; |
| 4544 if (valueTypeArgument != null) { | 4339 if (valueTypeArgument != null) { |
| 4545 mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); | 4340 mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); |
| 4546 } else { | 4341 } else { |
| 4547 mapType = coreTypes.mapType(); | 4342 mapType = coreTypes.mapType(); |
| 4548 } | 4343 } |
| 4549 if (node.isConst && mapType.containsTypeVariables) { | 4344 if (node.isConst && mapType.containsTypeVariables) { |
| 4550 reporter.reportErrorMessage( | 4345 reporter.reportErrorMessage( |
| 4551 arguments, | 4346 arguments, MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 4552 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | |
| 4553 isValidAsConstant = false; | 4347 isValidAsConstant = false; |
| 4554 } | 4348 } |
| 4555 registry.registerMapLiteral( | 4349 registry.registerMapLiteral(node, mapType, |
| 4556 node, | 4350 isConstant: node.isConst, isEmpty: node.entries.isEmpty); |
| 4557 mapType, | |
| 4558 isConstant: node.isConst, | |
| 4559 isEmpty: node.entries.isEmpty); | |
| 4560 | 4351 |
| 4561 if (node.isConst) { | 4352 if (node.isConst) { |
| 4562 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; | 4353 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; |
| 4563 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; | 4354 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; |
| 4564 inConstantContext(() { | 4355 inConstantContext(() { |
| 4565 for (LiteralMapEntry entry in node.entries) { | 4356 for (LiteralMapEntry entry in node.entries) { |
| 4566 ResolutionResult keyResult = visit(entry.key); | 4357 ResolutionResult keyResult = visit(entry.key); |
| 4567 ResolutionResult valueResult = visit(entry.value); | 4358 ResolutionResult valueResult = visit(entry.value); |
| 4568 if (isValidAsConstant && | 4359 if (isValidAsConstant && |
| 4569 keyResult.isConstant && | 4360 keyResult.isConstant && |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4617 return equals.enclosingClass != coreClasses.objectClass; | 4408 return equals.enclosingClass != coreClasses.objectClass; |
| 4618 } | 4409 } |
| 4619 | 4410 |
| 4620 void checkCaseExpressions(SwitchStatement node) { | 4411 void checkCaseExpressions(SwitchStatement node) { |
| 4621 CaseMatch firstCase = null; | 4412 CaseMatch firstCase = null; |
| 4622 DartType firstCaseType = null; | 4413 DartType firstCaseType = null; |
| 4623 DiagnosticMessage error; | 4414 DiagnosticMessage error; |
| 4624 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 4415 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
| 4625 | 4416 |
| 4626 for (Link<Node> cases = node.cases.nodes; | 4417 for (Link<Node> cases = node.cases.nodes; |
| 4627 !cases.isEmpty; | 4418 !cases.isEmpty; |
| 4628 cases = cases.tail) { | 4419 cases = cases.tail) { |
| 4629 SwitchCase switchCase = cases.head; | 4420 SwitchCase switchCase = cases.head; |
| 4630 | 4421 |
| 4631 for (Node labelOrCase in switchCase.labelsAndCases) { | 4422 for (Node labelOrCase in switchCase.labelsAndCases) { |
| 4632 CaseMatch caseMatch = labelOrCase.asCaseMatch(); | 4423 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
| 4633 if (caseMatch == null) continue; | 4424 if (caseMatch == null) continue; |
| 4634 | 4425 |
| 4635 // Analyze the constant. | 4426 // Analyze the constant. |
| 4636 ConstantExpression constant = | 4427 ConstantExpression constant = |
| 4637 registry.getConstant(caseMatch.expression); | 4428 registry.getConstant(caseMatch.expression); |
| 4638 assert(invariant(node, constant != null, | 4429 assert(invariant(node, constant != null, |
| 4639 message: 'No constant computed for $node')); | 4430 message: 'No constant computed for $node')); |
| 4640 | 4431 |
| 4641 ConstantValue value = compiler.constants.getConstantValue(constant); | 4432 ConstantValue value = compiler.constants.getConstantValue(constant); |
| 4642 DartType caseType = value.getType(coreTypes);//typeOfConstant(value); | 4433 DartType caseType = value.getType(coreTypes); //typeOfConstant(value); |
| 4643 | 4434 |
| 4644 if (firstCaseType == null) { | 4435 if (firstCaseType == null) { |
| 4645 firstCase = caseMatch; | 4436 firstCase = caseMatch; |
| 4646 firstCaseType = caseType; | 4437 firstCaseType = caseType; |
| 4647 | 4438 |
| 4648 // We only report the bad type on the first class element. All others | 4439 // We only report the bad type on the first class element. All others |
| 4649 // get a "type differs" error. | 4440 // get a "type differs" error. |
| 4650 if (caseType == coreTypes.doubleType) { | 4441 if (caseType == coreTypes.doubleType) { |
| 4651 reporter.reportErrorMessage( | 4442 reporter.reportErrorMessage( |
| 4652 node, | 4443 node, |
| 4653 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, | 4444 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, |
| 4654 {'type': "double"}); | 4445 {'type': "double"}); |
| 4655 } else if (caseType == coreTypes.functionType) { | 4446 } else if (caseType == coreTypes.functionType) { |
| 4656 reporter.reportErrorMessage( | 4447 reporter.reportErrorMessage( |
| 4657 node, MessageKind.SWITCH_CASE_FORBIDDEN, | 4448 node, MessageKind.SWITCH_CASE_FORBIDDEN, {'type': "Function"}); |
| 4658 {'type': "Function"}); | |
| 4659 } else if (value.isObject && overridesEquals(caseType)) { | 4449 } else if (value.isObject && overridesEquals(caseType)) { |
| 4660 reporter.reportErrorMessage( | 4450 reporter.reportErrorMessage( |
| 4661 firstCase.expression, | 4451 firstCase.expression, |
| 4662 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, | 4452 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, |
| 4663 {'type': caseType}); | 4453 {'type': caseType}); |
| 4664 } | 4454 } |
| 4665 } else { | 4455 } else { |
| 4666 if (caseType != firstCaseType) { | 4456 if (caseType != firstCaseType) { |
| 4667 if (error == null) { | 4457 if (error == null) { |
| 4668 error = reporter.createMessage( | 4458 error = reporter.createMessage( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4702 continue; | 4492 continue; |
| 4703 } | 4493 } |
| 4704 Label label = labelOrCase; | 4494 Label label = labelOrCase; |
| 4705 String labelName = label.labelName; | 4495 String labelName = label.labelName; |
| 4706 | 4496 |
| 4707 LabelDefinition existingElement = continueLabels[labelName]; | 4497 LabelDefinition existingElement = continueLabels[labelName]; |
| 4708 if (existingElement != null) { | 4498 if (existingElement != null) { |
| 4709 // It's an error if the same label occurs twice in the same switch. | 4499 // It's an error if the same label occurs twice in the same switch. |
| 4710 reporter.reportError( | 4500 reporter.reportError( |
| 4711 reporter.createMessage( | 4501 reporter.createMessage( |
| 4712 label, | 4502 label, MessageKind.DUPLICATE_LABEL, {'labelName': labelName}), |
| 4713 MessageKind.DUPLICATE_LABEL, | |
| 4714 {'labelName': labelName}), | |
| 4715 <DiagnosticMessage>[ | 4503 <DiagnosticMessage>[ |
| 4716 reporter.createMessage( | 4504 reporter.createMessage(existingElement.label, |
| 4717 existingElement.label, | 4505 MessageKind.EXISTING_LABEL, {'labelName': labelName}), |
| 4718 MessageKind.EXISTING_LABEL, | |
| 4719 {'labelName': labelName}), | |
| 4720 ]); | 4506 ]); |
| 4721 } else { | 4507 } else { |
| 4722 // It's only a warning if it shadows another label. | 4508 // It's only a warning if it shadows another label. |
| 4723 existingElement = statementScope.lookupLabel(labelName); | 4509 existingElement = statementScope.lookupLabel(labelName); |
| 4724 if (existingElement != null) { | 4510 if (existingElement != null) { |
| 4725 reporter.reportWarning( | 4511 reporter.reportWarning( |
| 4726 reporter.createMessage( | 4512 reporter.createMessage(label, MessageKind.DUPLICATE_LABEL, |
| 4727 label, | |
| 4728 MessageKind.DUPLICATE_LABEL, | |
| 4729 {'labelName': labelName}), | 4513 {'labelName': labelName}), |
| 4730 <DiagnosticMessage>[ | 4514 <DiagnosticMessage>[ |
| 4731 reporter.createMessage( | 4515 reporter.createMessage(existingElement.label, |
| 4732 existingElement.label, | 4516 MessageKind.EXISTING_LABEL, {'labelName': labelName}), |
| 4733 MessageKind.EXISTING_LABEL, | |
| 4734 {'labelName': labelName}), | |
| 4735 ]); | 4517 ]); |
| 4736 } | 4518 } |
| 4737 } | 4519 } |
| 4738 | 4520 |
| 4739 JumpTarget targetElement = getOrDefineTarget(switchCase); | 4521 JumpTarget targetElement = getOrDefineTarget(switchCase); |
| 4740 LabelDefinition labelElement = targetElement.addLabel(label, labelName); | 4522 LabelDefinition labelElement = targetElement.addLabel(label, labelName); |
| 4741 registry.defineLabel(label, labelElement); | 4523 registry.defineLabel(label, labelElement); |
| 4742 continueLabels[labelName] = labelElement; | 4524 continueLabels[labelName] = labelElement; |
| 4743 } | 4525 } |
| 4744 cases = cases.tail; | 4526 cases = cases.tail; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4800 | 4582 |
| 4801 ResolutionResult visitCatchBlock(CatchBlock node) { | 4583 ResolutionResult visitCatchBlock(CatchBlock node) { |
| 4802 registry.registerFeature(Feature.CATCH_STATEMENT); | 4584 registry.registerFeature(Feature.CATCH_STATEMENT); |
| 4803 // Check that if catch part is present, then | 4585 // Check that if catch part is present, then |
| 4804 // it has one or two formal parameters. | 4586 // it has one or two formal parameters. |
| 4805 VariableDefinitions exceptionDefinition; | 4587 VariableDefinitions exceptionDefinition; |
| 4806 VariableDefinitions stackTraceDefinition; | 4588 VariableDefinitions stackTraceDefinition; |
| 4807 if (node.formals != null) { | 4589 if (node.formals != null) { |
| 4808 Link<Node> formalsToProcess = node.formals.nodes; | 4590 Link<Node> formalsToProcess = node.formals.nodes; |
| 4809 if (formalsToProcess.isEmpty) { | 4591 if (formalsToProcess.isEmpty) { |
| 4810 reporter.reportErrorMessage( | 4592 reporter.reportErrorMessage(node, MessageKind.EMPTY_CATCH_DECLARATION); |
| 4811 node, MessageKind.EMPTY_CATCH_DECLARATION); | |
| 4812 } else { | 4593 } else { |
| 4813 exceptionDefinition = formalsToProcess.head.asVariableDefinitions(); | 4594 exceptionDefinition = formalsToProcess.head.asVariableDefinitions(); |
| 4814 formalsToProcess = formalsToProcess.tail; | 4595 formalsToProcess = formalsToProcess.tail; |
| 4815 if (!formalsToProcess.isEmpty) { | 4596 if (!formalsToProcess.isEmpty) { |
| 4816 stackTraceDefinition = formalsToProcess.head.asVariableDefinitions(); | 4597 stackTraceDefinition = formalsToProcess.head.asVariableDefinitions(); |
| 4817 formalsToProcess = formalsToProcess.tail; | 4598 formalsToProcess = formalsToProcess.tail; |
| 4818 if (!formalsToProcess.isEmpty) { | 4599 if (!formalsToProcess.isEmpty) { |
| 4819 for (Node extra in formalsToProcess) { | 4600 for (Node extra in formalsToProcess) { |
| 4820 reporter.reportErrorMessage( | 4601 reporter.reportErrorMessage( |
| 4821 extra, MessageKind.EXTRA_CATCH_DECLARATION); | 4602 extra, MessageKind.EXTRA_CATCH_DECLARATION); |
| 4822 } | 4603 } |
| 4823 } | 4604 } |
| 4824 registry.registerFeature(Feature.STACK_TRACE_IN_CATCH); | 4605 registry.registerFeature(Feature.STACK_TRACE_IN_CATCH); |
| 4825 } | 4606 } |
| 4826 } | 4607 } |
| 4827 | 4608 |
| 4828 // Check that the formals aren't optional and that they have no | 4609 // Check that the formals aren't optional and that they have no |
| 4829 // modifiers or type. | 4610 // modifiers or type. |
| 4830 for (Link<Node> link = node.formals.nodes; | 4611 for (Link<Node> link = node.formals.nodes; |
| 4831 !link.isEmpty; | 4612 !link.isEmpty; |
| 4832 link = link.tail) { | 4613 link = link.tail) { |
| 4833 // If the formal parameter is a node list, it means that it is a | 4614 // If the formal parameter is a node list, it means that it is a |
| 4834 // sequence of optional parameters. | 4615 // sequence of optional parameters. |
| 4835 NodeList nodeList = link.head.asNodeList(); | 4616 NodeList nodeList = link.head.asNodeList(); |
| 4836 if (nodeList != null) { | 4617 if (nodeList != null) { |
| 4837 reporter.reportErrorMessage( | 4618 reporter.reportErrorMessage( |
| 4838 nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); | 4619 nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); |
| 4839 } else { | 4620 } else { |
| 4840 VariableDefinitions declaration = link.head; | 4621 VariableDefinitions declaration = link.head; |
| 4841 for (Node modifier in declaration.modifiers.nodes) { | 4622 for (Node modifier in declaration.modifiers.nodes) { |
| 4842 reporter.reportErrorMessage( | 4623 reporter.reportErrorMessage( |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4874 VariableElementX stackTraceElement = | 4655 VariableElementX stackTraceElement = |
| 4875 registry.getDefinition(stackTraceVariable); | 4656 registry.getDefinition(stackTraceVariable); |
| 4876 InterfaceType stackTraceType = coreTypes.stackTraceType; | 4657 InterfaceType stackTraceType = coreTypes.stackTraceType; |
| 4877 stackTraceElement.variables.type = stackTraceType; | 4658 stackTraceElement.variables.type = stackTraceType; |
| 4878 } | 4659 } |
| 4879 return const NoneResult(); | 4660 return const NoneResult(); |
| 4880 } | 4661 } |
| 4881 } | 4662 } |
| 4882 | 4663 |
| 4883 /// Looks up [name] in [scope] and unwraps the result. | 4664 /// Looks up [name] in [scope] and unwraps the result. |
| 4884 Element lookupInScope(DiagnosticReporter reporter, Node node, | 4665 Element lookupInScope( |
| 4885 Scope scope, String name) { | 4666 DiagnosticReporter reporter, Node node, Scope scope, String name) { |
| 4886 return Elements.unwrap(scope.lookup(name), reporter, node); | 4667 return Elements.unwrap(scope.lookup(name), reporter, node); |
| 4887 } | 4668 } |
| OLD | NEW |