OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
(...skipping 9131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9142 @override | 9142 @override |
9143 Object visitMethodInvocation(MethodInvocation node) { | 9143 Object visitMethodInvocation(MethodInvocation node) { |
9144 // | 9144 // |
9145 // We visit the target and argument list, but do not visit the method name | 9145 // We visit the target and argument list, but do not visit the method name |
9146 // because it needs to be visited in the context of the invocation. | 9146 // because it needs to be visited in the context of the invocation. |
9147 // | 9147 // |
9148 safelyVisit(node.target); | 9148 safelyVisit(node.target); |
9149 safelyVisit(node.typeArguments); | 9149 safelyVisit(node.typeArguments); |
9150 node.accept(elementResolver); | 9150 node.accept(elementResolver); |
9151 _inferFunctionExpressionsParametersTypes(node.argumentList); | 9151 _inferFunctionExpressionsParametersTypes(node.argumentList); |
9152 Element methodElement = node.methodName.staticElement; | 9152 DartType contextType = node.staticInvokeType; |
9153 DartType contextType = null; | |
9154 if (methodElement is PropertyAccessorElement && methodElement.isGetter) { | |
9155 contextType = methodElement.returnType; | |
9156 } else if (methodElement is VariableElement) { | |
9157 contextType = methodElement.type; | |
9158 } else if (methodElement is ExecutableElement) { | |
9159 contextType = methodElement.type; | |
9160 } | |
9161 if (contextType is FunctionType) { | 9153 if (contextType is FunctionType) { |
9162 InferenceContext.setType(node.argumentList, contextType); | 9154 InferenceContext.setType(node.argumentList, contextType); |
9163 } | 9155 } |
9164 safelyVisit(node.argumentList); | 9156 safelyVisit(node.argumentList); |
9165 node.accept(typeAnalyzer); | 9157 node.accept(typeAnalyzer); |
9166 return null; | 9158 return null; |
9167 } | 9159 } |
9168 | 9160 |
| 9161 /** |
| 9162 * Given an [argumentList] and the [parameters] related to the element that |
| 9163 * will be invoked using those arguments, compute the list of parameters that |
| 9164 * correspond to the list of arguments. |
| 9165 * |
| 9166 * An error will be reported to [onError] if any of the arguments cannot be |
| 9167 * matched to a parameter. onError can be null to ignore the error. |
| 9168 * |
| 9169 * The flag [reportAsError] should be `true` if a compile-time error should be |
| 9170 * reported; or `false` if a compile-time warning should be reported |
| 9171 * |
| 9172 * Returns the parameters that correspond to the arguments. |
| 9173 */ |
| 9174 static List<ParameterElement> resolveArgumentsToParameters( |
| 9175 ArgumentList argumentList, |
| 9176 List<ParameterElement> parameters, |
| 9177 void onError(ErrorCode errorCode, AstNode node, [List<Object> arguments]), |
| 9178 {bool reportAsError: false}) { |
| 9179 List<ParameterElement> requiredParameters = new List<ParameterElement>(); |
| 9180 List<ParameterElement> positionalParameters = new List<ParameterElement>(); |
| 9181 HashMap<String, ParameterElement> namedParameters = |
| 9182 new HashMap<String, ParameterElement>(); |
| 9183 for (ParameterElement parameter in parameters) { |
| 9184 ParameterKind kind = parameter.parameterKind; |
| 9185 if (kind == ParameterKind.REQUIRED) { |
| 9186 requiredParameters.add(parameter); |
| 9187 } else if (kind == ParameterKind.POSITIONAL) { |
| 9188 positionalParameters.add(parameter); |
| 9189 } else { |
| 9190 namedParameters[parameter.name] = parameter; |
| 9191 } |
| 9192 } |
| 9193 List<ParameterElement> unnamedParameters = |
| 9194 new List<ParameterElement>.from(requiredParameters); |
| 9195 unnamedParameters.addAll(positionalParameters); |
| 9196 int unnamedParameterCount = unnamedParameters.length; |
| 9197 int unnamedIndex = 0; |
| 9198 NodeList<Expression> arguments = argumentList.arguments; |
| 9199 int argumentCount = arguments.length; |
| 9200 List<ParameterElement> resolvedParameters = |
| 9201 new List<ParameterElement>(argumentCount); |
| 9202 int positionalArgumentCount = 0; |
| 9203 HashSet<String> usedNames = new HashSet<String>(); |
| 9204 bool noBlankArguments = true; |
| 9205 for (int i = 0; i < argumentCount; i++) { |
| 9206 Expression argument = arguments[i]; |
| 9207 if (argument is NamedExpression) { |
| 9208 SimpleIdentifier nameNode = argument.name.label; |
| 9209 String name = nameNode.name; |
| 9210 ParameterElement element = namedParameters[name]; |
| 9211 if (element == null) { |
| 9212 ErrorCode errorCode = (reportAsError |
| 9213 ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER |
| 9214 : StaticWarningCode.UNDEFINED_NAMED_PARAMETER); |
| 9215 if (onError != null) { |
| 9216 onError(errorCode, nameNode, [name]); |
| 9217 } |
| 9218 } else { |
| 9219 resolvedParameters[i] = element; |
| 9220 nameNode.staticElement = element; |
| 9221 } |
| 9222 if (!usedNames.add(name)) { |
| 9223 if (onError != null) { |
| 9224 onError(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, |
| 9225 [name]); |
| 9226 } |
| 9227 } |
| 9228 } else { |
| 9229 if (argument is SimpleIdentifier && argument.name.isEmpty) { |
| 9230 noBlankArguments = false; |
| 9231 } |
| 9232 positionalArgumentCount++; |
| 9233 if (unnamedIndex < unnamedParameterCount) { |
| 9234 resolvedParameters[i] = unnamedParameters[unnamedIndex++]; |
| 9235 } |
| 9236 } |
| 9237 } |
| 9238 if (positionalArgumentCount < requiredParameters.length && |
| 9239 noBlankArguments) { |
| 9240 ErrorCode errorCode = (reportAsError |
| 9241 ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS |
| 9242 : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS); |
| 9243 if (onError != null) { |
| 9244 onError(errorCode, argumentList, |
| 9245 [requiredParameters.length, positionalArgumentCount]); |
| 9246 } |
| 9247 } else if (positionalArgumentCount > unnamedParameterCount && |
| 9248 noBlankArguments) { |
| 9249 ErrorCode errorCode = (reportAsError |
| 9250 ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS |
| 9251 : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS); |
| 9252 if (onError != null) { |
| 9253 onError(errorCode, argumentList, |
| 9254 [unnamedParameterCount, positionalArgumentCount]); |
| 9255 } |
| 9256 } |
| 9257 return resolvedParameters; |
| 9258 } |
| 9259 |
9169 @override | 9260 @override |
9170 Object visitNamedExpression(NamedExpression node) { | 9261 Object visitNamedExpression(NamedExpression node) { |
9171 InferenceContext.setType(node.expression, InferenceContext.getType(node)); | 9262 InferenceContext.setType(node.expression, InferenceContext.getType(node)); |
9172 return super.visitNamedExpression(node); | 9263 return super.visitNamedExpression(node); |
9173 } | 9264 } |
9174 | 9265 |
9175 @override | 9266 @override |
9176 Object visitNode(AstNode node) { | 9267 Object visitNode(AstNode node) { |
9177 node.visitChildren(this); | 9268 node.visitChildren(this); |
9178 node.accept(elementResolver); | 9269 node.accept(elementResolver); |
(...skipping 3370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12549 /** | 12640 /** |
12550 * Return the type arguments associated with the given type. | 12641 * Return the type arguments associated with the given type. |
12551 * | 12642 * |
12552 * @param type the type whole type arguments are to be returned | 12643 * @param type the type whole type arguments are to be returned |
12553 * @return the type arguments associated with the given type | 12644 * @return the type arguments associated with the given type |
12554 */ | 12645 */ |
12555 List<DartType> _getTypeParameters(DartType type) { | 12646 List<DartType> _getTypeParameters(DartType type) { |
12556 if (type is InterfaceType) { | 12647 if (type is InterfaceType) { |
12557 return type.typeArguments; | 12648 return type.typeArguments; |
12558 } else if (type is FunctionType) { | 12649 } else if (type is FunctionType) { |
12559 return TypeParameterTypeImpl.getTypes(type.boundTypeParameters); | 12650 return TypeParameterTypeImpl.getTypes(type.typeFormals); |
12560 } | 12651 } |
12561 return DartType.EMPTY_LIST; | 12652 return DartType.EMPTY_LIST; |
12562 } | 12653 } |
12563 | 12654 |
12564 /** | 12655 /** |
12565 * Returns the simple identifier of the given (may be qualified) type name. | 12656 * Returns the simple identifier of the given (may be qualified) type name. |
12566 * | 12657 * |
12567 * @param typeName the (may be qualified) qualified type name | 12658 * @param typeName the (may be qualified) qualified type name |
12568 * @return the simple identifier of the given (may be qualified) type name. | 12659 * @return the simple identifier of the given (may be qualified) type name. |
12569 */ | 12660 */ |
(...skipping 19 matching lines...) Expand all Loading... |
12589 if (type != null) { | 12680 if (type != null) { |
12590 return null; | 12681 return null; |
12591 } | 12682 } |
12592 type = element.type; | 12683 type = element.type; |
12593 } | 12684 } |
12594 } | 12685 } |
12595 return type; | 12686 return type; |
12596 } | 12687 } |
12597 | 12688 |
12598 DartType _instantiateType(DartType type, List<DartType> typeArguments) { | 12689 DartType _instantiateType(DartType type, List<DartType> typeArguments) { |
| 12690 // TODO(jmesserly): this should use TypeSystem.instantiateToBounds, |
| 12691 // from calling methods when they know they're just trying to fill in |
| 12692 // "dynamic" for the case of missing type arguments. |
| 12693 |
12599 if (type is InterfaceTypeImpl) { | 12694 if (type is InterfaceTypeImpl) { |
12600 return type.substitute4(typeArguments); | 12695 return type.substitute4(typeArguments); |
12601 } else if (type is FunctionTypeImpl) { | 12696 } else if (type is FunctionTypeImpl) { |
12602 return type.instantiate(typeArguments); | 12697 return type.instantiate(typeArguments); |
12603 } else { | 12698 } else { |
12604 // TODO(brianwilkerson) Report this internal error. | 12699 // TODO(brianwilkerson) Report this internal error. |
12605 return type; | 12700 return type; |
12606 } | 12701 } |
12607 } | 12702 } |
12608 | 12703 |
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13433 nonFields.add(node); | 13528 nonFields.add(node); |
13434 return null; | 13529 return null; |
13435 } | 13530 } |
13436 | 13531 |
13437 @override | 13532 @override |
13438 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 13533 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
13439 | 13534 |
13440 @override | 13535 @override |
13441 Object visitWithClause(WithClause node) => null; | 13536 Object visitWithClause(WithClause node) => null; |
13442 } | 13537 } |
OLD | NEW |