J2K does not convert usages of java "get" methods into "[]" (explicit "operator" modifier is required)

This commit is contained in:
Valentin Kipyatkov
2015-10-17 12:06:53 +03:00
parent e7fa2cb776
commit fc10fa66be
5 changed files with 40 additions and 7 deletions
@@ -32,9 +32,15 @@ import org.jetbrains.kotlin.psi.buildExpression
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
public class ExplicitGetInspection : IntentionBasedInspection<JetDotQualifiedExpression>( public class ExplicitGetInspection : IntentionBasedInspection<JetDotQualifiedExpression>(
ReplaceGetIntention(), ReplaceGetIntention(), ExplicitGetInspection.additionalChecker
additionalChecker = { expression -> (expression.toResolvedCall()!!.resultingDescriptor as FunctionDescriptor).isExplicitOperator() }
) ) {
companion object {
val additionalChecker = { expression: JetDotQualifiedExpression ->
(expression.toResolvedCall()!!.resultingDescriptor as FunctionDescriptor).isExplicitOperator()
}
}
}
private fun FunctionDescriptor.isExplicitOperator(): Boolean { private fun FunctionDescriptor.isExplicitOperator(): Boolean {
return if (overriddenDescriptors.isEmpty()) return if (overriddenDescriptors.isEmpty())
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.inspections.RedundantSamConstructorInspection
import org.jetbrains.kotlin.idea.intentions.* import org.jetbrains.kotlin.idea.intentions.*
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.IfThenToElvisIntention import org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.IfThenToElvisIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.IfThenToSafeAccessIntention import org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.IfThenToSafeAccessIntention
import org.jetbrains.kotlin.idea.intentions.conventionNameCalls.ExplicitGetInspection
import org.jetbrains.kotlin.idea.intentions.conventionNameCalls.ReplaceGetIntention import org.jetbrains.kotlin.idea.intentions.conventionNameCalls.ReplaceGetIntention
import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix
import org.jetbrains.kotlin.idea.quickfix.RemoveRightPartOfBinaryExpressionFix import org.jetbrains.kotlin.idea.quickfix.RemoveRightPartOfBinaryExpressionFix
@@ -59,7 +60,7 @@ object J2KPostProcessingRegistrar {
registerIntentionBasedProcessing(IfThenToElvisIntention()) { applyTo(it) } registerIntentionBasedProcessing(IfThenToElvisIntention()) { applyTo(it) }
registerIntentionBasedProcessing(IfNullToElvisIntention()) { applyTo(it) } registerIntentionBasedProcessing(IfNullToElvisIntention()) { applyTo(it) }
registerIntentionBasedProcessing(SimplifyNegatedBinaryExpressionIntention()) { applyTo(it) } registerIntentionBasedProcessing(SimplifyNegatedBinaryExpressionIntention()) { applyTo(it) }
registerIntentionBasedProcessing(ReplaceGetIntention()) { applyTo(it) } registerIntentionBasedProcessing(ReplaceGetIntention(), additionalChecker = ExplicitGetInspection.additionalChecker) { applyTo(it) }
registerIntentionBasedProcessing(AddOperatorModifierIntention()) { applyTo(it) } registerIntentionBasedProcessing(AddOperatorModifierIntention()) { applyTo(it) }
registerDiagnosticBasedProcessing<JetBinaryExpressionWithTypeRHS>(Errors.USELESS_CAST) { element, diagnostic -> registerDiagnosticBasedProcessing<JetBinaryExpressionWithTypeRHS>(Errors.USELESS_CAST) { element, diagnostic ->
@@ -102,12 +103,22 @@ object J2KPostProcessingRegistrar {
private inline fun <reified TElement : JetElement, TIntention: JetSelfTargetingRangeIntention<TElement>> registerIntentionBasedProcessing( private inline fun <reified TElement : JetElement, TIntention: JetSelfTargetingRangeIntention<TElement>> registerIntentionBasedProcessing(
intention: TIntention, intention: TIntention,
crossinline apply: TIntention.(TElement) -> Unit crossinline apply: TIntention.(TElement) -> Unit
) {
//TODO: replace with optional argument when supported for inline functions
return registerIntentionBasedProcessing<TElement, TIntention>(intention, { true }, apply)
}
private inline fun <reified TElement : JetElement, TIntention: JetSelfTargetingRangeIntention<TElement>> registerIntentionBasedProcessing(
intention: TIntention,
noinline additionalChecker: (TElement) -> Boolean,
crossinline apply: TIntention.(TElement) -> Unit
) { ) {
_processings.add(object : J2kPostProcessing { _processings.add(object : J2kPostProcessing {
override fun createAction(element: JetElement, diagnostics: Diagnostics): (() -> Unit)? { override fun createAction(element: JetElement, diagnostics: Diagnostics): (() -> Unit)? {
if (!javaClass<TElement>().isInstance(element)) return null if (!javaClass<TElement>().isInstance(element)) return null
@Suppress("UNCHECKED_CAST") val tElement = element as TElement
if (intention.applicabilityRange(element as TElement) == null) return null if (intention.applicabilityRange(tElement) == null) return null
if (!additionalChecker(tElement)) return null
return { intention.apply(element) } return { intention.apply(element) }
} }
}) })
+6
View File
@@ -113,4 +113,10 @@ public class JavaClassDerivedFromKotlinClassWithProperties extends KotlinClassWi
@Override @Override
public void setSomeVar2(String value) { } public void setSomeVar2(String value) { }
}
public class JavaClass {
public int get(int p) {
return 0;
}
} }
@@ -1,5 +1,6 @@
import java.util.HashMap; import java.util.HashMap;
import kotlinApi.KotlinClass; import kotlinApi.KotlinClass;
import javaApi.JavaClass;
class X { class X {
int get(int index) { int get(int index) {
@@ -19,4 +20,8 @@ class C {
int foo(KotlinClass kotlinClass) { int foo(KotlinClass kotlinClass) {
return kotlinClass.get(0); // not operator! return kotlinClass.get(0); // not operator!
} }
int foo(JavaClass javaClass) {
return javaClass.get(0);
}
} }
+6 -1
View File
@@ -1,6 +1,7 @@
// ERROR: Type mismatch: inferred type is kotlin.String? but kotlin.String was expected // ERROR: Type mismatch: inferred type is kotlin.String? but kotlin.String was expected
import java.util.HashMap import java.util.HashMap
import kotlinApi.KotlinClass import kotlinApi.KotlinClass
import javaApi.JavaClass
internal class X { internal class X {
operator fun get(index: Int): Int { operator fun get(index: Int): Int {
@@ -20,4 +21,8 @@ internal class C {
fun foo(kotlinClass: KotlinClass): Int { fun foo(kotlinClass: KotlinClass): Int {
return kotlinClass.get(0) // not operator! return kotlinClass.get(0) // not operator!
} }
}
fun foo(javaClass: JavaClass): Int {
return javaClass.get(0)
}
}