KtLightMethod: Wrap return type so it resolves to light method's type parameter as opposed to delegate's
Affects java type inference in IDEA #KT-12090 Fixed #KT-11095 Fixed
This commit is contained in:
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.asJava
|
||||
import com.intellij.core.JavaCoreBundle
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.compiled.ClsTypeElementImpl
|
||||
import com.intellij.psi.impl.light.LightMethod
|
||||
import com.intellij.psi.scope.PsiScopeProcessor
|
||||
import com.intellij.psi.util.*
|
||||
@@ -40,6 +41,10 @@ sealed class KtLightMethodImpl(
|
||||
override val kotlinOrigin: KtDeclaration? get() = lightMethodOrigin?.originalElement as? KtDeclaration
|
||||
|
||||
private val lightIdentifier by lazy(LazyThreadSafetyMode.PUBLICATION) { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) }
|
||||
private val returnTypeElem by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
val delegateTypeElement = clsDelegate.returnTypeElement as? ClsTypeElementImpl
|
||||
delegateTypeElement?.let { ClsTypeElementImpl(this, it.canonicalText, /*ClsTypeElementImpl.VARIANCE_NONE */ 0.toChar()) }
|
||||
}
|
||||
|
||||
override fun getContainingClass(): KtLightClass = super.getContainingClass() as KtLightClass
|
||||
|
||||
@@ -178,6 +183,12 @@ sealed class KtLightMethodImpl(
|
||||
override fun getDefaultValue() = clsDelegate.defaultValue
|
||||
}
|
||||
|
||||
// override getReturnType() so return type resolves to type parameters of this method not delegate's
|
||||
// which is relied upon by java type inference
|
||||
override fun getReturnTypeElement(): PsiTypeElement? = returnTypeElem
|
||||
|
||||
override fun getReturnType() = returnTypeElement?.type
|
||||
|
||||
companion object Factory {
|
||||
fun create(
|
||||
delegate: PsiMethod, origin: LightMemberOrigin?, containingClass: KtLightClass
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class InferenceReturnType_1_6 {
|
||||
public static void test(a.C c, a.I i, a.B b) {
|
||||
a.C cc = a.Util.helper(c);
|
||||
a.I ii = a.Util.helper(i);
|
||||
a.B bb = a.Util.helper(b);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
@file: JvmName("Util")
|
||||
|
||||
package a
|
||||
|
||||
interface I
|
||||
|
||||
class C : I
|
||||
class B : I
|
||||
|
||||
fun <T : I> T.helper(): T = this
|
||||
+1
@@ -0,0 +1 @@
|
||||
// LANGUAGE_LEVEL 1.6
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class InferenceReturnType_1_8 {
|
||||
public static void test() {
|
||||
a.A<a.A<String>> ll = a.ValueManager.Companion.reject();
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
@file: JvmName("Util")
|
||||
|
||||
package a
|
||||
|
||||
class A<T>()
|
||||
|
||||
class ValueManager() {
|
||||
companion object {
|
||||
fun <Z> reject() = null as A<Z>
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
// LANGUAGE_LEVEL 1.8
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,8 @@ import com.intellij.codeInspection.nullable.NullableStuffInspection;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.siyeh.ig.bugs.StaticCallOnSubclassInspection;
|
||||
import com.siyeh.ig.bugs.StaticFieldReferenceOnSubclassInspection;
|
||||
@@ -93,10 +95,25 @@ public abstract class AbstractJavaAgainstKotlinCheckerTest extends KotlinDaemonA
|
||||
Module module = super.createMainModule();
|
||||
|
||||
String configFileText = getConfigFileText();
|
||||
if (configFileText != null && InTextDirectivesUtils.isDirectiveDefined(configFileText, "// WITH_RUNTIME")) {
|
||||
if (configFileText == null) {
|
||||
return module;
|
||||
}
|
||||
|
||||
if (InTextDirectivesUtils.isDirectiveDefined(configFileText, "// WITH_RUNTIME")) {
|
||||
ConfigLibraryUtil.configureKotlinRuntime(module);
|
||||
}
|
||||
|
||||
List<String> languageLevelLines = InTextDirectivesUtils.findLinesWithPrefixesRemoved(configFileText, "// LANGUAGE_LEVEL");
|
||||
if (languageLevelLines.size() > 1) {
|
||||
throw new AssertionError("Language level specified multiple times: " + languageLevelLines);
|
||||
}
|
||||
if (languageLevelLines.size() == 1) {
|
||||
LanguageLevel level = LanguageLevel.parse(languageLevelLines.iterator().next());
|
||||
if (level != null) {
|
||||
IdeaTestUtil.setModuleLanguageLevel(module, level);
|
||||
}
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -77,6 +77,18 @@ public class JavaAgainstKotlinBinariesCheckerTestGenerated extends AbstractJavaA
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InferenceReturnType_1_6.kt")
|
||||
public void testInferenceReturnType_1_6() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kotlinAndJavaChecker/javaAgainstKotlin/InferenceReturnType_1_6.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InferenceReturnType_1_8.kt")
|
||||
public void testInferenceReturnType_1_8() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kotlinAndJavaChecker/javaAgainstKotlin/InferenceReturnType_1_8.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InterfaceDefaultImpls.kt")
|
||||
public void testInterfaceDefaultImpls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kotlinAndJavaChecker/javaAgainstKotlin/InterfaceDefaultImpls.kt");
|
||||
|
||||
+12
@@ -79,6 +79,18 @@ public class JavaAgainstKotlinSourceCheckerTestGenerated extends AbstractJavaAga
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InferenceReturnType_1_6.kt")
|
||||
public void testInferenceReturnType_1_6() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kotlinAndJavaChecker/javaAgainstKotlin/InferenceReturnType_1_6.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InferenceReturnType_1_8.kt")
|
||||
public void testInferenceReturnType_1_8() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kotlinAndJavaChecker/javaAgainstKotlin/InferenceReturnType_1_8.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InterfaceDefaultImpls.kt")
|
||||
public void testInterfaceDefaultImpls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kotlinAndJavaChecker/javaAgainstKotlin/InterfaceDefaultImpls.kt");
|
||||
|
||||
Reference in New Issue
Block a user