Switch to use FakeCallResolver in DelegatedPropertyResolver
This commit is contained in:
Generated
+1
@@ -3,6 +3,7 @@
|
||||
<words>
|
||||
<w>ctor</w>
|
||||
<w>lookups</w>
|
||||
<w>unescape</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
|
||||
@@ -77,7 +77,8 @@ public class CheckerTestUtil {
|
||||
};
|
||||
|
||||
private static final String IGNORE_DIAGNOSTIC_PARAMETER = "IGNORE";
|
||||
private static final String DIAGNOSTIC_PARAMETER = "[^\\)\\(;]+";
|
||||
private static final String SHOULD_BE_ESCAPED = "\\)\\(;";
|
||||
private static final String DIAGNOSTIC_PARAMETER = "(?:(?:\\\\[" + SHOULD_BE_ESCAPED + "])|[^" + SHOULD_BE_ESCAPED + "])+";
|
||||
private static final String INDIVIDUAL_DIAGNOSTIC = "(\\w+)(\\(" + DIAGNOSTIC_PARAMETER + "(;\\s*" + DIAGNOSTIC_PARAMETER + ")*\\))?";
|
||||
private static final Pattern RANGE_START_OR_END_PATTERN = Pattern.compile("(<!"+
|
||||
INDIVIDUAL_DIAGNOSTIC +"(,\\s*"+
|
||||
@@ -613,10 +614,18 @@ public class CheckerTestUtil {
|
||||
List<String> parsedParameters = new SmartList<String>();
|
||||
Matcher parametersMatcher = INDIVIDUAL_PARAMETER_PATTERN.matcher(parameters);
|
||||
while (parametersMatcher.find())
|
||||
parsedParameters.add(parametersMatcher.group().trim());
|
||||
parsedParameters.add(unescape(parametersMatcher.group().trim()));
|
||||
return new TextDiagnostic(name, parsedParameters);
|
||||
}
|
||||
|
||||
private static @NotNull String escape(@NotNull String s) {
|
||||
return s.replaceAll("([" + SHOULD_BE_ESCAPED + "])", "\\\\$1");
|
||||
}
|
||||
|
||||
private static @NotNull String unescape(@NotNull String s) {
|
||||
return s.replaceAll("\\\\([" + SHOULD_BE_ESCAPED + "])", "$1");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TextDiagnostic asTextDiagnostic(@NotNull Diagnostic diagnostic) {
|
||||
DiagnosticRenderer renderer = DefaultErrorMessages.getRendererForDiagnostic(diagnostic);
|
||||
@@ -679,7 +688,12 @@ public class CheckerTestUtil {
|
||||
public String asString() {
|
||||
if (parameters == null)
|
||||
return name;
|
||||
return name + '(' + StringUtil.join(parameters, "; ") + ')';
|
||||
return name + '(' + StringUtil.join(parameters, new Function<String, String>() {
|
||||
@Override
|
||||
public String fun(String s) {
|
||||
return escape(s);
|
||||
}
|
||||
}, "; ") + ')';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
@@ -25,13 +26,11 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolver;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemCompleter;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator;
|
||||
@@ -41,8 +40,10 @@ import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.kotlin.types.expressions.FakeCallResolver;
|
||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||
@@ -57,21 +58,23 @@ import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.creat
|
||||
public class DelegatedPropertyResolver {
|
||||
|
||||
public static final Name PROPERTY_DELEGATED_FUNCTION_NAME = Name.identifier("propertyDelegated");
|
||||
public static final Name GETTER_NAME = Name.identifier("get");
|
||||
public static final Name SETTER_NAME = Name.identifier("set");
|
||||
|
||||
@NotNull private final ExpressionTypingServices expressionTypingServices;
|
||||
@NotNull private final CallResolver callResolver;
|
||||
@NotNull private final FakeCallResolver fakeCallResolver;
|
||||
@NotNull private final KotlinBuiltIns builtIns;
|
||||
@NotNull private final SymbolUsageValidator symbolUsageValidator;
|
||||
|
||||
public DelegatedPropertyResolver(
|
||||
@NotNull SymbolUsageValidator symbolUsageValidator,
|
||||
@NotNull KotlinBuiltIns builtIns,
|
||||
@NotNull CallResolver callResolver,
|
||||
@NotNull FakeCallResolver fakeCallResolver,
|
||||
@NotNull ExpressionTypingServices expressionTypingServices
|
||||
) {
|
||||
this.symbolUsageValidator = symbolUsageValidator;
|
||||
this.builtIns = builtIns;
|
||||
this.callResolver = callResolver;
|
||||
this.fakeCallResolver = fakeCallResolver;
|
||||
this.expressionTypingServices = expressionTypingServices;
|
||||
}
|
||||
|
||||
@@ -143,15 +146,15 @@ public class DelegatedPropertyResolver {
|
||||
traceToResolvePDMethod, scope,
|
||||
DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE);
|
||||
|
||||
List<JetExpression> arguments = Lists.newArrayList();
|
||||
JetPsiFactory psiFactory = JetPsiFactory(delegateExpression);
|
||||
arguments.add(createExpressionForPropertyMetadata(psiFactory, propertyDescriptor));
|
||||
JetReferenceExpression fakeCalleeExpression = psiFactory.createSimpleName(PROPERTY_DELEGATED_FUNCTION_NAME.asString());
|
||||
List<JetExpression> arguments = Collections.singletonList(createExpressionForPropertyMetadata(psiFactory, propertyDescriptor));
|
||||
ExpressionReceiver receiver = new ExpressionReceiver(delegateExpression, delegateType);
|
||||
Call call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT);
|
||||
|
||||
OverloadResolutionResults<FunctionDescriptor> functionResults =
|
||||
callResolver.resolveCallWithGivenName(context, call, fakeCalleeExpression, PROPERTY_DELEGATED_FUNCTION_NAME);
|
||||
Pair<Call, OverloadResolutionResults<FunctionDescriptor>> resolutionResult =
|
||||
fakeCallResolver.makeAndResolveFakeCallInContext(receiver, context, arguments, PROPERTY_DELEGATED_FUNCTION_NAME, delegateExpression);
|
||||
|
||||
Call call = resolutionResult.getFirst();
|
||||
OverloadResolutionResults<FunctionDescriptor> functionResults = resolutionResult.getSecond();
|
||||
|
||||
if (!functionResults.isSuccess()) {
|
||||
String expectedFunction = renderCall(call, traceToResolvePDMethod.getBindingContext());
|
||||
@@ -245,7 +248,6 @@ public class DelegatedPropertyResolver {
|
||||
List<JetExpression> arguments = Lists.newArrayList();
|
||||
JetPsiFactory psiFactory = JetPsiFactory(delegateExpression);
|
||||
arguments.add(psiFactory.createExpression(hasThis ? "this" : "null"));
|
||||
|
||||
arguments.add(createExpressionForPropertyMetadata(psiFactory, propertyDescriptor));
|
||||
|
||||
if (!isGet) {
|
||||
@@ -257,17 +259,17 @@ public class DelegatedPropertyResolver {
|
||||
trace.record(REFERENCE_TARGET, fakeArgument, valueParameters.get(0));
|
||||
}
|
||||
|
||||
Name functionName = Name.identifier(isGet ? "get" : "set");
|
||||
JetReferenceExpression fakeCalleeExpression = psiFactory.createSimpleName(functionName.asString());
|
||||
|
||||
Name functionName = isGet ? GETTER_NAME : SETTER_NAME;
|
||||
ExpressionReceiver receiver = new ExpressionReceiver(delegateExpression, delegateType);
|
||||
Call call = CallMaker.makeCallWithExpressions(delegateExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT);
|
||||
trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, call);
|
||||
|
||||
return callResolver.resolveCallWithGivenName(context, call, fakeCalleeExpression, functionName);
|
||||
Pair<Call, OverloadResolutionResults<FunctionDescriptor>> resolutionResult =
|
||||
fakeCallResolver.makeAndResolveFakeCallInContext(receiver, context, arguments, functionName, delegateExpression);
|
||||
|
||||
trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, resolutionResult.getFirst());
|
||||
return resolutionResult.getSecond();
|
||||
}
|
||||
|
||||
private String renderCall(@NotNull Call call, @NotNull BindingContext context) {
|
||||
private static String renderCall(@NotNull Call call, @NotNull BindingContext context) {
|
||||
JetExpression calleeExpression = call.getCalleeExpression();
|
||||
assert calleeExpression != null : "CalleeExpression should exists for fake call of convention method";
|
||||
StringBuilder builder = new StringBuilder(calleeExpression.getText());
|
||||
|
||||
@@ -16,21 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.types.expressions
|
||||
|
||||
import com.google.common.collect.Lists
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.Call
|
||||
import org.jetbrains.kotlin.psi.JetExpression
|
||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.TraceEntryFilter
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice
|
||||
import org.jetbrains.kotlin.utils.doNothing
|
||||
import java.util.*
|
||||
|
||||
public class FakeCallResolver(
|
||||
@@ -78,17 +77,34 @@ public class FakeCallResolver(
|
||||
name: Name,
|
||||
callElement: JetExpression?
|
||||
): Pair<Call, OverloadResolutionResults<FunctionDescriptor>> {
|
||||
val fake = JetPsiFactory(project).createSimpleName("fake")
|
||||
val fakeTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve fake call for", name)
|
||||
val call = CallMaker.makeCallWithExpressions(callElement ?: fake, receiver, null, fake, valueArguments)
|
||||
val results = callResolver.resolveCallWithGivenName(context.replaceBindingTrace(fakeTrace), call, fake, name)
|
||||
if (results.isSuccess()) {
|
||||
val fakeBindingTrace = context.replaceBindingTrace(fakeTrace)
|
||||
|
||||
return makeAndResolveFakeCallInContext(receiver, fakeBindingTrace, valueArguments, name, callElement) { fake ->
|
||||
fakeTrace.commit({ _, key ->
|
||||
// excluding all entries related to fake expression
|
||||
key != fake
|
||||
}, true)
|
||||
}
|
||||
return Pair(call, results)
|
||||
}
|
||||
|
||||
}
|
||||
@JvmOverloads
|
||||
public fun makeAndResolveFakeCallInContext(
|
||||
receiver: ReceiverValue,
|
||||
context: ExpressionTypingContext,
|
||||
valueArguments: List<JetExpression>,
|
||||
name: Name,
|
||||
callElement: JetExpression?,
|
||||
onSuccess: (JetSimpleNameExpression) -> Unit = doNothing()
|
||||
): Pair<Call, OverloadResolutionResults<FunctionDescriptor>> {
|
||||
val fake = JetPsiFactory(project).createSimpleName(name.asString())
|
||||
val call = CallMaker.makeCallWithExpressions(callElement ?: fake, receiver, null, fake, valueArguments)
|
||||
val results = callResolver.resolveCallWithGivenName(context, call, fake, name)
|
||||
|
||||
if (results.isSuccess) {
|
||||
onSuccess(fake)
|
||||
}
|
||||
|
||||
return Pair(call, results)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
val a: Int by <!DELEGATE_SPECIAL_FUNCTION_MISSING!>A()<!>
|
||||
val a: Int by <!DELEGATE_SPECIAL_FUNCTION_MISSING(get\(kotlin.Nothing?, kotlin.PropertyMetadata\); A)!>A()<!>
|
||||
|
||||
class A
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
var a: Int by <!DELEGATE_SPECIAL_FUNCTION_MISSING!>A()<!>
|
||||
var a: Int by <!DELEGATE_SPECIAL_FUNCTION_MISSING(set\(kotlin.Nothing?, kotlin.PropertyMetadata, kotlin.Int\); A)!>A()<!>
|
||||
|
||||
class A {
|
||||
fun get(t: Any?, p: PropertyMetadata): Int {
|
||||
|
||||
Reference in New Issue
Block a user