Drop resolution of deprecated plus/minus/get/set conventions

Also remove the corresponding quick fix
This commit is contained in:
Alexander Udalov
2016-06-27 17:35:08 +03:00
parent 291f1f6c3a
commit 70a994b135
21 changed files with 20 additions and 244 deletions
@@ -580,8 +580,6 @@ public interface Errors {
DiagnosticFactory0<KtArrayAccessExpression> NO_GET_METHOD = DiagnosticFactory0.create(ERROR, ARRAY_ACCESS);
DiagnosticFactory0<KtArrayAccessExpression> NO_SET_METHOD = DiagnosticFactory0.create(ERROR, ARRAY_ACCESS);
DiagnosticFactory2<KtUnaryExpression, FunctionDescriptor, String> DEPRECATED_UNARY_PLUS_MINUS = DiagnosticFactory2.create(ERROR);
DiagnosticFactory0<KtSimpleNameExpression> INC_DEC_SHOULD_NOT_RETURN_UNIT = DiagnosticFactory0.create(ERROR);
DiagnosticFactory2<KtSimpleNameExpression, DeclarationDescriptor, KtSimpleNameExpression> ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT =
DiagnosticFactory2.create(ERROR);
@@ -607,7 +605,6 @@ public interface Errors {
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> ITERATOR_AMBIGUITY = DiagnosticFactory1.create(ERROR);
DiagnosticFactory2<KtExpression, String, KotlinType> DELEGATE_SPECIAL_FUNCTION_MISSING = DiagnosticFactory2.create(ERROR);
DiagnosticFactory3<PsiElement, FunctionDescriptor, KotlinType, String> DELEGATE_RESOLVED_TO_DEPRECATED_CONVENTION = DiagnosticFactory3.create(ERROR);
DiagnosticFactory2<KtExpression, String, Collection<? extends ResolvedCall<?>>> DELEGATE_SPECIAL_FUNCTION_AMBIGUITY = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<KtExpression, String, Collection<? extends ResolvedCall<?>>> DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory3<KtExpression, String, KotlinType, KotlinType> DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH = DiagnosticFactory3.create(ERROR);
@@ -312,8 +312,6 @@ public class DefaultErrorMessages {
MAP.put(NO_GET_METHOD, "No get method providing array access");
MAP.put(NO_SET_METHOD, "No set method providing array access");
MAP.put(DEPRECATED_UNARY_PLUS_MINUS, "Unary operation must be named ''{1}'', not ''{0}''", NAME, STRING);
MAP.put(INC_DEC_SHOULD_NOT_RETURN_UNIT, "Functions inc(), dec() shouldn't return Unit to be used by operators ++, --");
MAP.put(ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT, "Function ''{0}'' should return Unit to be used by corresponding operator ''{1}''",
NAME, ELEMENT_TEXT);
@@ -365,7 +363,6 @@ public class DefaultErrorMessages {
MAP.put(ITERATOR_AMBIGUITY, "Method ''iterator()'' is ambiguous for this expression: {0}", AMBIGUOUS_CALLS);
MAP.put(DELEGATE_SPECIAL_FUNCTION_MISSING, "Missing ''{0}'' method on delegate of type ''{1}''", STRING, RENDER_TYPE);
MAP.put(DELEGATE_RESOLVED_TO_DEPRECATED_CONVENTION, "''{0}'' method convention on type ''{1}'' is no longer supported. Rename to ''{2}''", NAME, RENDER_TYPE, STRING);
MAP.put(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY, "Overload resolution ambiguity on method ''{0}'': {1}", STRING, AMBIGUOUS_CALLS);
MAP.put(DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, "Property delegate must have a ''{0}'' method. None of the following functions is suitable: {1}",
STRING, AMBIGUOUS_CALLS);
@@ -63,9 +63,6 @@ import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.creat
public class DelegatedPropertyResolver {
public static final Name PROPERTY_DELEGATED_FUNCTION_NAME = Name.identifier("propertyDelegated");
private static final Name OLD_GETTER_NAME = Name.identifier("get");
private static final Name OLD_SETTER_NAME = Name.identifier("set");
private final ExpressionTypingServices expressionTypingServices;
private final FakeCallResolver fakeCallResolver;
private final KotlinBuiltIns builtIns;
@@ -142,7 +139,7 @@ public class DelegatedPropertyResolver {
return resolvedCall != null ? resolvedCall.getResultingDescriptor().getReturnType() : null;
}
public void resolveDelegatedPropertyGetMethod(
private void resolveDelegatedPropertyGetMethod(
@NotNull VariableDescriptorWithAccessors variableDescriptor,
@NotNull KtExpression delegateExpression,
@NotNull KotlinType delegateType,
@@ -162,7 +159,7 @@ public class DelegatedPropertyResolver {
}
}
public void resolveDelegatedPropertySetMethod(
private void resolveDelegatedPropertySetMethod(
@NotNull VariableDescriptorWithAccessors variableDescriptor,
@NotNull KtExpression delegateExpression,
@NotNull KotlinType delegateType,
@@ -177,7 +174,7 @@ public class DelegatedPropertyResolver {
return psiFactory.createExpression("null as " + KotlinBuiltIns.FQ_NAMES.kProperty.asSingleFqName().asString() + "<*>");
}
public void resolveDelegatedPropertyPDMethod(
private void resolveDelegatedPropertyPDMethod(
@NotNull VariableDescriptorWithAccessors variableDescriptor,
@NotNull KtExpression delegateExpression,
@NotNull KotlinType delegateType,
@@ -273,7 +270,7 @@ public class DelegatedPropertyResolver {
}
/* Resolve getValue() or setValue() methods from delegate */
public OverloadResolutionResults<FunctionDescriptor> getDelegatedPropertyConventionMethod(
private OverloadResolutionResults<FunctionDescriptor> getDelegatedPropertyConventionMethod(
@NotNull VariableDescriptorWithAccessors propertyDescriptor,
@NotNull KtExpression delegateExpression,
@NotNull KotlinType delegateType,
@@ -314,35 +311,8 @@ public class DelegatedPropertyResolver {
Pair<Call, OverloadResolutionResults<FunctionDescriptor>> resolutionResult =
fakeCallResolver.makeAndResolveFakeCallInContext(receiver, context, arguments, functionName, delegateExpression);
OverloadResolutionResults<FunctionDescriptor> resolutionResults = resolutionResult.getSecond();
// Resolve get/set is getValue/setValue was not found. Temporary, for code migration
if (!resolutionResults.isSuccess() && !resolutionResults.isAmbiguity()) {
Name oldFunctionName = isGet ? OLD_GETTER_NAME : OLD_SETTER_NAME;
Pair<Call, OverloadResolutionResults<FunctionDescriptor>> additionalResolutionResult =
fakeCallResolver.makeAndResolveFakeCallInContext(receiver, context, arguments, oldFunctionName, delegateExpression);
if (additionalResolutionResult.getSecond().isSuccess()) {
FunctionDescriptor resultingDescriptor = additionalResolutionResult.getSecond().getResultingDescriptor();
PsiElement declaration = DescriptorToSourceUtils.descriptorToDeclaration(propertyDescriptor);
if (declaration instanceof KtProperty) {
KtProperty property = (KtProperty) declaration;
KtPropertyDelegate delegate = property.getDelegate();
if (delegate != null) {
PsiElement byKeyword = delegate.getByKeywordNode().getPsi();
trace.report(DELEGATE_RESOLVED_TO_DEPRECATED_CONVENTION.on(
byKeyword, resultingDescriptor, delegateType, functionName.asString()));
}
}
trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, additionalResolutionResult.getFirst());
return additionalResolutionResult.getSecond();
}
}
trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, resolutionResult.getFirst());
return resolutionResults;
return resolutionResult.getSecond();
}
//TODO: diagnostics rendering does not belong here
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.builtins.isExtensionFunctionType
import org.jetbrains.kotlin.coroutines.getExpectedTypeForCoroutineControllerHandleResult
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.CallTransformer
@@ -138,13 +137,6 @@ fun isConventionCall(call: Call): Boolean {
fun isInfixCall(call: Call): Boolean = InfixCallChecker.isInfixCall(call.calleeExpression)
fun getUnaryPlusOrMinusOperatorFunctionName(call: Call): Name? {
if (call.callElement !is KtPrefixExpression) return null
val calleeExpression = call.calleeExpression as? KtOperationReferenceExpression ?: return null
val name = calleeExpression.getNameForConventionalOperation(unaryOperations = true, binaryOperations = false)
return if (name == OperatorNameConventions.UNARY_PLUS || name == OperatorNameConventions.UNARY_MINUS) name else null
}
fun isInvokeCallOnVariable(call: Call): Boolean {
if (call.callType !== Call.CallType.INVOKE) return false
val dispatchReceiver = call.dispatchReceiver
@@ -20,7 +20,9 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
import org.jetbrains.kotlin.psi.KtOperationReferenceExpression
import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
@@ -28,10 +30,6 @@ import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.util.OperatorNameConventions.MINUS
import org.jetbrains.kotlin.util.OperatorNameConventions.PLUS
import org.jetbrains.kotlin.util.OperatorNameConventions.UNARY_MINUS
import org.jetbrains.kotlin.util.OperatorNameConventions.UNARY_PLUS
class OperatorCallChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
@@ -62,19 +60,6 @@ class OperatorCallChecker : CallChecker {
if (!functionDescriptor.isOperator) {
report(reportOn, functionDescriptor, context.trace)
}
if (isConventionOperator) {
checkDeprecatedUnaryConventions(call, functionDescriptor, context.trace)
}
}
}
private fun checkDeprecatedUnaryConventions(call: Call, functionDescriptor: FunctionDescriptor, sink: DiagnosticSink) {
(call.callElement as? KtPrefixExpression)?.let { expr ->
val functionName = functionDescriptor.name
if (functionName == PLUS || functionName == MINUS) {
val newName = if (functionName == PLUS) UNARY_PLUS else UNARY_MINUS
sink.report(Errors.DEPRECATED_UNARY_PLUS_MINUS.on(expr, functionDescriptor, newName.asString()))
}
}
}
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.psi.Call
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.CandidateResolver
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getUnaryPlusOrMinusOperatorFunctionName
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation
@@ -141,22 +140,11 @@ class NewResolutionOldInference(
val dynamicScope = dynamicCallableDescriptors.createDynamicDescriptorScope(context.call, context.scope.ownerDescriptor)
val scopeTower = ScopeTowerImpl(context, dynamicScope, syntheticScopes, context.call.createLookupLocation())
var processor = kind.createTowerProcessor(this, name, tracing, scopeTower, explicitReceiver, context)
val processor = kind.createTowerProcessor(this, name, tracing, scopeTower, explicitReceiver, context)
if (context.collectAllCandidates) {
return allCandidatesResult(towerResolver.collectAllCandidates(scopeTower, processor))
}
// Temporary fix for code migration (unaryPlus()/unaryMinus())
val unaryConventionName = getUnaryPlusOrMinusOperatorFunctionName(context.call)
if (unaryConventionName != null) {
val deprecatedName = if (name == OperatorNameConventions.UNARY_PLUS)
OperatorNameConventions.PLUS
else
OperatorNameConventions.MINUS
val deprecatedProcessor = kind.createTowerProcessor(this, deprecatedName, tracing, scopeTower, explicitReceiver, context)
processor = CompositeScopeTowerProcessor(processor, deprecatedProcessor)
}
val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = kind != ResolutionKind.CallableReference)
return convertToOverloadResults(candidates, tracing, context)
@@ -33,15 +33,15 @@ operator fun CustomDelegate3.setValue(thisRef: Any?, prop: KProperty<*>, value:
class Example {
var a <!DELEGATE_RESOLVED_TO_DEPRECATED_CONVENTION, DELEGATE_RESOLVED_TO_DEPRECATED_CONVENTION!>by<!> CustomDelegate()
val aval <!DELEGATE_RESOLVED_TO_DEPRECATED_CONVENTION!>by<!> CustomDelegate()
var a by <!DELEGATE_SPECIAL_FUNCTION_MISSING, DELEGATE_SPECIAL_FUNCTION_MISSING!>CustomDelegate()<!>
val aval by <!DELEGATE_SPECIAL_FUNCTION_MISSING!>CustomDelegate()<!>
var b by OkDelegate()
var c by CustomDelegate2()
var d by CustomDelegate3()
fun test() {
requireString(a)
requireString(aval)
requireString(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>a<!>)
requireString(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>aval<!>)
requireString(b)
requireInt(c)
requireInt(d)
@@ -36,8 +36,8 @@ public final class CustomDelegate3 {
public final class Example {
public constructor Example()
public final var a: kotlin.String
public final val aval: kotlin.String
public final var a: [ERROR : Type from delegate]
public final val aval: [ERROR : Type from delegate]
public final var b: kotlin.String
public final var c: kotlin.Int
public final var d: kotlin.Int
@@ -15,7 +15,7 @@ operator fun String.unaryPlus(): Int = 0
fun test() {
requireInt(+ "")
requireInt(+ Example())
requireString(<!DEPRECATED_UNARY_PLUS_MINUS!>+ ExampleDeprecated()<!>)
requireString(<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+<!> ExampleDeprecated())
}
fun requireInt(n: Int) {}
@@ -26,7 +26,7 @@ class Example2 {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus() = this
fun test() {
<!DEPRECATED_UNARY_PLUS_MINUS!>+this<!>
<!DEPRECATED_UNARY_PLUS_MINUS!>-this<!>
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+<!>this
<!UNRESOLVED_REFERENCE!>-<!>this
}
}
}
@@ -27,7 +27,7 @@ fun dynamic.test() {
<!DEBUG_INFO_DYNAMIC!>this<!>()
C() + C()
<!DEPRECATED_UNARY_PLUS_MINUS!><!NO_VALUE_FOR_PARAMETER!>+<!>C()<!>
<!UNRESOLVED_REFERENCE!>+<!>C()
this <!DEBUG_INFO_DYNAMIC!>+<!> C()