[LL FIR, Java] fix resolve contract violation from java symbol provider
To create a smart psi type pointer, IJ Platform uses resolve. We cannot use resolve from JavaSymbolProvider, as it may lead to resolve contract violation. ^KT-59133 fixed
This commit is contained in:
committed by
Space Team
parent
f590e88bdd
commit
b8f15cbbb3
+13
@@ -47,3 +47,16 @@ internal class JavaElementDelegatingExpressionTypeSourceWithSmartPointer<TYPE :
|
|||||||
return psi.type as TYPE
|
return psi.type as TYPE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal class JavaElementDelegatingTypeParameterBoundTypeSourceWithSmartPointer<TYPE : PsiType>(
|
||||||
|
override val psiPointer: SmartPsiElementPointer<out PsiTypeParameter>,
|
||||||
|
private val boundIndex: Int,
|
||||||
|
override val factory: JavaElementSourceFactory,
|
||||||
|
) : JavaElementDelegatingTypeSourceWithSmartPointer<PsiTypeParameter, TYPE>() {
|
||||||
|
|
||||||
|
override fun getType(psi: PsiTypeParameter): TYPE {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return psi.bounds[boundIndex] as TYPE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+12
@@ -33,6 +33,18 @@ class JavaElementSourceWithSmartPointerFactory(project: Project) : JavaElementSo
|
|||||||
return JavaElementDelegatingMethodReturnTypeSourceWithSmartPointer(psiMethodSource.pointer, psiMethodSource.factory)
|
return JavaElementDelegatingMethodReturnTypeSourceWithSmartPointer(psiMethodSource.pointer, psiMethodSource.factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun <TYPE : PsiType> createTypeParameterUpperBoundTypeSource(
|
||||||
|
psiTypeParameterSource: JavaElementPsiSource<out PsiTypeParameter>,
|
||||||
|
boundIndex: Int
|
||||||
|
): JavaElementTypeSource<TYPE> {
|
||||||
|
require(psiTypeParameterSource is JavaElementPsiSourceWithSmartPointer)
|
||||||
|
return JavaElementDelegatingTypeParameterBoundTypeSourceWithSmartPointer(
|
||||||
|
psiTypeParameterSource.pointer,
|
||||||
|
boundIndex,
|
||||||
|
psiTypeParameterSource.factory
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun <TYPE : PsiType> createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource<out PsiExpression>): JavaElementTypeSource<TYPE> {
|
override fun <TYPE : PsiType> createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource<out PsiExpression>): JavaElementTypeSource<TYPE> {
|
||||||
require(psiExpressionSource is JavaElementPsiSourceWithSmartPointer)
|
require(psiExpressionSource is JavaElementPsiSourceWithSmartPointer)
|
||||||
return JavaElementDelegatingExpressionTypeSourceWithSmartPointer(psiExpressionSource.pointer, psiExpressionSource.factory)
|
return JavaElementDelegatingExpressionTypeSourceWithSmartPointer(psiExpressionSource.pointer, psiExpressionSource.factory)
|
||||||
|
|||||||
+6
@@ -21,6 +21,12 @@ public class DiagnosticCompilerTestFirTestdataTestGenerated extends AbstractDiag
|
|||||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolve")
|
@TestMetadata("compiler/fir/analysis-tests/testData/resolve")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
public class Resolve {
|
public class Resolve {
|
||||||
|
@Test
|
||||||
|
@TestMetadata("accessJavaFromKotlinViaImport.kt")
|
||||||
|
public void testAccessJavaFromKotlinViaImport() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInResolve() throws Exception {
|
public void testAllFilesPresentInResolve() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
|||||||
+6
@@ -21,6 +21,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated
|
|||||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolve")
|
@TestMetadata("compiler/fir/analysis-tests/testData/resolve")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
public class Resolve {
|
public class Resolve {
|
||||||
|
@Test
|
||||||
|
@TestMetadata("accessJavaFromKotlinViaImport.kt")
|
||||||
|
public void testAccessJavaFromKotlinViaImport() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInResolve() throws Exception {
|
public void testAllFilesPresentInResolve() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
|||||||
+5
@@ -25,6 +25,11 @@ public class LazyBodyIsNotTouchedTestGenerated extends AbstractLazyBodyIsNotTouc
|
|||||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("accessJavaFromKotlinViaImport.kt")
|
||||||
|
public void testAccessJavaFromKotlinViaImport() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInResolve() throws Exception {
|
public void testAllFilesPresentInResolve() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
FILE: useSite.kt
|
||||||
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
|
Q|InspectionProfileImpl|.R|/InspectionProfileImpl.INIT_INSPECTIONS| = Boolean(true)
|
||||||
|
}
|
||||||
|
FILE: NewInspectionProfile.kt
|
||||||
|
public abstract class NewInspectionProfile : R|kotlin/Any| {
|
||||||
|
public constructor(): R|NewInspectionProfile| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
// FILE: useSite.kt
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
InspectionProfileImpl.INIT_INSPECTIONS = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: InspectionProfileImpl.java
|
||||||
|
public class InspectionProfileImpl extends NewInspectionProfile {
|
||||||
|
public static boolean INIT_INSPECTIONS;
|
||||||
|
|
||||||
|
public <T extends InspectionProfileEntry> T getUnwrappedTool() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: NewInspectionProfile.kt
|
||||||
|
import InspectionProfileImpl.INIT_INSPECTIONS
|
||||||
|
|
||||||
|
abstract class NewInspectionProfile
|
||||||
|
|
||||||
|
// FILE: InspectionProfileEntry.java
|
||||||
|
public abstract class InspectionProfileEntry {}
|
||||||
+6
@@ -21,6 +21,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi
|
|||||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolve")
|
@TestMetadata("compiler/fir/analysis-tests/testData/resolve")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
public class Resolve {
|
public class Resolve {
|
||||||
|
@Test
|
||||||
|
@TestMetadata("accessJavaFromKotlinViaImport.kt")
|
||||||
|
public void testAccessJavaFromKotlinViaImport() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInResolve() throws Exception {
|
public void testAllFilesPresentInResolve() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
|||||||
+6
@@ -21,6 +21,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest
|
|||||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolve")
|
@TestMetadata("compiler/fir/analysis-tests/testData/resolve")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
public class Resolve {
|
public class Resolve {
|
||||||
|
@Test
|
||||||
|
@TestMetadata("accessJavaFromKotlinViaImport.kt")
|
||||||
|
public void testAccessJavaFromKotlinViaImport() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInResolve() throws Exception {
|
public void testAllFilesPresentInResolve() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
|||||||
+15
-1
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.load.java.structure.impl;
|
package org.jetbrains.kotlin.load.java.structure.impl;
|
||||||
|
|
||||||
import com.intellij.psi.PsiAnnotationOwner;
|
import com.intellij.psi.PsiAnnotationOwner;
|
||||||
|
import com.intellij.psi.PsiClassType;
|
||||||
import com.intellij.psi.PsiField;
|
import com.intellij.psi.PsiField;
|
||||||
import com.intellij.psi.PsiTypeParameter;
|
import com.intellij.psi.PsiTypeParameter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -25,10 +26,14 @@ import org.jetbrains.kotlin.load.java.structure.JavaClassifierType;
|
|||||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter;
|
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter;
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementPsiSource;
|
import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementPsiSource;
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementSourceFactory;
|
import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementSourceFactory;
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementTypeSource;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.name.SpecialNames;
|
import org.jetbrains.kotlin.name.SpecialNames;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.load.java.structure.impl.JavaElementCollectionFromPsiArrayUtil.classifierTypes;
|
import static org.jetbrains.kotlin.load.java.structure.impl.JavaElementCollectionFromPsiArrayUtil.classifierTypes;
|
||||||
|
|
||||||
@@ -51,7 +56,16 @@ public class JavaTypeParameterImpl extends JavaClassifierImpl<PsiTypeParameter>
|
|||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public Collection<JavaClassifierType> getUpperBounds() {
|
public Collection<JavaClassifierType> getUpperBounds() {
|
||||||
return classifierTypes(getPsi().getExtendsList().getReferencedTypes(), getSourceFactory());
|
PsiClassType[] referencedTypes = getPsi().getExtendsList().getReferencedTypes();
|
||||||
|
if (referencedTypes.length == 0) return Collections.emptyList();
|
||||||
|
Collection<JavaClassifierType> result = new ArrayList<>(referencedTypes.length);
|
||||||
|
JavaElementSourceFactory sourceFactory = getSourceFactory();
|
||||||
|
for (int boundIndex = 0; boundIndex < referencedTypes.length; boundIndex++) {
|
||||||
|
JavaElementTypeSource<PsiClassType> source =
|
||||||
|
sourceFactory.createTypeParameterUpperBoundTypeSource(psiElementSource, boundIndex);
|
||||||
|
result.add(new JavaClassifierTypeImpl(source));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
+13
@@ -14,6 +14,11 @@ abstract class JavaElementSourceFactory {
|
|||||||
abstract fun <TYPE : PsiType> createVariableReturnTypeSource(psiVariableSource: JavaElementPsiSource<out PsiVariable>): JavaElementTypeSource<TYPE>
|
abstract fun <TYPE : PsiType> createVariableReturnTypeSource(psiVariableSource: JavaElementPsiSource<out PsiVariable>): JavaElementTypeSource<TYPE>
|
||||||
abstract fun <TYPE : PsiType> createMethodReturnTypeSource(psiMethodSource: JavaElementPsiSource<out PsiMethod>): JavaElementTypeSource<TYPE>
|
abstract fun <TYPE : PsiType> createMethodReturnTypeSource(psiMethodSource: JavaElementPsiSource<out PsiMethod>): JavaElementTypeSource<TYPE>
|
||||||
|
|
||||||
|
abstract fun <TYPE : PsiType> createTypeParameterUpperBoundTypeSource(
|
||||||
|
psiTypeParameterSource: JavaElementPsiSource<out PsiTypeParameter>,
|
||||||
|
boundIndex: Int,
|
||||||
|
): JavaElementTypeSource<TYPE>
|
||||||
|
|
||||||
abstract fun <TYPE : PsiType> createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource<out PsiExpression>): JavaElementTypeSource<TYPE>
|
abstract fun <TYPE : PsiType> createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource<out PsiExpression>): JavaElementTypeSource<TYPE>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -38,6 +43,14 @@ class JavaFixedElementSourceFactory : JavaElementSourceFactory() {
|
|||||||
return createTypeSource(psiVariableSource.psi.type as TYPE)
|
return createTypeSource(psiVariableSource.psi.type as TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun <TYPE : PsiType> createTypeParameterUpperBoundTypeSource(
|
||||||
|
psiTypeParameterSource: JavaElementPsiSource<out PsiTypeParameter>,
|
||||||
|
boundIndex: Int
|
||||||
|
): JavaElementTypeSource<TYPE> {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return createTypeSource(psiTypeParameterSource.psi.bounds[boundIndex] as TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun <TYPE : PsiType> createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource<out PsiExpression>): JavaElementTypeSource<TYPE> {
|
override fun <TYPE : PsiType> createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource<out PsiExpression>): JavaElementTypeSource<TYPE> {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
|||||||
Reference in New Issue
Block a user