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

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 2456803004: fixes #27586, prefer context type in generic inference (Closed)
Patch Set: fix Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/error/codes.dart ('k') | pkg/analyzer/lib/src/generated/static_type_analyzer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698