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 [reportError] should be `true` if a compile-time error should be | |
Brian Wilkerson
2016/01/06 21:57:34
Perhaps "reportAsError"? As named my first impress
Jennifer Messerly
2016/01/06 22:25:51
Great idea. Done!
| |
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 reportError: 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 = (reportError | |
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 = (reportError | |
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 = (reportError | |
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 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13431 nonFields.add(node); | 13526 nonFields.add(node); |
13432 return null; | 13527 return null; |
13433 } | 13528 } |
13434 | 13529 |
13435 @override | 13530 @override |
13436 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 13531 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
13437 | 13532 |
13438 @override | 13533 @override |
13439 Object visitWithClause(WithClause node) => null; | 13534 Object visitWithClause(WithClause node) => null; |
13440 } | 13535 } |
OLD | NEW |