Decouple Call.hasUnresolvedArguments from ResolutionContext

This commit is contained in:
Svyatoslav Scherbina
2020-05-26 12:28:21 +03:00
parent eb338e2e91
commit 3e8b0055ab
2 changed files with 46 additions and 9 deletions
@@ -149,26 +149,51 @@ public class ArgumentTypeResolver {
public static boolean isFunctionLiteralArgument( public static boolean isFunctionLiteralArgument(
@NotNull KtExpression expression, @NotNull ResolutionContext context @NotNull KtExpression expression, @NotNull ResolutionContext context
) { ) {
return getFunctionLiteralArgumentIfAny(expression, context) != null; return isFunctionLiteralArgument(expression, context.statementFilter);
}
private static boolean isFunctionLiteralArgument(
@NotNull KtExpression expression, @NotNull StatementFilter statementFilter
) {
return getFunctionLiteralArgumentIfAny(expression, statementFilter) != null;
} }
public static boolean isCallableReferenceArgument( public static boolean isCallableReferenceArgument(
@NotNull KtExpression expression, @NotNull ResolutionContext context @NotNull KtExpression expression, @NotNull ResolutionContext context
) { ) {
return getCallableReferenceExpressionIfAny(expression, context) != null; return isCallableReferenceArgument(expression, context.statementFilter);
}
private static boolean isCallableReferenceArgument(
@NotNull KtExpression expression, @NotNull StatementFilter statementFilter
) {
return getCallableReferenceExpressionIfAny(expression, statementFilter) != null;
} }
public static boolean isFunctionLiteralOrCallableReference( public static boolean isFunctionLiteralOrCallableReference(
@NotNull KtExpression expression, @NotNull ResolutionContext context @NotNull KtExpression expression, @NotNull ResolutionContext context
) { ) {
return isFunctionLiteralArgument(expression, context) || isCallableReferenceArgument(expression, context); return isFunctionLiteralOrCallableReference(expression, context.statementFilter);
}
public static boolean isFunctionLiteralOrCallableReference(
@NotNull KtExpression expression, @NotNull StatementFilter statementFilter
) {
return isFunctionLiteralArgument(expression, statementFilter) || isCallableReferenceArgument(expression, statementFilter);
} }
@Nullable @Nullable
public static KtFunction getFunctionLiteralArgumentIfAny( public static KtFunction getFunctionLiteralArgumentIfAny(
@NotNull KtExpression expression, @NotNull ResolutionContext context @NotNull KtExpression expression, @NotNull ResolutionContext context
) { ) {
KtExpression deparenthesizedExpression = getLastElementDeparenthesized(expression, context.statementFilter); return getFunctionLiteralArgumentIfAny(expression, context.statementFilter);
}
@Nullable
public static KtFunction getFunctionLiteralArgumentIfAny(
@NotNull KtExpression expression, @NotNull StatementFilter statementFilter
) {
KtExpression deparenthesizedExpression = getLastElementDeparenthesized(expression, statementFilter);
if (deparenthesizedExpression instanceof KtLambdaExpression) { if (deparenthesizedExpression instanceof KtLambdaExpression) {
return ((KtLambdaExpression) deparenthesizedExpression).getFunctionLiteral(); return ((KtLambdaExpression) deparenthesizedExpression).getFunctionLiteral();
} }
@@ -183,7 +208,15 @@ public class ArgumentTypeResolver {
@NotNull KtExpression expression, @NotNull KtExpression expression,
@NotNull ResolutionContext context @NotNull ResolutionContext context
) { ) {
KtExpression deparenthesizedExpression = getLastElementDeparenthesized(expression, context.statementFilter); return getCallableReferenceExpressionIfAny(expression, context.statementFilter);
}
@Nullable
public static KtCallableReferenceExpression getCallableReferenceExpressionIfAny(
@NotNull KtExpression expression,
@NotNull StatementFilter statementFilter
) {
KtExpression deparenthesizedExpression = getLastElementDeparenthesized(expression, statementFilter);
if (deparenthesizedExpression instanceof KtCallableReferenceExpression) { if (deparenthesizedExpression instanceof KtCallableReferenceExpression) {
return (KtCallableReferenceExpression) deparenthesizedExpression; return (KtCallableReferenceExpression) deparenthesizedExpression;
} }
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.CALL import org.jetbrains.kotlin.resolve.BindingContext.CALL
import org.jetbrains.kotlin.resolve.BindingContext.RESOLVED_CALL import org.jetbrains.kotlin.resolve.BindingContext.RESOLVED_CALL
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.StatementFilter
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
@@ -79,17 +80,20 @@ fun <D : CallableDescriptor> ResolvedCall<D>.usesDefaultArguments(): Boolean {
// call // call
fun <C : ResolutionContext<C>> Call.hasUnresolvedArguments(context: ResolutionContext<C>): Boolean { fun <C : ResolutionContext<C>> Call.hasUnresolvedArguments(context: ResolutionContext<C>): Boolean =
hasUnresolvedArguments(context.trace.bindingContext, context.statementFilter)
fun Call.hasUnresolvedArguments(bindingContext: BindingContext, statementFilter: StatementFilter): Boolean {
val arguments = valueArguments.map { it.getArgumentExpression() } val arguments = valueArguments.map { it.getArgumentExpression() }
return arguments.any(fun(argument: KtExpression?): Boolean { return arguments.any(fun(argument: KtExpression?): Boolean {
if (argument == null || ArgumentTypeResolver.isFunctionLiteralOrCallableReference(argument, context)) return false if (argument == null || ArgumentTypeResolver.isFunctionLiteralOrCallableReference(argument, statementFilter)) return false
when (val resolvedCall = argument.getResolvedCall(context.trace.bindingContext)) { when (val resolvedCall = argument.getResolvedCall(bindingContext)) {
is MutableResolvedCall<*> -> if (!resolvedCall.hasInferredReturnType()) return false is MutableResolvedCall<*> -> if (!resolvedCall.hasInferredReturnType()) return false
is NewResolvedCallImpl<*> -> if (resolvedCall.resultingDescriptor.returnType?.isError == true) return false is NewResolvedCallImpl<*> -> if (resolvedCall.resultingDescriptor.returnType?.isError == true) return false
} }
val expressionType = context.trace.bindingContext.getType(argument) val expressionType = bindingContext.getType(argument)
return expressionType == null || expressionType.isError return expressionType == null || expressionType.isError
}) })
} }