Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
| 11 import 'package:analyzer/dart/ast/token.dart'; | 11 import 'package:analyzer/dart/ast/token.dart'; |
| 12 import 'package:analyzer/dart/ast/visitor.dart'; | 12 import 'package:analyzer/dart/ast/visitor.dart'; |
| 13 import 'package:analyzer/dart/element/element.dart'; | 13 import 'package:analyzer/dart/element/element.dart'; |
| 14 import 'package:analyzer/dart/element/type.dart'; | 14 import 'package:analyzer/dart/element/type.dart'; |
| 15 import 'package:analyzer/dart/element/visitor.dart'; | 15 import 'package:analyzer/dart/element/visitor.dart'; |
| 16 import 'package:analyzer/error/error.dart'; | 16 import 'package:analyzer/error/error.dart'; |
| 17 import 'package:analyzer/error/listener.dart'; | 17 import 'package:analyzer/error/listener.dart'; |
| 18 import 'package:analyzer/exception/exception.dart'; | 18 import 'package:analyzer/exception/exception.dart'; |
| 19 import 'package:analyzer/src/dart/ast/ast.dart'; | 19 import 'package:analyzer/src/dart/ast/ast.dart'; |
| 20 import 'package:analyzer/src/dart/ast/utilities.dart'; | 20 import 'package:analyzer/src/dart/ast/utilities.dart'; |
| 21 import 'package:analyzer/src/dart/element/element.dart'; | 21 import 'package:analyzer/src/dart/element/element.dart'; |
| 22 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember; | |
| 22 import 'package:analyzer/src/dart/element/type.dart'; | 23 import 'package:analyzer/src/dart/element/type.dart'; |
| 23 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; | 24 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; |
| 24 import 'package:analyzer/src/dart/resolver/scope.dart'; | 25 import 'package:analyzer/src/dart/resolver/scope.dart'; |
| 25 import 'package:analyzer/src/error/codes.dart'; | 26 import 'package:analyzer/src/error/codes.dart'; |
| 26 import 'package:analyzer/src/generated/constant.dart'; | 27 import 'package:analyzer/src/generated/constant.dart'; |
| 27 import 'package:analyzer/src/generated/element_resolver.dart'; | 28 import 'package:analyzer/src/generated/element_resolver.dart'; |
| 28 import 'package:analyzer/src/generated/engine.dart'; | 29 import 'package:analyzer/src/generated/engine.dart'; |
| 29 import 'package:analyzer/src/generated/error_verifier.dart'; | 30 import 'package:analyzer/src/generated/error_verifier.dart'; |
| 30 import 'package:analyzer/src/generated/source.dart'; | 31 import 'package:analyzer/src/generated/source.dart'; |
| 31 import 'package:analyzer/src/generated/static_type_analyzer.dart'; | 32 import 'package:analyzer/src/generated/static_type_analyzer.dart'; |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 642 // TODO(jwren) We should modify ConstructorElement.getDisplayName(), | 643 // TODO(jwren) We should modify ConstructorElement.getDisplayName(), |
| 643 // or have the logic centralized elsewhere, instead of doing this logic | 644 // or have the logic centralized elsewhere, instead of doing this logic |
| 644 // here. | 645 // here. |
| 645 displayName = element.enclosingElement.displayName; | 646 displayName = element.enclosingElement.displayName; |
| 646 if (!element.displayName.isEmpty) { | 647 if (!element.displayName.isEmpty) { |
| 647 displayName = "$displayName.${element.displayName}"; | 648 displayName = "$displayName.${element.displayName}"; |
| 648 } | 649 } |
| 649 } else if (displayName == FunctionElement.CALL_METHOD_NAME && | 650 } else if (displayName == FunctionElement.CALL_METHOD_NAME && |
| 650 node is MethodInvocation && | 651 node is MethodInvocation && |
| 651 node.staticInvokeType is InterfaceType) { | 652 node.staticInvokeType is InterfaceType) { |
| 652 displayName = | 653 displayName = "${resolutionMap |
| 653 "${resolutionMap.staticInvokeTypeForInvocationExpression(node).displ ayName}.${element.displayName}"; | 654 .staticInvokeTypeForInvocationExpression(node) |
| 655 .displayName}.${element.displayName}"; | |
| 654 } | 656 } |
| 655 _errorReporter.reportErrorForNode( | 657 _errorReporter.reportErrorForNode( |
| 656 HintCode.DEPRECATED_MEMBER_USE, node, [displayName]); | 658 HintCode.DEPRECATED_MEMBER_USE, node, [displayName]); |
| 657 } | 659 } |
| 658 } | 660 } |
| 659 | 661 |
| 660 /** | 662 /** |
| 661 * For [SimpleIdentifier]s, only call [checkForDeprecatedMemberUse] | 663 * For [SimpleIdentifier]s, only call [checkForDeprecatedMemberUse] |
| 662 * if the node is not in a declaration context. | 664 * if the node is not in a declaration context. |
| 663 * | 665 * |
| (...skipping 3498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4162 if (_returnStack.isEmpty) { | 4164 if (_returnStack.isEmpty) { |
| 4163 return; | 4165 return; |
| 4164 } | 4166 } |
| 4165 | 4167 |
| 4166 DartType inferred = _inferredReturn.last; | 4168 DartType inferred = _inferredReturn.last; |
| 4167 inferred = _typeSystem.getLeastUpperBound(type, inferred); | 4169 inferred = _typeSystem.getLeastUpperBound(type, inferred); |
| 4168 _inferredReturn[_inferredReturn.length - 1] = inferred; | 4170 _inferredReturn[_inferredReturn.length - 1] = inferred; |
| 4169 } | 4171 } |
| 4170 | 4172 |
| 4171 /** | 4173 /** |
| 4172 * Like [getContext] but expands a union type into a list of types. | |
| 4173 */ | |
| 4174 Iterable<DartType> getTypes(AstNode node) { | |
| 4175 DartType t = getContext(node); | |
| 4176 if (t == null) { | |
| 4177 return DartType.EMPTY_LIST; | |
| 4178 } | |
| 4179 if (t is InterfaceType && t.isDartAsyncFutureOr) { | |
| 4180 var tArg = t.typeArguments[0]; // The T in FutureOr<T> | |
| 4181 return [ | |
| 4182 _typeProvider.futureType.instantiate([tArg]), | |
| 4183 tArg | |
| 4184 ]; | |
| 4185 } | |
| 4186 return [t]; | |
| 4187 } | |
| 4188 | |
| 4189 /** | |
| 4190 * Match type [t1] against type [t2] as follows. | |
| 4191 * If `t1 = I<dynamic, ..., dynamic>`, then look for a supertype | |
| 4192 * of t1 of the form `K<S0, ..., Sm>` where `t2 = K<S0', ..., Sm'>` | |
| 4193 * If the supertype exists, use the constraints `S0 <: S0', ... Sm <: Sm'` | |
| 4194 * to derive a concrete instantation for I of the form `<T0, ..., Tn>`, | |
| 4195 * such that `I<T0, .., Tn> <: t2` | |
| 4196 */ | |
| 4197 List<DartType> matchTypes(DartType t1, DartType t2) => | |
| 4198 (t1 is InterfaceType && t2 is InterfaceType) ? _matchTypes(t1, t2) : null; | |
| 4199 | |
| 4200 /** | |
| 4201 * Pop a return type off of the return stack. | 4174 * Pop a return type off of the return stack. |
| 4202 * | 4175 * |
| 4203 * Also record any inferred return type using [setType], unless this node | 4176 * Also record any inferred return type using [setType], unless this node |
| 4204 * already has a context type. This recorded type will be the least upper | 4177 * already has a context type. This recorded type will be the least upper |
| 4205 * bound of all types added with [addReturnOrYieldType]. | 4178 * bound of all types added with [addReturnOrYieldType]. |
| 4206 */ | 4179 */ |
| 4207 void popReturnContext(BlockFunctionBody node) { | 4180 void popReturnContext(BlockFunctionBody node) { |
| 4208 if (_returnStack.isNotEmpty && _inferredReturn.isNotEmpty) { | 4181 if (_returnStack.isNotEmpty && _inferredReturn.isNotEmpty) { |
| 4209 DartType context = _returnStack.removeLast() ?? DynamicTypeImpl.instance; | 4182 DartType context = _returnStack.removeLast() ?? DynamicTypeImpl.instance; |
| 4210 DartType inferred = _inferredReturn.removeLast(); | 4183 DartType inferred = _inferredReturn.removeLast(); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 4241 error = StrongModeCode.INFERRED_TYPE_ALLOCATION; | 4214 error = StrongModeCode.INFERRED_TYPE_ALLOCATION; |
| 4242 } else if (node is FunctionExpression) { | 4215 } else if (node is FunctionExpression) { |
| 4243 error = StrongModeCode.INFERRED_TYPE_CLOSURE; | 4216 error = StrongModeCode.INFERRED_TYPE_CLOSURE; |
| 4244 } else { | 4217 } else { |
| 4245 error = StrongModeCode.INFERRED_TYPE; | 4218 error = StrongModeCode.INFERRED_TYPE; |
| 4246 } | 4219 } |
| 4247 | 4220 |
| 4248 _errorReporter.reportErrorForNode(error, node, [node, type]); | 4221 _errorReporter.reportErrorForNode(error, node, [node, type]); |
| 4249 } | 4222 } |
| 4250 | 4223 |
| 4251 List<DartType> _matchTypes(InterfaceType t1, InterfaceType t2) { | |
| 4252 if (t1 == t2) { | |
| 4253 return t2.typeArguments; | |
| 4254 } | |
| 4255 List<DartType> tArgs1 = t1.typeArguments; | |
| 4256 List<DartType> tArgs2 = t2.typeArguments; | |
| 4257 // If t1 isn't a raw type, bail out | |
| 4258 if (tArgs1 != null && tArgs1.any((t) => !t.isDynamic)) { | |
| 4259 return null; | |
| 4260 } | |
| 4261 | |
| 4262 // This is our inferred type argument list. We start at all dynamic, | |
| 4263 // and fill in with inferred types when we reach a match. | |
| 4264 List<DartType> actuals = | |
| 4265 new List<DartType>.filled(tArgs1.length, _typeProvider.dynamicType); | |
| 4266 | |
| 4267 // When we find the supertype of t1 with the same | |
| 4268 // classname as t2 (see below), we have the following: | |
| 4269 // If t1 is an instantiation of a class T1<X0, ..., Xn> | |
| 4270 // and t2 is an instantiation of a class T2<Y0, ...., Ym> | |
| 4271 // of the form t2 = T2<S0, ..., Sm> | |
| 4272 // then we want to choose instantiations for the Xi | |
| 4273 // T0, ..., Tn such that T1<T0, ..., Tn> <: t2 . | |
| 4274 // To find this, we simply instantate T1 with | |
| 4275 // X0, ..., Xn, and then find its superclass | |
| 4276 // T2<T0', ..., Tn'>. We then solve the constraint | |
| 4277 // set T0' <: S0, ..., Tn' <: Sn for the Xi. | |
| 4278 // Currently, we only handle constraints where | |
| 4279 // the Ti' is one of the Xi'. If there are multiple | |
| 4280 // constraints on some Xi, we choose the lower of the | |
| 4281 // two (if it exists). | |
| 4282 bool permute(List<DartType> permutedArgs) { | |
| 4283 if (permutedArgs == null) { | |
| 4284 return false; | |
| 4285 } | |
| 4286 List<TypeParameterElement> ps = t1.typeParameters; | |
| 4287 List<DartType> ts = ps.map((p) => p.type).toList(); | |
| 4288 for (int i = 0; i < permutedArgs.length; i++) { | |
| 4289 DartType tVar = permutedArgs[i]; | |
| 4290 DartType tActual = tArgs2[i]; | |
| 4291 int index = ts.indexOf(tVar); | |
| 4292 if (index >= 0 && _typeSystem.isSubtypeOf(tActual, actuals[index])) { | |
| 4293 actuals[index] = tActual; | |
| 4294 } | |
| 4295 } | |
| 4296 return actuals.any((x) => !x.isDynamic); | |
| 4297 } | |
| 4298 | |
| 4299 // Look for the first supertype of t1 with the same class name as t2. | |
| 4300 bool match(InterfaceType t1, Set<Element> visited) { | |
| 4301 if (t1.element == t2.element) { | |
| 4302 return permute(t1.typeArguments); | |
| 4303 } | |
| 4304 | |
| 4305 if (t1 == _typeProvider.objectType) { | |
| 4306 return false; | |
| 4307 } | |
| 4308 | |
| 4309 Element element = t1.element; | |
| 4310 if (visited == null) { | |
| 4311 visited = new HashSet<Element>(); | |
| 4312 } | |
| 4313 if (element == null || !visited.add(element)) { | |
| 4314 return false; | |
| 4315 } | |
| 4316 try { | |
| 4317 if (match(t1.superclass, visited)) { | |
| 4318 return true; | |
| 4319 } | |
| 4320 | |
| 4321 List<InterfaceType> mixins = t1.mixins; | |
| 4322 int mixinLength = mixins.length; | |
| 4323 for (int i = 0; i < mixinLength; i++) { | |
| 4324 if (match(mixins[i], visited)) { | |
| 4325 return true; | |
| 4326 } | |
| 4327 } | |
| 4328 | |
| 4329 List<InterfaceType> interfaces = t1.interfaces; | |
| 4330 int interfaceLength = interfaces.length; | |
| 4331 for (int j = 0; j < interfaceLength; j++) { | |
| 4332 if (match(interfaces[j], visited)) { | |
| 4333 return true; | |
| 4334 } | |
| 4335 } | |
| 4336 } finally { | |
| 4337 visited.remove(element); | |
| 4338 } | |
| 4339 return false; | |
| 4340 } | |
| 4341 | |
| 4342 // We have that t1 = T1<dynamic, ..., dynamic>. | |
| 4343 // To match t1 against t2, we use the uninstantiated version | |
| 4344 // of t1, essentially treating it as an instantiation with | |
| 4345 // fresh variables, and solve for the variables. | |
| 4346 // t1.element.type will be of the form T1<X0, ..., Xn> | |
| 4347 if (!match(t1.element.type, null)) { | |
| 4348 return null; | |
| 4349 } | |
| 4350 DartType newT1 = t1.element.type.instantiate(actuals); | |
| 4351 // If we found a solution, return it. | |
| 4352 if (_typeSystem.isSubtypeOf(newT1, t2)) { | |
| 4353 return actuals; | |
| 4354 } | |
| 4355 return null; | |
| 4356 } | |
| 4357 | |
| 4358 /** | 4224 /** |
| 4359 * Clear the type information assocated with [node]. | 4225 * Clear the type information assocated with [node]. |
| 4360 */ | 4226 */ |
| 4361 static void clearType(AstNode node) { | 4227 static void clearType(AstNode node) { |
| 4362 node?.setProperty(_typeProperty, null); | 4228 node?.setProperty(_typeProperty, null); |
| 4363 } | 4229 } |
| 4364 | 4230 |
| 4365 /** | 4231 /** |
| 4366 * Look for contextual type information attached to [node]. Returns | 4232 * Look for contextual type information attached to [node], and returns |
| 4367 * the type if found, otherwise null. | 4233 * the type if found. |
| 4368 * | 4234 * |
| 4369 * If [node] has a contextual union type like `T | Future<T>` this will be | 4235 * The returned type may be partially or completely unknown, denoted with an |
| 4370 * returned. You can use [getType] if you prefer to only get the `T`. | 4236 * unknown type `?`, for example `List<?>` or `(?, int) -> void`. |
| 4237 * You can use [StrongTypeSystemImpl.upperBoundForType] or | |
| 4238 * [StrongTypeSystemImpl.lowerBoundForType] if you would prefer a known type | |
| 4239 * that represents the bound of the context type. | |
| 4371 */ | 4240 */ |
| 4372 static DartType getContext(AstNode node) => node?.getProperty(_typeProperty); | 4241 static DartType getContext(AstNode node) => node?.getProperty(_typeProperty); |
| 4373 | 4242 |
| 4374 /** | 4243 /** |
| 4375 * Look for a single contextual type attached to [node], and returns the type | |
| 4376 * if found, otherwise null. | |
| 4377 * | |
| 4378 * If [node] has a contextual union type like `T | Future<T>` this will | |
| 4379 * simplify it to only return `T`. If the caller can handle a union type, | |
| 4380 * [getContext] should be used instead. | |
| 4381 */ | |
| 4382 static DartType getType(AstNode node) { | |
| 4383 DartType t = getContext(node); | |
| 4384 if (t is InterfaceType && t.isDartAsyncFutureOr) { | |
| 4385 return t.typeArguments[0]; // The T in FutureOr<T> | |
| 4386 } | |
| 4387 return t; | |
| 4388 } | |
| 4389 | |
| 4390 /** | |
| 4391 * Attach contextual type information [type] to [node] for use during | 4244 * Attach contextual type information [type] to [node] for use during |
| 4392 * inference. | 4245 * inference. |
| 4393 */ | 4246 */ |
| 4394 static void setType(AstNode node, DartType type) { | 4247 static void setType(AstNode node, DartType type) { |
| 4395 if (type == null || type.isDynamic) { | 4248 if (type == null || type.isDynamic) { |
| 4396 clearType(node); | 4249 clearType(node); |
| 4397 } else { | 4250 } else { |
| 4398 node?.setProperty(_typeProperty, type); | 4251 node?.setProperty(_typeProperty, type); |
| 4399 } | 4252 } |
| 4400 } | 4253 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4502 */ | 4355 */ |
| 4503 void _resolveClassDeclaration(ClassDeclaration node) { | 4356 void _resolveClassDeclaration(ClassDeclaration node) { |
| 4504 _enclosingClassDeclaration = node; | 4357 _enclosingClassDeclaration = node; |
| 4505 ClassElement outerType = enclosingClass; | 4358 ClassElement outerType = enclosingClass; |
| 4506 Scope outerScope = nameScope; | 4359 Scope outerScope = nameScope; |
| 4507 try { | 4360 try { |
| 4508 enclosingClass = node.element; | 4361 enclosingClass = node.element; |
| 4509 typeAnalyzer.thisType = enclosingClass?.type; | 4362 typeAnalyzer.thisType = enclosingClass?.type; |
| 4510 if (enclosingClass == null) { | 4363 if (enclosingClass == null) { |
| 4511 AnalysisEngine.instance.logger.logInformation( | 4364 AnalysisEngine.instance.logger.logInformation( |
| 4512 "Missing element for class declaration ${node.name.name} in ${defini ngLibrary.source.fullName}", | 4365 "Missing element for class declaration ${node.name |
| 4366 .name} in ${definingLibrary.source.fullName}", | |
| 4513 new CaughtException(new AnalysisException(), null)); | 4367 new CaughtException(new AnalysisException(), null)); |
| 4514 // Don't try to re-resolve the initializers if we cannot set up the | 4368 // Don't try to re-resolve the initializers if we cannot set up the |
| 4515 // right name scope for resolution. | 4369 // right name scope for resolution. |
| 4516 } else { | 4370 } else { |
| 4517 nameScope = new ClassScope(nameScope, enclosingClass); | 4371 nameScope = new ClassScope(nameScope, enclosingClass); |
| 4518 NodeList<ClassMember> members = node.members; | 4372 NodeList<ClassMember> members = node.members; |
| 4519 int length = members.length; | 4373 int length = members.length; |
| 4520 for (int i = 0; i < length; i++) { | 4374 for (int i = 0; i < length; i++) { |
| 4521 ClassMember member = members[i]; | 4375 ClassMember member = members[i]; |
| 4522 if (member is FieldDeclaration) { | 4376 if (member is FieldDeclaration) { |
| (...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5449 assert(parent is PartOfDirective); | 5303 assert(parent is PartOfDirective); |
| 5450 } else { | 5304 } else { |
| 5451 elementAnnotationImpl.annotationAst = | 5305 elementAnnotationImpl.annotationAst = |
| 5452 new ConstantAstCloner().cloneNode(node); | 5306 new ConstantAstCloner().cloneNode(node); |
| 5453 } | 5307 } |
| 5454 return null; | 5308 return null; |
| 5455 } | 5309 } |
| 5456 | 5310 |
| 5457 @override | 5311 @override |
| 5458 Object visitArgumentList(ArgumentList node) { | 5312 Object visitArgumentList(ArgumentList node) { |
| 5459 DartType callerType = InferenceContext.getType(node); | 5313 DartType callerType = InferenceContext.getContext(node); |
| 5460 if (callerType is FunctionType) { | 5314 if (callerType is FunctionType) { |
| 5461 Map<String, DartType> namedParameterTypes = | 5315 Map<String, DartType> namedParameterTypes = |
| 5462 callerType.namedParameterTypes; | 5316 callerType.namedParameterTypes; |
| 5463 List<DartType> normalParameterTypes = callerType.normalParameterTypes; | 5317 List<DartType> normalParameterTypes = callerType.normalParameterTypes; |
| 5464 List<DartType> optionalParameterTypes = callerType.optionalParameterTypes; | 5318 List<DartType> optionalParameterTypes = callerType.optionalParameterTypes; |
| 5465 int normalCount = normalParameterTypes.length; | 5319 int normalCount = normalParameterTypes.length; |
| 5466 int optionalCount = optionalParameterTypes.length; | 5320 int optionalCount = optionalParameterTypes.length; |
| 5467 | 5321 |
| 5468 NodeList<Expression> arguments = node.arguments; | 5322 NodeList<Expression> arguments = node.arguments; |
| 5469 Iterable<Expression> positional = | 5323 Iterable<Expression> positional = |
| (...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6062 | 5916 |
| 6063 @override | 5917 @override |
| 6064 Object visitFunctionExpression(FunctionExpression node) { | 5918 Object visitFunctionExpression(FunctionExpression node) { |
| 6065 ExecutableElement outerFunction = _enclosingFunction; | 5919 ExecutableElement outerFunction = _enclosingFunction; |
| 6066 FunctionBody outerFunctionBody = _currentFunctionBody; | 5920 FunctionBody outerFunctionBody = _currentFunctionBody; |
| 6067 try { | 5921 try { |
| 6068 _currentFunctionBody = node.body; | 5922 _currentFunctionBody = node.body; |
| 6069 _enclosingFunction = node.element; | 5923 _enclosingFunction = node.element; |
| 6070 _overrideManager.enterScope(); | 5924 _overrideManager.enterScope(); |
| 6071 try { | 5925 try { |
| 6072 DartType functionType = InferenceContext.getType(node); | 5926 DartType functionType = InferenceContext.getContext(node); |
| 6073 if (functionType is FunctionType) { | 5927 var ts = typeSystem; |
| 5928 if (functionType is FunctionType && ts is StrongTypeSystemImpl) { | |
| 6074 functionType = | 5929 functionType = |
| 6075 matchFunctionTypeParameters(node.typeParameters, functionType); | 5930 matchFunctionTypeParameters(node.typeParameters, functionType); |
| 6076 if (functionType is FunctionType) { | 5931 if (functionType is FunctionType) { |
| 6077 _inferFormalParameterList(node.parameters, functionType); | 5932 _inferFormalParameterList(node.parameters, functionType); |
| 6078 DartType returnType; | 5933 DartType returnType; |
| 6079 ParameterElement parameterElement = | 5934 ParameterElement parameterElement = |
| 6080 resolutionMap.staticParameterElementForExpression(node); | 5935 resolutionMap.staticParameterElementForExpression(node); |
| 6081 if (isFutureThen(parameterElement?.enclosingElement)) { | 5936 if (isFutureThen(parameterElement?.enclosingElement)) { |
| 6082 var futureThenType = | 5937 var futureThenType = |
| 6083 InferenceContext.getContext(node.parent) as FunctionType; | 5938 InferenceContext.getContext(node.parent) as FunctionType; |
| 6084 | 5939 |
| 6085 // TODO(leafp): Get rid of this once code has been updated to use | 5940 // TODO(leafp): Get rid of this once code has been updated to use |
| 6086 // FutureOr | 5941 // FutureOr |
| 6087 // Introduce FutureOr<T> for backwards compatibility if it was | 5942 // Introduce FutureOr<T> for backwards compatibility if it was |
| 6088 // missing in old code. | 5943 // missing in old code. |
| 6089 if (futureThenType.parameters.isNotEmpty) { | 5944 if (futureThenType.parameters.isNotEmpty) { |
| 6090 if (!futureThenType.parameters[0].type.isDartAsyncFutureOr) { | 5945 if (!futureThenType.parameters[0].type.isDartAsyncFutureOr) { |
| 6091 var typeParamS = | 5946 var typeParamS = futureThenType.returnType.flattenFutures(ts); |
| 6092 futureThenType.returnType.flattenFutures(typeSystem); | |
| 6093 returnType = _createFutureOr(typeParamS); | 5947 returnType = _createFutureOr(typeParamS); |
| 6094 } | 5948 } |
| 6095 } | 5949 } |
| 6096 } | 5950 } |
| 6097 returnType ??= _computeReturnOrYieldType(functionType.returnType); | 5951 returnType ??= _computeReturnOrYieldType( |
| 5952 ts.upperBoundForType(functionType.returnType)); | |
|
Leaf
2017/03/15 00:27:13
Do we really want to eliminate this here? I think
| |
| 6098 InferenceContext.setType(node.body, returnType); | 5953 InferenceContext.setType(node.body, returnType); |
| 6099 } | 5954 } |
| 6100 } | 5955 } |
| 6101 super.visitFunctionExpression(node); | 5956 super.visitFunctionExpression(node); |
| 6102 } finally { | 5957 } finally { |
| 6103 _overrideManager.exitScope(); | 5958 _overrideManager.exitScope(); |
| 6104 } | 5959 } |
| 6105 } finally { | 5960 } finally { |
| 6106 _currentFunctionBody = outerFunctionBody; | 5961 _currentFunctionBody = outerFunctionBody; |
| 6107 _enclosingFunction = outerFunction; | 5962 _enclosingFunction = outerFunction; |
| 6108 } | 5963 } |
| 6109 return null; | 5964 return null; |
| 6110 } | 5965 } |
| 6111 | 5966 |
| 6112 @override | 5967 @override |
| 6113 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 5968 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 6114 node.function?.accept(this); | 5969 node.function?.accept(this); |
| 6115 node.accept(elementResolver); | 5970 node.accept(elementResolver); |
| 6116 _inferArgumentTypesFromContext(node); | 5971 _inferArgumentTypesForInvocation(node); |
| 6117 node.argumentList?.accept(this); | 5972 node.argumentList?.accept(this); |
| 6118 node.accept(typeAnalyzer); | 5973 node.accept(typeAnalyzer); |
| 6119 return null; | 5974 return null; |
| 6120 } | 5975 } |
| 6121 | 5976 |
| 6122 @override | 5977 @override |
| 6123 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 5978 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 6124 // Resolve the metadata in the library scope. | 5979 // Resolve the metadata in the library scope. |
| 6125 if (node.metadata != null) { | 5980 if (node.metadata != null) { |
| 6126 node.metadata.accept(this); | 5981 node.metadata.accept(this); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6204 <Map<VariableElement, DartType>>[]; | 6059 <Map<VariableElement, DartType>>[]; |
| 6205 perBranchOverrides.add(thenOverrides); | 6060 perBranchOverrides.add(thenOverrides); |
| 6206 perBranchOverrides.add(elseOverrides); | 6061 perBranchOverrides.add(elseOverrides); |
| 6207 _overrideManager.mergeOverrides(perBranchOverrides); | 6062 _overrideManager.mergeOverrides(perBranchOverrides); |
| 6208 } | 6063 } |
| 6209 return null; | 6064 return null; |
| 6210 } | 6065 } |
| 6211 | 6066 |
| 6212 @override | 6067 @override |
| 6213 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 6068 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 6214 TypeName classTypeName = node.constructorName.type; | |
| 6215 // TODO(leafp): Currently, we may re-infer types here, since we | |
| 6216 // sometimes resolve multiple times. We should really check that we | |
| 6217 // have not already inferred something. However, the obvious ways to | |
| 6218 // check this don't work, since we may have been instantiated | |
| 6219 // to bounds in an earlier phase, and we *do* want to do inference | |
| 6220 // in that case. | |
| 6221 if (classTypeName.typeArguments == null) { | |
| 6222 // Given a union of context types ` T0 | T1 | ... | Tn`, find the first | |
| 6223 // valid instantiation `new C<Ti>`, if it exists. | |
| 6224 // TODO(jmesserly): if we support union types for real, `new C<Ti | Tj>` | |
| 6225 // will become a valid possibility. Right now the only allowed union is | |
| 6226 // `T | Future<T>` so we can take a simple approach. | |
| 6227 for (var contextType in inferenceContext.getTypes(node)) { | |
| 6228 if (contextType is InterfaceType && | |
| 6229 contextType.typeArguments != null && | |
| 6230 contextType.typeArguments.isNotEmpty) { | |
| 6231 // TODO(jmesserly): for generic methods we use the | |
| 6232 // StrongTypeSystemImpl.inferGenericFunctionCall, which appears to | |
| 6233 // be a tad more powerful than matchTypes. | |
| 6234 // | |
| 6235 // For example it can infer this case: | |
| 6236 // | |
| 6237 // class E<S, T> extends A<C<S>, T> { ... } | |
| 6238 // A<C<int>, String> a0 = /*infer<int, String>*/new E("hello"); | |
| 6239 // | |
| 6240 // See _inferArgumentTypesFromContext in this file for use of it. | |
| 6241 List<DartType> targs = | |
| 6242 inferenceContext.matchTypes(classTypeName.type, contextType); | |
| 6243 if (targs != null && targs.any((t) => !t.isDynamic)) { | |
| 6244 ClassElement classElement = | |
| 6245 resolutionMap.typeForTypeName(classTypeName).element; | |
| 6246 InterfaceType rawType = classElement.type; | |
| 6247 InterfaceType fullType = | |
| 6248 rawType.substitute2(targs, rawType.typeArguments); | |
| 6249 // The element resolver uses the type on the constructor name, so | |
| 6250 // infer it first | |
| 6251 typeAnalyzer.inferConstructorName(node.constructorName, fullType); | |
| 6252 break; | |
| 6253 } | |
| 6254 } | |
| 6255 } | |
| 6256 } | |
| 6257 node.constructorName?.accept(this); | 6069 node.constructorName?.accept(this); |
| 6258 FunctionType constructorType = resolutionMap | 6070 _inferArgumentTypesForInstanceCreate(node); |
| 6259 .staticElementForConstructorReference(node.constructorName) | |
| 6260 ?.type; | |
| 6261 if (constructorType != null) { | |
| 6262 InferenceContext.setType(node.argumentList, constructorType); | |
| 6263 } | |
| 6264 node.argumentList?.accept(this); | 6071 node.argumentList?.accept(this); |
| 6265 node.accept(elementResolver); | 6072 node.accept(elementResolver); |
| 6266 node.accept(typeAnalyzer); | 6073 node.accept(typeAnalyzer); |
| 6267 return null; | 6074 return null; |
| 6268 } | 6075 } |
| 6269 | 6076 |
| 6270 @override | 6077 @override |
| 6271 Object visitLabel(Label node) => null; | 6078 Object visitLabel(Label node) => null; |
| 6272 | 6079 |
| 6273 @override | 6080 @override |
| 6274 Object visitLibraryIdentifier(LibraryIdentifier node) => null; | 6081 Object visitLibraryIdentifier(LibraryIdentifier node) => null; |
| 6275 | 6082 |
| 6276 @override | 6083 @override |
| 6277 Object visitListLiteral(ListLiteral node) { | 6084 Object visitListLiteral(ListLiteral node) { |
| 6278 DartType contextType = InferenceContext.getType(node); | 6085 InterfaceType listT; |
| 6279 List<DartType> targs = null; | 6086 |
| 6280 if (node.typeArguments != null) { | 6087 if (node.typeArguments != null) { |
| 6281 targs = node.typeArguments.arguments.map((t) => t.type).toList(); | 6088 var targs = node.typeArguments.arguments.map((t) => t.type).toList(); |
| 6282 } else if (contextType is InterfaceType) { | 6089 if (targs.length == 1 && !targs[0].isDynamic) { |
| 6283 InterfaceType listD = | 6090 listT = typeProvider.listType.instantiate([targs[0]]); |
| 6284 typeProvider.listType.instantiate([typeProvider.dynamicType]); | 6091 } |
| 6285 targs = inferenceContext.matchTypes(listD, contextType); | 6092 } else if (strongMode) { |
| 6093 listT = typeAnalyzer.inferListType(node, downwards: true); | |
| 6286 } | 6094 } |
| 6287 if (targs != null && targs.length == 1 && !targs[0].isDynamic) { | 6095 if (listT != null) { |
| 6288 DartType eType = targs[0]; | 6096 DartType eType = listT.typeArguments[0]; |
| 6289 InterfaceType listT = typeProvider.listType.instantiate([eType]); | |
| 6290 for (Expression child in node.elements) { | 6097 for (Expression child in node.elements) { |
| 6291 InferenceContext.setType(child, eType); | 6098 InferenceContext.setType(child, eType); |
| 6292 } | 6099 } |
| 6293 InferenceContext.setType(node, listT); | 6100 InferenceContext.setType(node, listT); |
| 6294 } else { | 6101 } else { |
| 6295 InferenceContext.clearType(node); | 6102 InferenceContext.clearType(node); |
| 6296 } | 6103 } |
| 6297 super.visitListLiteral(node); | 6104 super.visitListLiteral(node); |
| 6298 return null; | 6105 return null; |
| 6299 } | 6106 } |
| 6300 | 6107 |
| 6301 @override | 6108 @override |
| 6302 Object visitMapLiteral(MapLiteral node) { | 6109 Object visitMapLiteral(MapLiteral node) { |
| 6303 DartType contextType = InferenceContext.getType(node); | 6110 InterfaceType mapT; |
| 6304 List<DartType> targs = null; | |
| 6305 if (node.typeArguments != null) { | 6111 if (node.typeArguments != null) { |
| 6306 targs = node.typeArguments.arguments.map((t) => t.type).toList(); | 6112 var targs = node.typeArguments.arguments.map((t) => t.type).toList(); |
| 6307 } else if (contextType is InterfaceType) { | 6113 if (targs.length == 2 && targs.any((t) => !t.isDynamic)) { |
| 6308 InterfaceType mapD = typeProvider.mapType | 6114 mapT = typeProvider.mapType.instantiate([targs[0], targs[1]]); |
| 6309 .instantiate([typeProvider.dynamicType, typeProvider.dynamicType]); | 6115 } |
| 6310 targs = inferenceContext.matchTypes(mapD, contextType); | 6116 } else if (strongMode) { |
| 6117 mapT = typeAnalyzer.inferMapType(node, downwards: true); | |
| 6311 } | 6118 } |
| 6312 if (targs != null && targs.length == 2 && targs.any((t) => !t.isDynamic)) { | 6119 if (mapT != null) { |
| 6313 DartType kType = targs[0]; | 6120 DartType kType = mapT.typeArguments[0]; |
| 6314 DartType vType = targs[1]; | 6121 DartType vType = mapT.typeArguments[1]; |
| 6315 InterfaceType mapT = typeProvider.mapType.instantiate([kType, vType]); | |
| 6316 for (MapLiteralEntry entry in node.entries) { | 6122 for (MapLiteralEntry entry in node.entries) { |
| 6317 InferenceContext.setType(entry.key, kType); | 6123 InferenceContext.setType(entry.key, kType); |
| 6318 InferenceContext.setType(entry.value, vType); | 6124 InferenceContext.setType(entry.value, vType); |
| 6319 } | 6125 } |
| 6320 InferenceContext.setType(node, mapT); | 6126 InferenceContext.setType(node, mapT); |
| 6321 } else { | 6127 } else { |
| 6322 InferenceContext.clearType(node); | 6128 InferenceContext.clearType(node); |
| 6323 } | 6129 } |
| 6324 super.visitMapLiteral(node); | 6130 super.visitMapLiteral(node); |
| 6325 return null; | 6131 return null; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 6351 | 6157 |
| 6352 @override | 6158 @override |
| 6353 Object visitMethodInvocation(MethodInvocation node) { | 6159 Object visitMethodInvocation(MethodInvocation node) { |
| 6354 // | 6160 // |
| 6355 // We visit the target and argument list, but do not visit the method name | 6161 // We visit the target and argument list, but do not visit the method name |
| 6356 // because it needs to be visited in the context of the invocation. | 6162 // because it needs to be visited in the context of the invocation. |
| 6357 // | 6163 // |
| 6358 node.target?.accept(this); | 6164 node.target?.accept(this); |
| 6359 node.typeArguments?.accept(this); | 6165 node.typeArguments?.accept(this); |
| 6360 node.accept(elementResolver); | 6166 node.accept(elementResolver); |
| 6361 _inferArgumentTypesFromContext(node); | 6167 _inferArgumentTypesForInvocation(node); |
| 6362 node.argumentList?.accept(this); | 6168 node.argumentList?.accept(this); |
| 6363 node.accept(typeAnalyzer); | 6169 node.accept(typeAnalyzer); |
| 6364 return null; | 6170 return null; |
| 6365 } | 6171 } |
| 6366 | 6172 |
| 6367 @override | 6173 @override |
| 6368 Object visitNamedExpression(NamedExpression node) { | 6174 Object visitNamedExpression(NamedExpression node) { |
| 6369 InferenceContext.setTypeFromNode(node.expression, node); | 6175 InferenceContext.setTypeFromNode(node.expression, node); |
| 6370 return super.visitNamedExpression(node); | 6176 return super.visitNamedExpression(node); |
| 6371 } | 6177 } |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6644 | 6450 |
| 6645 // Ordinary functions just return their declared types. | 6451 // Ordinary functions just return their declared types. |
| 6646 if (!isGenerator && !isAsynchronous) { | 6452 if (!isGenerator && !isAsynchronous) { |
| 6647 return declaredType; | 6453 return declaredType; |
| 6648 } | 6454 } |
| 6649 if (declaredType is InterfaceType) { | 6455 if (declaredType is InterfaceType) { |
| 6650 if (isGenerator) { | 6456 if (isGenerator) { |
| 6651 // If it's sync* we expect Iterable<T> | 6457 // If it's sync* we expect Iterable<T> |
| 6652 // If it's async* we expect Stream<T> | 6458 // If it's async* we expect Stream<T> |
| 6653 InterfaceType rawType = isAsynchronous | 6459 InterfaceType rawType = isAsynchronous |
| 6654 ? typeProvider.streamDynamicType | 6460 ? typeProvider.streamType |
| 6655 : typeProvider.iterableDynamicType; | 6461 : typeProvider.iterableType; |
| 6656 // Match the types to instantiate the type arguments if possible | 6462 // Match the types to instantiate the type arguments if possible |
| 6657 List<DartType> typeArgs = | 6463 List<DartType> targs = declaredType.typeArguments; |
| 6658 inferenceContext.matchTypes(rawType, declaredType); | 6464 if (targs.length == 1 && rawType.instantiate(targs) == declaredType) { |
| 6659 return (typeArgs?.length == 1) ? typeArgs[0] : null; | 6465 return targs[0]; |
| 6466 } | |
| 6660 } | 6467 } |
| 6661 // async functions expect `Future<T> | T` | 6468 // async functions expect `Future<T> | T` |
| 6662 var futureTypeParam = declaredType.flattenFutures(typeSystem); | 6469 var futureTypeParam = declaredType.flattenFutures(typeSystem); |
| 6663 return _createFutureOr(futureTypeParam); | 6470 return _createFutureOr(futureTypeParam); |
| 6664 } | 6471 } |
| 6665 return declaredType; | 6472 return declaredType; |
| 6666 } | 6473 } |
| 6667 | 6474 |
| 6668 /** | 6475 /** |
| 6669 * Creates a union of `T | Future<T>`, unless `T` is already a | 6476 * Creates a union of `T | Future<T>`, unless `T` is already a |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6748 if (executable is MethodElement) { | 6555 if (executable is MethodElement) { |
| 6749 return true; | 6556 return true; |
| 6750 } | 6557 } |
| 6751 if (executable is FunctionElement) { | 6558 if (executable is FunctionElement) { |
| 6752 return executable.enclosingElement is CompilationUnitElement; | 6559 return executable.enclosingElement is CompilationUnitElement; |
| 6753 } | 6560 } |
| 6754 } | 6561 } |
| 6755 return false; | 6562 return false; |
| 6756 } | 6563 } |
| 6757 | 6564 |
| 6758 void _inferArgumentTypesFromContext(InvocationExpression node) { | 6565 FunctionType _inferArgumentTypesForGeneric(AstNode inferenceNode, |
| 6566 DartType uninstantiatedType, TypeArgumentList typeArguments, | |
| 6567 {AstNode errorNode}) { | |
| 6568 errorNode ??= inferenceNode; | |
| 6569 TypeSystem ts = typeSystem; | |
| 6570 if (typeArguments == null && | |
| 6571 uninstantiatedType is FunctionType && | |
| 6572 uninstantiatedType.typeFormals.isNotEmpty && | |
| 6573 ts is StrongTypeSystemImpl) { | |
| 6574 return ts.inferGenericFunctionOrType/*<FunctionType>*/( | |
| 6575 uninstantiatedType, | |
| 6576 ParameterElement.EMPTY_LIST, | |
| 6577 DartType.EMPTY_LIST, | |
| 6578 InferenceContext.getContext(inferenceNode), | |
| 6579 downwards: true, | |
| 6580 errorReporter: errorReporter, | |
| 6581 errorNode: errorNode); | |
| 6582 } | |
| 6583 return null; | |
| 6584 } | |
| 6585 | |
| 6586 void _inferArgumentTypesForInstanceCreate(InstanceCreationExpression node) { | |
| 6587 ConstructorName constructor = node.constructorName; | |
| 6588 TypeName classTypeName = constructor?.type; | |
| 6589 if (classTypeName == null || !strongMode) { | |
| 6590 return; | |
| 6591 } | |
| 6592 | |
| 6593 ConstructorElement originalElement = | |
| 6594 resolutionMap.staticElementForConstructorReference(constructor); | |
| 6595 FunctionType inferred; | |
| 6596 // If the constructor is generic, we'll have a ConstructorMember that | |
| 6597 // substitutes in type arguments (possibly `dynamic`) from earlier in | |
| 6598 // resolution. | |
| 6599 // | |
| 6600 // Otherwise we'll have a ConstructorElement, and we can skip inference | |
| 6601 // because there's nothing to infer in a non-generic type. | |
| 6602 if (classTypeName.typeArguments == null && | |
| 6603 originalElement is ConstructorMember) { | |
| 6604 // TODO(leafp): Currently, we may re-infer types here, since we | |
| 6605 // sometimes resolve multiple times. We should really check that we | |
| 6606 // have not already inferred something. However, the obvious ways to | |
| 6607 // check this don't work, since we may have been instantiated | |
| 6608 // to bounds in an earlier phase, and we *do* want to do inference | |
| 6609 // in that case. | |
| 6610 | |
| 6611 // Get back to the uninstantiated generic constructor. | |
| 6612 // TODO(jmesserly): should we store this earlier in resolution? | |
| 6613 // Or look it up, instead of jumping backwards through the Member? | |
| 6614 var rawElement = originalElement.baseElement; | |
| 6615 | |
| 6616 FunctionType constructorType = | |
| 6617 StaticTypeAnalyzer.constructorToGenericFunctionType(rawElement); | |
| 6618 | |
| 6619 inferred = _inferArgumentTypesForGeneric( | |
| 6620 node, constructorType, constructor.type.typeArguments, | |
| 6621 errorNode: node.constructorName); | |
| 6622 | |
| 6623 if (inferred != null) { | |
| 6624 ArgumentList arguments = node.argumentList; | |
| 6625 InferenceContext.setType(arguments, inferred); | |
| 6626 // Fix up the parameter elements based on inferred method. | |
| 6627 arguments.correspondingStaticParameters = | |
| 6628 resolveArgumentsToParameters(arguments, inferred.parameters, null); | |
| 6629 | |
| 6630 constructor.type.type = inferred.returnType; | |
| 6631 if (UnknownInferredType.isKnown(inferred)) { | |
| 6632 inferenceContext.recordInference(node, inferred.returnType); | |
| 6633 } | |
| 6634 | |
| 6635 // Update the static element as well. This is used in some cases, such | |
| 6636 // as computing constant values. It is stored in two places. | |
| 6637 constructor.staticElement = | |
| 6638 ConstructorMember.from(rawElement, inferred.returnType); | |
| 6639 node.staticElement = constructor.staticElement; | |
| 6640 } | |
| 6641 } | |
| 6642 | |
| 6643 if (inferred == null) { | |
| 6644 InferenceContext.setType(node.argumentList, originalElement?.type); | |
| 6645 } | |
| 6646 } | |
| 6647 | |
| 6648 void _inferArgumentTypesForInvocation(InvocationExpression node) { | |
| 6759 if (!strongMode) { | 6649 if (!strongMode) { |
| 6760 // Use propagated type inference for lambdas if not in strong mode. | 6650 // Use propagated type inference for lambdas if not in strong mode. |
| 6761 _inferFunctionExpressionsParametersTypes(node.argumentList); | 6651 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 6762 return; | 6652 return; |
| 6763 } | 6653 } |
| 6764 | 6654 DartType inferred = _inferArgumentTypesForGeneric( |
| 6765 DartType contextType = node.staticInvokeType; | 6655 node, node.function.staticType, node.typeArguments); |
| 6766 if (contextType is FunctionType) { | 6656 InferenceContext.setType( |
| 6767 DartType originalType = node.function.staticType; | 6657 node.argumentList, inferred ?? node.staticInvokeType); |
| 6768 DartType returnContextType = InferenceContext.getContext(node); | |
| 6769 TypeSystem ts = typeSystem; | |
| 6770 if (returnContextType != null && | |
| 6771 node.typeArguments == null && | |
| 6772 originalType is FunctionType && | |
| 6773 originalType.typeFormals.isNotEmpty && | |
| 6774 ts is StrongTypeSystemImpl) { | |
| 6775 contextType = ts.inferGenericFunctionCall( | |
| 6776 originalType, | |
| 6777 DartType.EMPTY_LIST, | |
| 6778 DartType.EMPTY_LIST, | |
| 6779 originalType.returnType, | |
| 6780 returnContextType); | |
| 6781 } | |
| 6782 | |
| 6783 InferenceContext.setType(node.argumentList, contextType); | |
| 6784 } | |
| 6785 } | 6658 } |
| 6786 | 6659 |
| 6787 void _inferFormalParameterList(FormalParameterList node, DartType type) { | 6660 void _inferFormalParameterList(FormalParameterList node, DartType type) { |
| 6788 if (typeAnalyzer.inferFormalParameterList(node, type)) { | 6661 if (typeAnalyzer.inferFormalParameterList(node, type)) { |
| 6789 // TODO(leafp): This gets dropped on the floor if we're in the field | 6662 // TODO(leafp): This gets dropped on the floor if we're in the field |
| 6790 // inference task. We should probably keep these infos. | 6663 // inference task. We should probably keep these infos. |
| 6791 // | 6664 // |
| 6792 // TODO(jmesserly): this is reporting the context type, and therefore not | 6665 // TODO(jmesserly): this is reporting the context type, and therefore not |
| 6793 // necessarily the correct inferred type for the lambda. | 6666 // necessarily the correct inferred type for the lambda. |
| 6794 // | 6667 // |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7356 return null; | 7229 return null; |
| 7357 } | 7230 } |
| 7358 | 7231 |
| 7359 @override | 7232 @override |
| 7360 Object visitClassDeclaration(ClassDeclaration node) { | 7233 Object visitClassDeclaration(ClassDeclaration node) { |
| 7361 ClassElement classElement = node.element; | 7234 ClassElement classElement = node.element; |
| 7362 Scope outerScope = nameScope; | 7235 Scope outerScope = nameScope; |
| 7363 try { | 7236 try { |
| 7364 if (classElement == null) { | 7237 if (classElement == null) { |
| 7365 AnalysisEngine.instance.logger.logInformation( | 7238 AnalysisEngine.instance.logger.logInformation( |
| 7366 "Missing element for class declaration ${node.name.name} in ${defini ngLibrary.source.fullName}", | 7239 "Missing element for class declaration ${node.name |
| 7240 .name} in ${definingLibrary.source.fullName}", | |
| 7367 new CaughtException(new AnalysisException(), null)); | 7241 new CaughtException(new AnalysisException(), null)); |
| 7368 super.visitClassDeclaration(node); | 7242 super.visitClassDeclaration(node); |
| 7369 } else { | 7243 } else { |
| 7370 ClassElement outerClass = enclosingClass; | 7244 ClassElement outerClass = enclosingClass; |
| 7371 try { | 7245 try { |
| 7372 enclosingClass = node.element; | 7246 enclosingClass = node.element; |
| 7373 nameScope = new TypeParameterScope(nameScope, classElement); | 7247 nameScope = new TypeParameterScope(nameScope, classElement); |
| 7374 visitClassDeclarationInScope(node); | 7248 visitClassDeclarationInScope(node); |
| 7375 nameScope = new ClassScope(nameScope, classElement); | 7249 nameScope = new ClassScope(nameScope, classElement); |
| 7376 visitClassMembersInScope(node); | 7250 visitClassMembersInScope(node); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7484 return null; | 7358 return null; |
| 7485 } | 7359 } |
| 7486 | 7360 |
| 7487 @override | 7361 @override |
| 7488 Object visitEnumDeclaration(EnumDeclaration node) { | 7362 Object visitEnumDeclaration(EnumDeclaration node) { |
| 7489 ClassElement classElement = node.element; | 7363 ClassElement classElement = node.element; |
| 7490 Scope outerScope = nameScope; | 7364 Scope outerScope = nameScope; |
| 7491 try { | 7365 try { |
| 7492 if (classElement == null) { | 7366 if (classElement == null) { |
| 7493 AnalysisEngine.instance.logger.logInformation( | 7367 AnalysisEngine.instance.logger.logInformation( |
| 7494 "Missing element for enum declaration ${node.name.name} in ${definin gLibrary.source.fullName}", | 7368 "Missing element for enum declaration ${node.name |
| 7369 .name} in ${definingLibrary.source.fullName}", | |
| 7495 new CaughtException(new AnalysisException(), null)); | 7370 new CaughtException(new AnalysisException(), null)); |
| 7496 super.visitEnumDeclaration(node); | 7371 super.visitEnumDeclaration(node); |
| 7497 } else { | 7372 } else { |
| 7498 ClassElement outerClass = enclosingClass; | 7373 ClassElement outerClass = enclosingClass; |
| 7499 try { | 7374 try { |
| 7500 enclosingClass = node.element; | 7375 enclosingClass = node.element; |
| 7501 nameScope = new ClassScope(nameScope, classElement); | 7376 nameScope = new ClassScope(nameScope, classElement); |
| 7502 visitEnumMembersInScope(node); | 7377 visitEnumMembersInScope(node); |
| 7503 } finally { | 7378 } finally { |
| 7504 enclosingClass = outerClass; | 7379 enclosingClass = outerClass; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7600 Object visitFunctionDeclaration(FunctionDeclaration node) { | 7475 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 7601 ExecutableElement functionElement = node.element; | 7476 ExecutableElement functionElement = node.element; |
| 7602 if (functionElement != null && | 7477 if (functionElement != null && |
| 7603 functionElement.enclosingElement is! CompilationUnitElement) { | 7478 functionElement.enclosingElement is! CompilationUnitElement) { |
| 7604 nameScope.define(functionElement); | 7479 nameScope.define(functionElement); |
| 7605 } | 7480 } |
| 7606 Scope outerScope = nameScope; | 7481 Scope outerScope = nameScope; |
| 7607 try { | 7482 try { |
| 7608 if (functionElement == null) { | 7483 if (functionElement == null) { |
| 7609 AnalysisEngine.instance.logger.logInformation( | 7484 AnalysisEngine.instance.logger.logInformation( |
| 7610 "Missing element for top-level function ${node.name.name} in ${defin ingLibrary.source.fullName}", | 7485 "Missing element for top-level function ${node.name |
| 7486 .name} in ${definingLibrary.source.fullName}", | |
| 7611 new CaughtException(new AnalysisException(), null)); | 7487 new CaughtException(new AnalysisException(), null)); |
| 7612 } else { | 7488 } else { |
| 7613 nameScope = new FunctionScope(nameScope, functionElement); | 7489 nameScope = new FunctionScope(nameScope, functionElement); |
| 7614 } | 7490 } |
| 7615 visitFunctionDeclarationInScope(node); | 7491 visitFunctionDeclarationInScope(node); |
| 7616 } finally { | 7492 } finally { |
| 7617 nameScope = outerScope; | 7493 nameScope = outerScope; |
| 7618 } | 7494 } |
| 7619 return null; | 7495 return null; |
| 7620 } | 7496 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7676 super.visitFunctionTypeAlias(node); | 7552 super.visitFunctionTypeAlias(node); |
| 7677 } | 7553 } |
| 7678 | 7554 |
| 7679 @override | 7555 @override |
| 7680 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 7556 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 7681 Scope outerScope = nameScope; | 7557 Scope outerScope = nameScope; |
| 7682 try { | 7558 try { |
| 7683 ParameterElement parameterElement = node.element; | 7559 ParameterElement parameterElement = node.element; |
| 7684 if (parameterElement == null) { | 7560 if (parameterElement == null) { |
| 7685 AnalysisEngine.instance.logger.logInformation( | 7561 AnalysisEngine.instance.logger.logInformation( |
| 7686 "Missing element for function typed formal parameter ${node.identifi er.name} in ${definingLibrary.source.fullName}", | 7562 "Missing element for function typed formal parameter ${node |
| 7563 .identifier.name} in ${definingLibrary.source.fullName}", | |
| 7687 new CaughtException(new AnalysisException(), null)); | 7564 new CaughtException(new AnalysisException(), null)); |
| 7688 } else { | 7565 } else { |
| 7689 nameScope = new EnclosedScope(nameScope); | 7566 nameScope = new EnclosedScope(nameScope); |
| 7690 List<TypeParameterElement> typeParameters = | 7567 List<TypeParameterElement> typeParameters = |
| 7691 parameterElement.typeParameters; | 7568 parameterElement.typeParameters; |
| 7692 int length = typeParameters.length; | 7569 int length = typeParameters.length; |
| 7693 for (int i = 0; i < length; i++) { | 7570 for (int i = 0; i < length; i++) { |
| 7694 nameScope.define(typeParameters[i]); | 7571 nameScope.define(typeParameters[i]); |
| 7695 } | 7572 } |
| 7696 } | 7573 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 7720 return null; | 7597 return null; |
| 7721 } | 7598 } |
| 7722 | 7599 |
| 7723 @override | 7600 @override |
| 7724 Object visitMethodDeclaration(MethodDeclaration node) { | 7601 Object visitMethodDeclaration(MethodDeclaration node) { |
| 7725 Scope outerScope = nameScope; | 7602 Scope outerScope = nameScope; |
| 7726 try { | 7603 try { |
| 7727 ExecutableElement methodElement = node.element; | 7604 ExecutableElement methodElement = node.element; |
| 7728 if (methodElement == null) { | 7605 if (methodElement == null) { |
| 7729 AnalysisEngine.instance.logger.logInformation( | 7606 AnalysisEngine.instance.logger.logInformation( |
| 7730 "Missing element for method ${node.name.name} in ${definingLibrary.s ource.fullName}", | 7607 "Missing element for method ${node.name.name} in ${definingLibrary |
| 7608 .source.fullName}", | |
| 7731 new CaughtException(new AnalysisException(), null)); | 7609 new CaughtException(new AnalysisException(), null)); |
| 7732 } else { | 7610 } else { |
| 7733 nameScope = new FunctionScope(nameScope, methodElement); | 7611 nameScope = new FunctionScope(nameScope, methodElement); |
| 7734 } | 7612 } |
| 7735 visitMethodDeclarationInScope(node); | 7613 visitMethodDeclarationInScope(node); |
| 7736 } finally { | 7614 } finally { |
| 7737 nameScope = outerScope; | 7615 nameScope = outerScope; |
| 7738 } | 7616 } |
| 7739 return null; | 7617 return null; |
| 7740 } | 7618 } |
| (...skipping 3158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10899 return null; | 10777 return null; |
| 10900 } | 10778 } |
| 10901 if (identical(node.staticElement, variable)) { | 10779 if (identical(node.staticElement, variable)) { |
| 10902 if (node.inSetterContext()) { | 10780 if (node.inSetterContext()) { |
| 10903 result = true; | 10781 result = true; |
| 10904 } | 10782 } |
| 10905 } | 10783 } |
| 10906 return null; | 10784 return null; |
| 10907 } | 10785 } |
| 10908 } | 10786 } |
| OLD | NEW |