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 | |
2 // for details. All rights reserved. Use of this source code is governed by a | 3 // 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. | 4 // BSD-style license that can be found in the LICENSE file. |
4 | 5 |
5 library analyzer.src.generated.resolver; | 6 library analyzer.src.generated.resolver; |
6 | 7 |
7 import 'dart:collection'; | 8 import 'dart:collection'; |
8 | 9 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | 11 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
11 import 'package:analyzer/dart/ast/token.dart'; | 12 import 'package:analyzer/dart/ast/token.dart'; |
12 import 'package:analyzer/dart/ast/visitor.dart'; | 13 import 'package:analyzer/dart/ast/visitor.dart'; |
13 import 'package:analyzer/dart/element/element.dart'; | 14 import 'package:analyzer/dart/element/element.dart'; |
14 import 'package:analyzer/dart/element/type.dart'; | 15 import 'package:analyzer/dart/element/type.dart'; |
15 import 'package:analyzer/dart/element/visitor.dart'; | 16 import 'package:analyzer/dart/element/visitor.dart'; |
16 import 'package:analyzer/error/error.dart'; | 17 import 'package:analyzer/error/error.dart'; |
17 import 'package:analyzer/error/listener.dart'; | 18 import 'package:analyzer/error/listener.dart'; |
18 import 'package:analyzer/exception/exception.dart'; | 19 import 'package:analyzer/exception/exception.dart'; |
19 import 'package:analyzer/src/dart/ast/ast.dart'; | 20 import 'package:analyzer/src/dart/ast/ast.dart'; |
20 import 'package:analyzer/src/dart/ast/utilities.dart'; | 21 import 'package:analyzer/src/dart/ast/utilities.dart'; |
21 import 'package:analyzer/src/dart/element/element.dart'; | 22 import 'package:analyzer/src/dart/element/element.dart'; |
23 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember; | |
22 import 'package:analyzer/src/dart/element/type.dart'; | 24 import 'package:analyzer/src/dart/element/type.dart'; |
23 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; | 25 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; |
24 import 'package:analyzer/src/dart/resolver/scope.dart'; | 26 import 'package:analyzer/src/dart/resolver/scope.dart'; |
25 import 'package:analyzer/src/error/codes.dart'; | 27 import 'package:analyzer/src/error/codes.dart'; |
26 import 'package:analyzer/src/generated/constant.dart'; | 28 import 'package:analyzer/src/generated/constant.dart'; |
27 import 'package:analyzer/src/generated/element_resolver.dart'; | 29 import 'package:analyzer/src/generated/element_resolver.dart'; |
28 import 'package:analyzer/src/generated/engine.dart'; | 30 import 'package:analyzer/src/generated/engine.dart'; |
29 import 'package:analyzer/src/generated/error_verifier.dart'; | 31 import 'package:analyzer/src/generated/error_verifier.dart'; |
30 import 'package:analyzer/src/generated/source.dart'; | 32 import 'package:analyzer/src/generated/source.dart'; |
31 import 'package:analyzer/src/generated/static_type_analyzer.dart'; | 33 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(), | 644 // TODO(jwren) We should modify ConstructorElement.getDisplayName(), |
643 // or have the logic centralized elsewhere, instead of doing this logic | 645 // or have the logic centralized elsewhere, instead of doing this logic |
644 // here. | 646 // here. |
645 displayName = element.enclosingElement.displayName; | 647 displayName = element.enclosingElement.displayName; |
646 if (!element.displayName.isEmpty) { | 648 if (!element.displayName.isEmpty) { |
647 displayName = "$displayName.${element.displayName}"; | 649 displayName = "$displayName.${element.displayName}"; |
648 } | 650 } |
649 } else if (displayName == FunctionElement.CALL_METHOD_NAME && | 651 } else if (displayName == FunctionElement.CALL_METHOD_NAME && |
650 node is MethodInvocation && | 652 node is MethodInvocation && |
651 node.staticInvokeType is InterfaceType) { | 653 node.staticInvokeType is InterfaceType) { |
652 displayName = | 654 displayName = "${resolutionMap |
653 "${resolutionMap.staticInvokeTypeForInvocationExpression(node).displ ayName}.${element.displayName}"; | 655 .staticInvokeTypeForInvocationExpression(node) |
656 .displayName}.${element.displayName}"; | |
654 } | 657 } |
655 _errorReporter.reportErrorForNode( | 658 _errorReporter.reportErrorForNode( |
656 HintCode.DEPRECATED_MEMBER_USE, node, [displayName]); | 659 HintCode.DEPRECATED_MEMBER_USE, node, [displayName]); |
657 } | 660 } |
658 } | 661 } |
659 | 662 |
660 /** | 663 /** |
661 * For [SimpleIdentifier]s, only call [checkForDeprecatedMemberUse] | 664 * For [SimpleIdentifier]s, only call [checkForDeprecatedMemberUse] |
662 * if the node is not in a declaration context. | 665 * if the node is not in a declaration context. |
663 * | 666 * |
(...skipping 3498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4162 if (_returnStack.isEmpty) { | 4165 if (_returnStack.isEmpty) { |
4163 return; | 4166 return; |
4164 } | 4167 } |
4165 | 4168 |
4166 DartType inferred = _inferredReturn.last; | 4169 DartType inferred = _inferredReturn.last; |
4167 inferred = _typeSystem.getLeastUpperBound(type, inferred); | 4170 inferred = _typeSystem.getLeastUpperBound(type, inferred); |
4168 _inferredReturn[_inferredReturn.length - 1] = inferred; | 4171 _inferredReturn[_inferredReturn.length - 1] = inferred; |
4169 } | 4172 } |
4170 | 4173 |
4171 /** | 4174 /** |
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. | 4175 * Pop a return type off of the return stack. |
4202 * | 4176 * |
4203 * Also record any inferred return type using [setType], unless this node | 4177 * 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 | 4178 * already has a context type. This recorded type will be the least upper |
4205 * bound of all types added with [addReturnOrYieldType]. | 4179 * bound of all types added with [addReturnOrYieldType]. |
4206 */ | 4180 */ |
4207 void popReturnContext(BlockFunctionBody node) { | 4181 void popReturnContext(BlockFunctionBody node) { |
4208 if (_returnStack.isNotEmpty && _inferredReturn.isNotEmpty) { | 4182 if (_returnStack.isNotEmpty && _inferredReturn.isNotEmpty) { |
4209 DartType context = _returnStack.removeLast() ?? DynamicTypeImpl.instance; | 4183 DartType context = _returnStack.removeLast() ?? DynamicTypeImpl.instance; |
4210 DartType inferred = _inferredReturn.removeLast(); | 4184 DartType inferred = _inferredReturn.removeLast(); |
(...skipping 30 matching lines...) Expand all Loading... | |
4241 error = StrongModeCode.INFERRED_TYPE_ALLOCATION; | 4215 error = StrongModeCode.INFERRED_TYPE_ALLOCATION; |
4242 } else if (node is FunctionExpression) { | 4216 } else if (node is FunctionExpression) { |
4243 error = StrongModeCode.INFERRED_TYPE_CLOSURE; | 4217 error = StrongModeCode.INFERRED_TYPE_CLOSURE; |
4244 } else { | 4218 } else { |
4245 error = StrongModeCode.INFERRED_TYPE; | 4219 error = StrongModeCode.INFERRED_TYPE; |
4246 } | 4220 } |
4247 | 4221 |
4248 _errorReporter.reportErrorForNode(error, node, [node, type]); | 4222 _errorReporter.reportErrorForNode(error, node, [node, type]); |
4249 } | 4223 } |
4250 | 4224 |
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 /** | 4225 /** |
4359 * Clear the type information assocated with [node]. | 4226 * Clear the type information assocated with [node]. |
4360 */ | 4227 */ |
4361 static void clearType(AstNode node) { | 4228 static void clearType(AstNode node) { |
4362 node?.setProperty(_typeProperty, null); | 4229 node?.setProperty(_typeProperty, null); |
4363 } | 4230 } |
4364 | 4231 |
4365 /** | 4232 /** |
4366 * Look for contextual type information attached to [node]. Returns | 4233 * Look for contextual type information attached to [node], and returns |
4367 * the type if found, otherwise null. | 4234 * the type if found. |
4368 * | 4235 * |
4369 * If [node] has a contextual union type like `T | Future<T>` this will be | 4236 * If [node] has a contextual union type like `T | Future<T>` or a type that |
4370 * returned. You can use [getType] if you prefer to only get the `T`. | 4237 * contains `?` this will be returned. You can use [getValueContext] if you |
Leaf
2017/03/14 22:37:40
Is this residual? I can't find getValueContext an
Jennifer Messerly
2017/03/14 23:49:09
fixed!
| |
4238 * prefer to eliminate the Future union, or [getType] to eliminate both. | |
4371 */ | 4239 */ |
4372 static DartType getContext(AstNode node) => node?.getProperty(_typeProperty); | 4240 static DartType getContext(AstNode node) => node?.getProperty(_typeProperty); |
4373 | 4241 |
4374 /** | 4242 /** |
4375 * Look for a single contextual type attached to [node], and returns the type | 4243 * Look for a single contextual type attached to [node], and returns the type |
4376 * if found, otherwise null. | 4244 * if found, otherwise null. |
4377 * | 4245 * |
4378 * If [node] has a contextual union type like `T | Future<T>` this will | 4246 * 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, | 4247 * simplify it to only return `T`. If the caller can handle a union type, |
4380 * [getContext] should be used instead. | 4248 * [getContext] should be used instead. |
4381 */ | 4249 */ |
4382 static DartType getType(AstNode node) { | 4250 DartType getType(AstNode node) { |
4383 DartType t = getContext(node); | 4251 DartType t = getContext(node); |
4384 if (t is InterfaceType && t.isDartAsyncFutureOr) { | 4252 if (t == null) return null; |
4385 return t.typeArguments[0]; // The T in FutureOr<T> | 4253 var ts = _typeSystem; |
4254 if (ts is StrongTypeSystemImpl) { | |
4255 if (t is InterfaceType && t.isDartAsyncFutureOr) { | |
4256 return ts.upperBoundForType(t.typeArguments[0]); // The T in FutureOr<T> | |
4257 } | |
4258 // Since the type is being used for downwards inference, the expression | |
4259 // type E must be a subtype of the context type T, i.e. T is an upper boun d. | |
Leaf
2017/03/14 22:37:40
length.
Jennifer Messerly
2017/03/14 23:49:09
fixed, this method is gone now.
| |
4260 return ts.upperBoundForType(t); | |
4386 } | 4261 } |
4387 return t; | 4262 return null; |
4388 } | 4263 } |
4389 | 4264 |
4390 /** | 4265 /** |
4391 * Attach contextual type information [type] to [node] for use during | 4266 * Attach contextual type information [type] to [node] for use during |
4392 * inference. | 4267 * inference. |
4393 */ | 4268 */ |
4394 static void setType(AstNode node, DartType type) { | 4269 static void setType(AstNode node, DartType type) { |
4395 if (type == null || type.isDynamic) { | 4270 if (type == null || type.isDynamic) { |
4396 clearType(node); | 4271 clearType(node); |
4397 } else { | 4272 } else { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4502 */ | 4377 */ |
4503 void _resolveClassDeclaration(ClassDeclaration node) { | 4378 void _resolveClassDeclaration(ClassDeclaration node) { |
4504 _enclosingClassDeclaration = node; | 4379 _enclosingClassDeclaration = node; |
4505 ClassElement outerType = enclosingClass; | 4380 ClassElement outerType = enclosingClass; |
4506 Scope outerScope = nameScope; | 4381 Scope outerScope = nameScope; |
4507 try { | 4382 try { |
4508 enclosingClass = node.element; | 4383 enclosingClass = node.element; |
4509 typeAnalyzer.thisType = enclosingClass?.type; | 4384 typeAnalyzer.thisType = enclosingClass?.type; |
4510 if (enclosingClass == null) { | 4385 if (enclosingClass == null) { |
4511 AnalysisEngine.instance.logger.logInformation( | 4386 AnalysisEngine.instance.logger.logInformation( |
4512 "Missing element for class declaration ${node.name.name} in ${defini ngLibrary.source.fullName}", | 4387 "Missing element for class declaration ${node.name |
4388 .name} in ${definingLibrary.source.fullName}", | |
4513 new CaughtException(new AnalysisException(), null)); | 4389 new CaughtException(new AnalysisException(), null)); |
4514 // Don't try to re-resolve the initializers if we cannot set up the | 4390 // Don't try to re-resolve the initializers if we cannot set up the |
4515 // right name scope for resolution. | 4391 // right name scope for resolution. |
4516 } else { | 4392 } else { |
4517 nameScope = new ClassScope(nameScope, enclosingClass); | 4393 nameScope = new ClassScope(nameScope, enclosingClass); |
4518 NodeList<ClassMember> members = node.members; | 4394 NodeList<ClassMember> members = node.members; |
4519 int length = members.length; | 4395 int length = members.length; |
4520 for (int i = 0; i < length; i++) { | 4396 for (int i = 0; i < length; i++) { |
4521 ClassMember member = members[i]; | 4397 ClassMember member = members[i]; |
4522 if (member is FieldDeclaration) { | 4398 if (member is FieldDeclaration) { |
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5449 assert(parent is PartOfDirective); | 5325 assert(parent is PartOfDirective); |
5450 } else { | 5326 } else { |
5451 elementAnnotationImpl.annotationAst = | 5327 elementAnnotationImpl.annotationAst = |
5452 new ConstantAstCloner().cloneNode(node); | 5328 new ConstantAstCloner().cloneNode(node); |
5453 } | 5329 } |
5454 return null; | 5330 return null; |
5455 } | 5331 } |
5456 | 5332 |
5457 @override | 5333 @override |
5458 Object visitArgumentList(ArgumentList node) { | 5334 Object visitArgumentList(ArgumentList node) { |
5459 DartType callerType = InferenceContext.getType(node); | 5335 DartType callerType = InferenceContext.getContext(node); |
5460 if (callerType is FunctionType) { | 5336 if (callerType is FunctionType) { |
5461 Map<String, DartType> namedParameterTypes = | 5337 Map<String, DartType> namedParameterTypes = |
5462 callerType.namedParameterTypes; | 5338 callerType.namedParameterTypes; |
5463 List<DartType> normalParameterTypes = callerType.normalParameterTypes; | 5339 List<DartType> normalParameterTypes = callerType.normalParameterTypes; |
5464 List<DartType> optionalParameterTypes = callerType.optionalParameterTypes; | 5340 List<DartType> optionalParameterTypes = callerType.optionalParameterTypes; |
5465 int normalCount = normalParameterTypes.length; | 5341 int normalCount = normalParameterTypes.length; |
5466 int optionalCount = optionalParameterTypes.length; | 5342 int optionalCount = optionalParameterTypes.length; |
5467 | 5343 |
5468 NodeList<Expression> arguments = node.arguments; | 5344 NodeList<Expression> arguments = node.arguments; |
5469 Iterable<Expression> positional = | 5345 Iterable<Expression> positional = |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6062 | 5938 |
6063 @override | 5939 @override |
6064 Object visitFunctionExpression(FunctionExpression node) { | 5940 Object visitFunctionExpression(FunctionExpression node) { |
6065 ExecutableElement outerFunction = _enclosingFunction; | 5941 ExecutableElement outerFunction = _enclosingFunction; |
6066 FunctionBody outerFunctionBody = _currentFunctionBody; | 5942 FunctionBody outerFunctionBody = _currentFunctionBody; |
6067 try { | 5943 try { |
6068 _currentFunctionBody = node.body; | 5944 _currentFunctionBody = node.body; |
6069 _enclosingFunction = node.element; | 5945 _enclosingFunction = node.element; |
6070 _overrideManager.enterScope(); | 5946 _overrideManager.enterScope(); |
6071 try { | 5947 try { |
6072 DartType functionType = InferenceContext.getType(node); | 5948 DartType functionType = inferenceContext.getType(node); |
6073 if (functionType is FunctionType) { | 5949 if (functionType is FunctionType) { |
6074 functionType = | 5950 functionType = |
6075 matchFunctionTypeParameters(node.typeParameters, functionType); | 5951 matchFunctionTypeParameters(node.typeParameters, functionType); |
6076 if (functionType is FunctionType) { | 5952 if (functionType is FunctionType) { |
6077 _inferFormalParameterList(node.parameters, functionType); | 5953 _inferFormalParameterList(node.parameters, functionType); |
6078 DartType returnType; | 5954 DartType returnType; |
6079 ParameterElement parameterElement = | 5955 ParameterElement parameterElement = |
6080 resolutionMap.staticParameterElementForExpression(node); | 5956 resolutionMap.staticParameterElementForExpression(node); |
6081 if (isFutureThen(parameterElement?.enclosingElement)) { | 5957 if (isFutureThen(parameterElement?.enclosingElement)) { |
6082 var futureThenType = | 5958 var futureThenType = |
(...skipping 23 matching lines...) Expand all Loading... | |
6106 _currentFunctionBody = outerFunctionBody; | 5982 _currentFunctionBody = outerFunctionBody; |
6107 _enclosingFunction = outerFunction; | 5983 _enclosingFunction = outerFunction; |
6108 } | 5984 } |
6109 return null; | 5985 return null; |
6110 } | 5986 } |
6111 | 5987 |
6112 @override | 5988 @override |
6113 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 5989 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
6114 node.function?.accept(this); | 5990 node.function?.accept(this); |
6115 node.accept(elementResolver); | 5991 node.accept(elementResolver); |
6116 _inferArgumentTypesFromContext(node); | 5992 _inferArgumentTypesForInvocation(node); |
6117 node.argumentList?.accept(this); | 5993 node.argumentList?.accept(this); |
6118 node.accept(typeAnalyzer); | 5994 node.accept(typeAnalyzer); |
6119 return null; | 5995 return null; |
6120 } | 5996 } |
6121 | 5997 |
6122 @override | 5998 @override |
6123 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 5999 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
6124 // Resolve the metadata in the library scope. | 6000 // Resolve the metadata in the library scope. |
6125 if (node.metadata != null) { | 6001 if (node.metadata != null) { |
6126 node.metadata.accept(this); | 6002 node.metadata.accept(this); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6204 <Map<VariableElement, DartType>>[]; | 6080 <Map<VariableElement, DartType>>[]; |
6205 perBranchOverrides.add(thenOverrides); | 6081 perBranchOverrides.add(thenOverrides); |
6206 perBranchOverrides.add(elseOverrides); | 6082 perBranchOverrides.add(elseOverrides); |
6207 _overrideManager.mergeOverrides(perBranchOverrides); | 6083 _overrideManager.mergeOverrides(perBranchOverrides); |
6208 } | 6084 } |
6209 return null; | 6085 return null; |
6210 } | 6086 } |
6211 | 6087 |
6212 @override | 6088 @override |
6213 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 6089 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); | 6090 node.constructorName?.accept(this); |
6258 FunctionType constructorType = resolutionMap | 6091 _inferArgumentTypesForInstanceCreate(node); |
6259 .staticElementForConstructorReference(node.constructorName) | |
6260 ?.type; | |
6261 if (constructorType != null) { | |
6262 InferenceContext.setType(node.argumentList, constructorType); | |
6263 } | |
6264 node.argumentList?.accept(this); | 6092 node.argumentList?.accept(this); |
6265 node.accept(elementResolver); | 6093 node.accept(elementResolver); |
6266 node.accept(typeAnalyzer); | 6094 node.accept(typeAnalyzer); |
6267 return null; | 6095 return null; |
6268 } | 6096 } |
6269 | 6097 |
6270 @override | 6098 @override |
6271 Object visitLabel(Label node) => null; | 6099 Object visitLabel(Label node) => null; |
6272 | 6100 |
6273 @override | 6101 @override |
6274 Object visitLibraryIdentifier(LibraryIdentifier node) => null; | 6102 Object visitLibraryIdentifier(LibraryIdentifier node) => null; |
6275 | 6103 |
6276 @override | 6104 @override |
6277 Object visitListLiteral(ListLiteral node) { | 6105 Object visitListLiteral(ListLiteral node) { |
6278 DartType contextType = InferenceContext.getType(node); | 6106 InterfaceType listT; |
6279 List<DartType> targs = null; | 6107 |
6280 if (node.typeArguments != null) { | 6108 if (node.typeArguments != null) { |
6281 targs = node.typeArguments.arguments.map((t) => t.type).toList(); | 6109 var targs = node.typeArguments.arguments.map((t) => t.type).toList(); |
6282 } else if (contextType is InterfaceType) { | 6110 if (targs.length == 1 && !targs[0].isDynamic) { |
6283 InterfaceType listD = | 6111 listT = typeProvider.listType.instantiate([targs[0]]); |
6284 typeProvider.listType.instantiate([typeProvider.dynamicType]); | 6112 } |
6285 targs = inferenceContext.matchTypes(listD, contextType); | 6113 } else if (strongMode) { |
6114 listT = typeAnalyzer.inferListType(node, downwards: true); | |
6286 } | 6115 } |
6287 if (targs != null && targs.length == 1 && !targs[0].isDynamic) { | 6116 if (listT != null) { |
6288 DartType eType = targs[0]; | 6117 DartType eType = listT.typeArguments[0]; |
6289 InterfaceType listT = typeProvider.listType.instantiate([eType]); | |
6290 for (Expression child in node.elements) { | 6118 for (Expression child in node.elements) { |
6291 InferenceContext.setType(child, eType); | 6119 InferenceContext.setType(child, eType); |
6292 } | 6120 } |
6293 InferenceContext.setType(node, listT); | 6121 InferenceContext.setType(node, listT); |
6294 } else { | 6122 } else { |
6295 InferenceContext.clearType(node); | 6123 InferenceContext.clearType(node); |
6296 } | 6124 } |
6297 super.visitListLiteral(node); | 6125 super.visitListLiteral(node); |
6298 return null; | 6126 return null; |
6299 } | 6127 } |
6300 | 6128 |
6301 @override | 6129 @override |
6302 Object visitMapLiteral(MapLiteral node) { | 6130 Object visitMapLiteral(MapLiteral node) { |
6303 DartType contextType = InferenceContext.getType(node); | 6131 InterfaceType mapT; |
6304 List<DartType> targs = null; | |
6305 if (node.typeArguments != null) { | 6132 if (node.typeArguments != null) { |
6306 targs = node.typeArguments.arguments.map((t) => t.type).toList(); | 6133 var targs = node.typeArguments.arguments.map((t) => t.type).toList(); |
6307 } else if (contextType is InterfaceType) { | 6134 if (targs.length == 2 && targs.any((t) => !t.isDynamic)) { |
6308 InterfaceType mapD = typeProvider.mapType | 6135 mapT = typeProvider.mapType.instantiate([targs[0], targs[1]]); |
6309 .instantiate([typeProvider.dynamicType, typeProvider.dynamicType]); | 6136 } |
6310 targs = inferenceContext.matchTypes(mapD, contextType); | 6137 } else if (strongMode) { |
6138 mapT = typeAnalyzer.inferMapType(node, downwards: true); | |
6311 } | 6139 } |
6312 if (targs != null && targs.length == 2 && targs.any((t) => !t.isDynamic)) { | 6140 if (mapT != null) { |
6313 DartType kType = targs[0]; | 6141 DartType kType = mapT.typeArguments[0]; |
6314 DartType vType = targs[1]; | 6142 DartType vType = mapT.typeArguments[1]; |
6315 InterfaceType mapT = typeProvider.mapType.instantiate([kType, vType]); | |
6316 for (MapLiteralEntry entry in node.entries) { | 6143 for (MapLiteralEntry entry in node.entries) { |
6317 InferenceContext.setType(entry.key, kType); | 6144 InferenceContext.setType(entry.key, kType); |
6318 InferenceContext.setType(entry.value, vType); | 6145 InferenceContext.setType(entry.value, vType); |
6319 } | 6146 } |
6320 InferenceContext.setType(node, mapT); | 6147 InferenceContext.setType(node, mapT); |
6321 } else { | 6148 } else { |
6322 InferenceContext.clearType(node); | 6149 InferenceContext.clearType(node); |
6323 } | 6150 } |
6324 super.visitMapLiteral(node); | 6151 super.visitMapLiteral(node); |
6325 return null; | 6152 return null; |
(...skipping 25 matching lines...) Expand all Loading... | |
6351 | 6178 |
6352 @override | 6179 @override |
6353 Object visitMethodInvocation(MethodInvocation node) { | 6180 Object visitMethodInvocation(MethodInvocation node) { |
6354 // | 6181 // |
6355 // We visit the target and argument list, but do not visit the method name | 6182 // 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. | 6183 // because it needs to be visited in the context of the invocation. |
6357 // | 6184 // |
6358 node.target?.accept(this); | 6185 node.target?.accept(this); |
6359 node.typeArguments?.accept(this); | 6186 node.typeArguments?.accept(this); |
6360 node.accept(elementResolver); | 6187 node.accept(elementResolver); |
6361 _inferArgumentTypesFromContext(node); | 6188 _inferArgumentTypesForInvocation(node); |
6362 node.argumentList?.accept(this); | 6189 node.argumentList?.accept(this); |
6363 node.accept(typeAnalyzer); | 6190 node.accept(typeAnalyzer); |
6364 return null; | 6191 return null; |
6365 } | 6192 } |
6366 | 6193 |
6367 @override | 6194 @override |
6368 Object visitNamedExpression(NamedExpression node) { | 6195 Object visitNamedExpression(NamedExpression node) { |
6369 InferenceContext.setTypeFromNode(node.expression, node); | 6196 InferenceContext.setTypeFromNode(node.expression, node); |
6370 return super.visitNamedExpression(node); | 6197 return super.visitNamedExpression(node); |
6371 } | 6198 } |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6644 | 6471 |
6645 // Ordinary functions just return their declared types. | 6472 // Ordinary functions just return their declared types. |
6646 if (!isGenerator && !isAsynchronous) { | 6473 if (!isGenerator && !isAsynchronous) { |
6647 return declaredType; | 6474 return declaredType; |
6648 } | 6475 } |
6649 if (declaredType is InterfaceType) { | 6476 if (declaredType is InterfaceType) { |
6650 if (isGenerator) { | 6477 if (isGenerator) { |
6651 // If it's sync* we expect Iterable<T> | 6478 // If it's sync* we expect Iterable<T> |
6652 // If it's async* we expect Stream<T> | 6479 // If it's async* we expect Stream<T> |
6653 InterfaceType rawType = isAsynchronous | 6480 InterfaceType rawType = isAsynchronous |
6654 ? typeProvider.streamDynamicType | 6481 ? typeProvider.streamType |
6655 : typeProvider.iterableDynamicType; | 6482 : typeProvider.iterableType; |
6656 // Match the types to instantiate the type arguments if possible | 6483 // Match the types to instantiate the type arguments if possible |
6657 List<DartType> typeArgs = | 6484 List<DartType> targs = declaredType.typeArguments; |
6658 inferenceContext.matchTypes(rawType, declaredType); | 6485 if (targs.length == 1 && rawType.instantiate(targs) == declaredType) { |
6659 return (typeArgs?.length == 1) ? typeArgs[0] : null; | 6486 return targs[0]; |
6487 } | |
6660 } | 6488 } |
6661 // async functions expect `Future<T> | T` | 6489 // async functions expect `Future<T> | T` |
6662 var futureTypeParam = declaredType.flattenFutures(typeSystem); | 6490 var futureTypeParam = declaredType.flattenFutures(typeSystem); |
6663 return _createFutureOr(futureTypeParam); | 6491 return _createFutureOr(futureTypeParam); |
6664 } | 6492 } |
6665 return declaredType; | 6493 return declaredType; |
6666 } | 6494 } |
6667 | 6495 |
6668 /** | 6496 /** |
6669 * Creates a union of `T | Future<T>`, unless `T` is already a | 6497 * 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) { | 6576 if (executable is MethodElement) { |
6749 return true; | 6577 return true; |
6750 } | 6578 } |
6751 if (executable is FunctionElement) { | 6579 if (executable is FunctionElement) { |
6752 return executable.enclosingElement is CompilationUnitElement; | 6580 return executable.enclosingElement is CompilationUnitElement; |
6753 } | 6581 } |
6754 } | 6582 } |
6755 return false; | 6583 return false; |
6756 } | 6584 } |
6757 | 6585 |
6758 void _inferArgumentTypesFromContext(InvocationExpression node) { | 6586 FunctionType _inferArgumentTypesForGeneric(AstNode inferenceNode, |
6587 DartType uninstantiatedType, TypeArgumentList typeArguments, | |
6588 {AstNode errorNode}) { | |
6589 errorNode ??= inferenceNode; | |
6590 TypeSystem ts = typeSystem; | |
6591 if (typeArguments == null && | |
6592 uninstantiatedType is FunctionType && | |
6593 uninstantiatedType.typeFormals.isNotEmpty && | |
6594 ts is StrongTypeSystemImpl) { | |
6595 return ts.inferGenericFunctionOrType/*<FunctionType>*/( | |
6596 uninstantiatedType, | |
6597 ParameterElement.EMPTY_LIST, | |
6598 DartType.EMPTY_LIST, | |
6599 InferenceContext.getContext(inferenceNode), | |
6600 downwards: true, | |
6601 errorReporter: errorReporter, | |
6602 errorNode: errorNode); | |
6603 } | |
6604 return null; | |
6605 } | |
6606 | |
6607 void _inferArgumentTypesForInstanceCreate(InstanceCreationExpression node) { | |
6608 ConstructorName constructor = node.constructorName; | |
6609 TypeName classTypeName = constructor?.type; | |
6610 if (classTypeName == null || !strongMode) { | |
6611 return; | |
6612 } | |
6613 | |
6614 ConstructorElement originalElement = | |
6615 resolutionMap.staticElementForConstructorReference(constructor); | |
6616 FunctionType inferred; | |
6617 // If the constructor is generic, we'll have a ConstructorMember that | |
6618 // substitutes in type arguments (possibly `dynamic`) from earlier in | |
6619 // resolution. | |
6620 // | |
6621 // Otherwise we'll have a ConstructorElement, and we can skip inference | |
6622 // because there's nothing to infer in a non-generic type. | |
6623 if (classTypeName.typeArguments == null && | |
6624 originalElement is ConstructorMember) { | |
6625 // TODO(leafp): Currently, we may re-infer types here, since we | |
6626 // sometimes resolve multiple times. We should really check that we | |
6627 // have not already inferred something. However, the obvious ways to | |
6628 // check this don't work, since we may have been instantiated | |
6629 // to bounds in an earlier phase, and we *do* want to do inference | |
6630 // in that case. | |
6631 | |
6632 // Get back to the uninstantiated generic constructor. | |
6633 // TODO(jmesserly): should we store this earlier in resolution? | |
6634 // Or look it up, instead of jumping backwards through the Member? | |
6635 var rawElement = originalElement.baseElement; | |
6636 | |
6637 FunctionType constructorType = | |
6638 StaticTypeAnalyzer.constructorToGenericFunctionType(rawElement); | |
6639 | |
6640 inferred = _inferArgumentTypesForGeneric( | |
6641 node, constructorType, constructor.type.typeArguments, | |
6642 errorNode: node.constructorName); | |
6643 | |
6644 if (inferred != null) { | |
6645 ArgumentList arguments = node.argumentList; | |
6646 InferenceContext.setType(arguments, inferred); | |
6647 // Fix up the parameter elements based on inferred method. | |
6648 arguments.correspondingStaticParameters = | |
6649 resolveArgumentsToParameters(arguments, inferred.parameters, null); | |
6650 | |
6651 constructor.type.type = inferred.returnType; | |
6652 if (UnknownInferredType.isKnown(inferred)) { | |
6653 inferenceContext.recordInference(node, inferred.returnType); | |
6654 } | |
6655 | |
6656 // Update the static element as well. This is used in some cases, such | |
6657 // as computing constant values. It is stored in two places. | |
6658 constructor.staticElement = | |
6659 ConstructorMember.from(rawElement, inferred.returnType); | |
6660 node.staticElement = constructor.staticElement; | |
6661 } | |
6662 } | |
6663 | |
6664 if (inferred == null) { | |
6665 InferenceContext.setType(node.argumentList, originalElement?.type); | |
6666 } | |
6667 } | |
6668 | |
6669 void _inferArgumentTypesForInvocation(InvocationExpression node) { | |
6759 if (!strongMode) { | 6670 if (!strongMode) { |
6760 // Use propagated type inference for lambdas if not in strong mode. | 6671 // Use propagated type inference for lambdas if not in strong mode. |
6761 _inferFunctionExpressionsParametersTypes(node.argumentList); | 6672 _inferFunctionExpressionsParametersTypes(node.argumentList); |
6762 return; | 6673 return; |
6763 } | 6674 } |
6764 | 6675 DartType inferred = _inferArgumentTypesForGeneric( |
6765 DartType contextType = node.staticInvokeType; | 6676 node, node.function.staticType, node.typeArguments); |
6766 if (contextType is FunctionType) { | 6677 InferenceContext.setType( |
6767 DartType originalType = node.function.staticType; | 6678 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 } | 6679 } |
6786 | 6680 |
6787 void _inferFormalParameterList(FormalParameterList node, DartType type) { | 6681 void _inferFormalParameterList(FormalParameterList node, DartType type) { |
6788 if (typeAnalyzer.inferFormalParameterList(node, type)) { | 6682 if (typeAnalyzer.inferFormalParameterList(node, type)) { |
6789 // TODO(leafp): This gets dropped on the floor if we're in the field | 6683 // TODO(leafp): This gets dropped on the floor if we're in the field |
6790 // inference task. We should probably keep these infos. | 6684 // inference task. We should probably keep these infos. |
6791 // | 6685 // |
6792 // TODO(jmesserly): this is reporting the context type, and therefore not | 6686 // TODO(jmesserly): this is reporting the context type, and therefore not |
6793 // necessarily the correct inferred type for the lambda. | 6687 // necessarily the correct inferred type for the lambda. |
6794 // | 6688 // |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7356 return null; | 7250 return null; |
7357 } | 7251 } |
7358 | 7252 |
7359 @override | 7253 @override |
7360 Object visitClassDeclaration(ClassDeclaration node) { | 7254 Object visitClassDeclaration(ClassDeclaration node) { |
7361 ClassElement classElement = node.element; | 7255 ClassElement classElement = node.element; |
7362 Scope outerScope = nameScope; | 7256 Scope outerScope = nameScope; |
7363 try { | 7257 try { |
7364 if (classElement == null) { | 7258 if (classElement == null) { |
7365 AnalysisEngine.instance.logger.logInformation( | 7259 AnalysisEngine.instance.logger.logInformation( |
7366 "Missing element for class declaration ${node.name.name} in ${defini ngLibrary.source.fullName}", | 7260 "Missing element for class declaration ${node.name |
7261 .name} in ${definingLibrary.source.fullName}", | |
7367 new CaughtException(new AnalysisException(), null)); | 7262 new CaughtException(new AnalysisException(), null)); |
7368 super.visitClassDeclaration(node); | 7263 super.visitClassDeclaration(node); |
7369 } else { | 7264 } else { |
7370 ClassElement outerClass = enclosingClass; | 7265 ClassElement outerClass = enclosingClass; |
7371 try { | 7266 try { |
7372 enclosingClass = node.element; | 7267 enclosingClass = node.element; |
7373 nameScope = new TypeParameterScope(nameScope, classElement); | 7268 nameScope = new TypeParameterScope(nameScope, classElement); |
7374 visitClassDeclarationInScope(node); | 7269 visitClassDeclarationInScope(node); |
7375 nameScope = new ClassScope(nameScope, classElement); | 7270 nameScope = new ClassScope(nameScope, classElement); |
7376 visitClassMembersInScope(node); | 7271 visitClassMembersInScope(node); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7484 return null; | 7379 return null; |
7485 } | 7380 } |
7486 | 7381 |
7487 @override | 7382 @override |
7488 Object visitEnumDeclaration(EnumDeclaration node) { | 7383 Object visitEnumDeclaration(EnumDeclaration node) { |
7489 ClassElement classElement = node.element; | 7384 ClassElement classElement = node.element; |
7490 Scope outerScope = nameScope; | 7385 Scope outerScope = nameScope; |
7491 try { | 7386 try { |
7492 if (classElement == null) { | 7387 if (classElement == null) { |
7493 AnalysisEngine.instance.logger.logInformation( | 7388 AnalysisEngine.instance.logger.logInformation( |
7494 "Missing element for enum declaration ${node.name.name} in ${definin gLibrary.source.fullName}", | 7389 "Missing element for enum declaration ${node.name |
7390 .name} in ${definingLibrary.source.fullName}", | |
7495 new CaughtException(new AnalysisException(), null)); | 7391 new CaughtException(new AnalysisException(), null)); |
7496 super.visitEnumDeclaration(node); | 7392 super.visitEnumDeclaration(node); |
7497 } else { | 7393 } else { |
7498 ClassElement outerClass = enclosingClass; | 7394 ClassElement outerClass = enclosingClass; |
7499 try { | 7395 try { |
7500 enclosingClass = node.element; | 7396 enclosingClass = node.element; |
7501 nameScope = new ClassScope(nameScope, classElement); | 7397 nameScope = new ClassScope(nameScope, classElement); |
7502 visitEnumMembersInScope(node); | 7398 visitEnumMembersInScope(node); |
7503 } finally { | 7399 } finally { |
7504 enclosingClass = outerClass; | 7400 enclosingClass = outerClass; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7600 Object visitFunctionDeclaration(FunctionDeclaration node) { | 7496 Object visitFunctionDeclaration(FunctionDeclaration node) { |
7601 ExecutableElement functionElement = node.element; | 7497 ExecutableElement functionElement = node.element; |
7602 if (functionElement != null && | 7498 if (functionElement != null && |
7603 functionElement.enclosingElement is! CompilationUnitElement) { | 7499 functionElement.enclosingElement is! CompilationUnitElement) { |
7604 nameScope.define(functionElement); | 7500 nameScope.define(functionElement); |
7605 } | 7501 } |
7606 Scope outerScope = nameScope; | 7502 Scope outerScope = nameScope; |
7607 try { | 7503 try { |
7608 if (functionElement == null) { | 7504 if (functionElement == null) { |
7609 AnalysisEngine.instance.logger.logInformation( | 7505 AnalysisEngine.instance.logger.logInformation( |
7610 "Missing element for top-level function ${node.name.name} in ${defin ingLibrary.source.fullName}", | 7506 "Missing element for top-level function ${node.name |
7507 .name} in ${definingLibrary.source.fullName}", | |
7611 new CaughtException(new AnalysisException(), null)); | 7508 new CaughtException(new AnalysisException(), null)); |
7612 } else { | 7509 } else { |
7613 nameScope = new FunctionScope(nameScope, functionElement); | 7510 nameScope = new FunctionScope(nameScope, functionElement); |
7614 } | 7511 } |
7615 visitFunctionDeclarationInScope(node); | 7512 visitFunctionDeclarationInScope(node); |
7616 } finally { | 7513 } finally { |
7617 nameScope = outerScope; | 7514 nameScope = outerScope; |
7618 } | 7515 } |
7619 return null; | 7516 return null; |
7620 } | 7517 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7676 super.visitFunctionTypeAlias(node); | 7573 super.visitFunctionTypeAlias(node); |
7677 } | 7574 } |
7678 | 7575 |
7679 @override | 7576 @override |
7680 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 7577 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
7681 Scope outerScope = nameScope; | 7578 Scope outerScope = nameScope; |
7682 try { | 7579 try { |
7683 ParameterElement parameterElement = node.element; | 7580 ParameterElement parameterElement = node.element; |
7684 if (parameterElement == null) { | 7581 if (parameterElement == null) { |
7685 AnalysisEngine.instance.logger.logInformation( | 7582 AnalysisEngine.instance.logger.logInformation( |
7686 "Missing element for function typed formal parameter ${node.identifi er.name} in ${definingLibrary.source.fullName}", | 7583 "Missing element for function typed formal parameter ${node |
7584 .identifier.name} in ${definingLibrary.source.fullName}", | |
7687 new CaughtException(new AnalysisException(), null)); | 7585 new CaughtException(new AnalysisException(), null)); |
7688 } else { | 7586 } else { |
7689 nameScope = new EnclosedScope(nameScope); | 7587 nameScope = new EnclosedScope(nameScope); |
7690 List<TypeParameterElement> typeParameters = | 7588 List<TypeParameterElement> typeParameters = |
7691 parameterElement.typeParameters; | 7589 parameterElement.typeParameters; |
7692 int length = typeParameters.length; | 7590 int length = typeParameters.length; |
7693 for (int i = 0; i < length; i++) { | 7591 for (int i = 0; i < length; i++) { |
7694 nameScope.define(typeParameters[i]); | 7592 nameScope.define(typeParameters[i]); |
7695 } | 7593 } |
7696 } | 7594 } |
(...skipping 23 matching lines...) Expand all Loading... | |
7720 return null; | 7618 return null; |
7721 } | 7619 } |
7722 | 7620 |
7723 @override | 7621 @override |
7724 Object visitMethodDeclaration(MethodDeclaration node) { | 7622 Object visitMethodDeclaration(MethodDeclaration node) { |
7725 Scope outerScope = nameScope; | 7623 Scope outerScope = nameScope; |
7726 try { | 7624 try { |
7727 ExecutableElement methodElement = node.element; | 7625 ExecutableElement methodElement = node.element; |
7728 if (methodElement == null) { | 7626 if (methodElement == null) { |
7729 AnalysisEngine.instance.logger.logInformation( | 7627 AnalysisEngine.instance.logger.logInformation( |
7730 "Missing element for method ${node.name.name} in ${definingLibrary.s ource.fullName}", | 7628 "Missing element for method ${node.name.name} in ${definingLibrary |
7629 .source.fullName}", | |
7731 new CaughtException(new AnalysisException(), null)); | 7630 new CaughtException(new AnalysisException(), null)); |
7732 } else { | 7631 } else { |
7733 nameScope = new FunctionScope(nameScope, methodElement); | 7632 nameScope = new FunctionScope(nameScope, methodElement); |
7734 } | 7633 } |
7735 visitMethodDeclarationInScope(node); | 7634 visitMethodDeclarationInScope(node); |
7736 } finally { | 7635 } finally { |
7737 nameScope = outerScope; | 7636 nameScope = outerScope; |
7738 } | 7637 } |
7739 return null; | 7638 return null; |
7740 } | 7639 } |
(...skipping 3158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10899 return null; | 10798 return null; |
10900 } | 10799 } |
10901 if (identical(node.staticElement, variable)) { | 10800 if (identical(node.staticElement, variable)) { |
10902 if (node.inSetterContext()) { | 10801 if (node.inSetterContext()) { |
10903 result = true; | 10802 result = true; |
10904 } | 10803 } |
10905 } | 10804 } |
10906 return null; | 10805 return null; |
10907 } | 10806 } |
10908 } | 10807 } |
OLD | NEW |