[LL FIR] fix contract violation exception from Java Resolution
When we create `SmartTypePointer` directly inside `JavaSymbolProvider`, the Java resolution is called which is forbidden inside the `JavaSymbolProvider`. Instead, the lazy `JavaElementTypeSource` for JavaType is created, which creates a `SmartTypePointer` outside `JavaSymbolProvider`. ^KT-58194
This commit is contained in:
committed by
Space Team
parent
2d08d29dac
commit
9829a2bf98
+49
@@ -0,0 +1,49 @@
|
|||||||
|
package org.jetbrains.kotlin.analysis.api.impl.base.java.source
|
||||||
|
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementSourceFactory
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementTypeSource
|
||||||
|
|
||||||
|
internal abstract class JavaElementDelegatingTypeSourceWithSmartPointer<PSI : PsiElement, TYPE : PsiType> : JavaElementTypeSource<TYPE>() {
|
||||||
|
abstract val psiPointer: SmartPsiElementPointer<out PSI>
|
||||||
|
abstract fun getType(psi: PSI): TYPE
|
||||||
|
|
||||||
|
override val type: TYPE
|
||||||
|
get() {
|
||||||
|
val psi = psiPointer.element
|
||||||
|
?: error("Cannot restore $psiPointer")
|
||||||
|
return getType(psi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class JavaElementDelegatingVariableReturnTypeSourceWithSmartPointer<TYPE : PsiType>(
|
||||||
|
override val psiPointer: SmartPsiElementPointer<out PsiVariable>,
|
||||||
|
override val factory: JavaElementSourceFactory,
|
||||||
|
) : JavaElementDelegatingTypeSourceWithSmartPointer<PsiVariable, TYPE>() {
|
||||||
|
|
||||||
|
override fun getType(psi: PsiVariable): TYPE {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return psi.type as TYPE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class JavaElementDelegatingMethodReturnTypeSourceWithSmartPointer<TYPE : PsiType>(
|
||||||
|
override val psiPointer: SmartPsiElementPointer<out PsiMethod>,
|
||||||
|
override val factory: JavaElementSourceFactory,
|
||||||
|
) : JavaElementDelegatingTypeSourceWithSmartPointer<PsiMethod, TYPE>() {
|
||||||
|
|
||||||
|
override fun getType(psi: PsiMethod): TYPE {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return psi.returnType as TYPE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal class JavaElementDelegatingExpressionTypeSourceWithSmartPointer<TYPE : PsiType>(
|
||||||
|
override val psiPointer: SmartPsiElementPointer<out PsiExpression>,
|
||||||
|
override val factory: JavaElementSourceFactory,
|
||||||
|
) : JavaElementDelegatingTypeSourceWithSmartPointer<PsiExpression, TYPE>() {
|
||||||
|
|
||||||
|
override fun getType(psi: PsiExpression): TYPE {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return psi.type as TYPE
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-5
@@ -11,7 +11,7 @@ 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
|
||||||
|
|
||||||
internal class JavaElementPsiSourceWithSmartPointer<PSI : PsiElement>(
|
internal class JavaElementPsiSourceWithSmartPointer<PSI : PsiElement>(
|
||||||
private val pointer: SmartPsiElementPointer<PSI>,
|
val pointer: SmartPsiElementPointer<PSI>,
|
||||||
override val factory: JavaElementSourceFactory,
|
override val factory: JavaElementSourceFactory,
|
||||||
) : JavaElementPsiSource<PSI>() {
|
) : JavaElementPsiSource<PSI>() {
|
||||||
|
|
||||||
@@ -20,9 +20,5 @@ internal class JavaElementPsiSourceWithSmartPointer<PSI : PsiElement>(
|
|||||||
return pointer.element
|
return pointer.element
|
||||||
?: error("Cannot restore a PsiElement from $pointer")
|
?: error("Cannot restore a PsiElement from $pointer")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
return pointer.element?.toString() ?: "Cannot restore a PsiElement from $pointer"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-5
@@ -6,15 +6,12 @@
|
|||||||
package org.jetbrains.kotlin.analysis.api.impl.base.java.source
|
package org.jetbrains.kotlin.analysis.api.impl.base.java.source
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiType
|
|
||||||
import com.intellij.psi.SmartPointerManager
|
|
||||||
import com.intellij.psi.SmartTypePointerManager
|
|
||||||
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.load.java.structure.impl.source.JavaElementTypeSource
|
||||||
|
|
||||||
class JavaElementSourceWithSmartPointerFactory(project: Project) : JavaElementSourceFactory() {
|
class JavaElementSourceWithSmartPointerFactory(project: Project) : JavaElementSourceFactory() {
|
||||||
private val smartTypePointerManager = SmartTypePointerManager.getInstance(project)
|
private val smartTypePointerManager = SmartTypePointerManager.getInstance(project)
|
||||||
private val smartPsiPointerManager = SmartPointerManager.getInstance(project)
|
private val smartPsiPointerManager = SmartPointerManager.getInstance(project)
|
||||||
|
|
||||||
@@ -25,4 +22,19 @@ import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementTypeSourc
|
|||||||
override fun <TYPE : PsiType> createTypeSource(type: TYPE): JavaElementTypeSource<TYPE> {
|
override fun <TYPE : PsiType> createTypeSource(type: TYPE): JavaElementTypeSource<TYPE> {
|
||||||
return JavaElementTypeSourceWithSmartPointer(smartTypePointerManager.createSmartTypePointer(type), this)
|
return JavaElementTypeSourceWithSmartPointer(smartTypePointerManager.createSmartTypePointer(type), this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun <TYPE : PsiType> createVariableReturnTypeSource(psiVariableSource: JavaElementPsiSource<out PsiVariable>): JavaElementTypeSource<TYPE> {
|
||||||
|
require(psiVariableSource is JavaElementPsiSourceWithSmartPointer)
|
||||||
|
return JavaElementDelegatingVariableReturnTypeSourceWithSmartPointer(psiVariableSource.pointer, psiVariableSource.factory)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <TYPE : PsiType> createMethodReturnTypeSource(psiMethodSource: JavaElementPsiSource<out PsiMethod>): JavaElementTypeSource<TYPE> {
|
||||||
|
require(psiMethodSource is JavaElementPsiSourceWithSmartPointer)
|
||||||
|
return JavaElementDelegatingMethodReturnTypeSourceWithSmartPointer(psiMethodSource.pointer, psiMethodSource.factory)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <TYPE : PsiType> createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource<out PsiExpression>): JavaElementTypeSource<TYPE> {
|
||||||
|
require(psiExpressionSource is JavaElementPsiSourceWithSmartPointer)
|
||||||
|
return JavaElementDelegatingExpressionTypeSourceWithSmartPointer(psiExpressionSource.pointer, psiExpressionSource.factory)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+2
-4
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.load.java.structure.impl;
|
|||||||
import com.intellij.psi.PsiAnnotationMemberValue;
|
import com.intellij.psi.PsiAnnotationMemberValue;
|
||||||
import com.intellij.psi.PsiAnnotationMethod;
|
import com.intellij.psi.PsiAnnotationMethod;
|
||||||
import com.intellij.psi.PsiMethod;
|
import com.intellij.psi.PsiMethod;
|
||||||
import com.intellij.psi.PsiType;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.load.java.structure.*;
|
import org.jetbrains.kotlin.load.java.structure.*;
|
||||||
@@ -27,6 +26,7 @@ import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementPsiSource
|
|||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.load.java.structure.impl.JavaElementCollectionFromPsiArrayUtil.typeParameters;
|
import static org.jetbrains.kotlin.load.java.structure.impl.JavaElementCollectionFromPsiArrayUtil.typeParameters;
|
||||||
import static org.jetbrains.kotlin.load.java.structure.impl.JavaElementCollectionFromPsiArrayUtil.valueParameters;
|
import static org.jetbrains.kotlin.load.java.structure.impl.JavaElementCollectionFromPsiArrayUtil.valueParameters;
|
||||||
@@ -80,8 +80,6 @@ public class JavaMethodImpl extends JavaMemberImpl<PsiMethod> implements JavaMet
|
|||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public JavaType getReturnType() {
|
public JavaType getReturnType() {
|
||||||
PsiType psiType = getPsi().getReturnType();
|
return JavaTypeImpl.create(Objects.requireNonNull(getPsi().getReturnType()), createMethodReturnTypeSource(psiElementSource));
|
||||||
assert psiType != null : "Method is not a constructor and has no return type: " + getName();
|
|
||||||
return JavaTypeImpl.create(createTypeSource(psiType));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ class JavaRecordComponentImpl(
|
|||||||
psiRecordComponentSource: JavaElementPsiSource<PsiRecordComponent>
|
psiRecordComponentSource: JavaElementPsiSource<PsiRecordComponent>
|
||||||
) : JavaMemberImpl<PsiRecordComponent>(psiRecordComponentSource), JavaRecordComponent {
|
) : JavaMemberImpl<PsiRecordComponent>(psiRecordComponentSource), JavaRecordComponent {
|
||||||
override val type: JavaType
|
override val type: JavaType
|
||||||
get() = JavaTypeImpl.create(sourceFactory.createTypeSource(psiElementSource.psi.type))
|
get() = JavaTypeImpl.create(psi.type, sourceFactory.createVariableReturnTypeSource(psiElementSource))
|
||||||
|
|
||||||
override val isVararg: Boolean
|
override val isVararg: Boolean
|
||||||
get() = psi.isVarArgs
|
get() = psi.isVarArgs
|
||||||
|
|||||||
+16
-7
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.load.java.structure.impl.source.JavaSourceFactoryOwn
|
|||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public abstract class JavaTypeImpl<Psi extends PsiType> implements JavaType, JavaAnnotationOwnerImpl, JavaSourceFactoryOwner {
|
public abstract class JavaTypeImpl<Psi extends PsiType> implements JavaType, JavaAnnotationOwnerImpl, JavaSourceFactoryOwner {
|
||||||
private final JavaElementTypeSource<Psi> psiType;
|
private final JavaElementTypeSource<Psi> psiType;
|
||||||
@@ -54,9 +55,13 @@ public abstract class JavaTypeImpl<Psi extends PsiType> implements JavaType, Jav
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JavaTypeImpl<?> create(@NotNull JavaElementTypeSource<PsiType> psiTypeSource) {
|
public static JavaTypeImpl<?> create(JavaElementTypeSource<? extends PsiType> psiTypeSource) {
|
||||||
JavaElementSourceFactory sourceFactory = psiTypeSource.getFactory();
|
return create(psiTypeSource.getType(), psiTypeSource);
|
||||||
return psiTypeSource.getType().accept(new PsiTypeVisitor<JavaTypeImpl<?>>() {
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JavaTypeImpl<?> create(@NotNull PsiType psiType, JavaElementTypeSource<? extends PsiType> psiTypeSource) {
|
||||||
|
return psiType.accept(new PsiTypeVisitor<JavaTypeImpl<?>>() {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
@@ -66,26 +71,30 @@ public abstract class JavaTypeImpl<Psi extends PsiType> implements JavaType, Jav
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public JavaTypeImpl<?> visitPrimitiveType(@NotNull PsiPrimitiveType primitiveType) {
|
public JavaTypeImpl<?> visitPrimitiveType(@NotNull PsiPrimitiveType primitiveType) {
|
||||||
return new JavaPrimitiveTypeImpl(sourceFactory.createTypeSource(primitiveType));
|
return new JavaPrimitiveTypeImpl((JavaElementTypeSource<PsiPrimitiveType>)psiTypeSource );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public JavaTypeImpl<?> visitArrayType(@NotNull PsiArrayType arrayType) {
|
public JavaTypeImpl<?> visitArrayType(@NotNull PsiArrayType arrayType) {
|
||||||
return new JavaArrayTypeImpl(sourceFactory.createTypeSource(arrayType));
|
return new JavaArrayTypeImpl((JavaElementTypeSource<PsiArrayType>) psiTypeSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public JavaTypeImpl<?> visitClassType(@NotNull PsiClassType classType) {
|
public JavaTypeImpl<?> visitClassType(@NotNull PsiClassType classType) {
|
||||||
return new JavaClassifierTypeImpl(sourceFactory.createTypeSource(classType));
|
return new JavaClassifierTypeImpl((JavaElementTypeSource<PsiClassType>) psiTypeSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public JavaTypeImpl<?> visitWildcardType(@NotNull PsiWildcardType wildcardType) {
|
public JavaTypeImpl<?> visitWildcardType(@NotNull PsiWildcardType wildcardType) {
|
||||||
return new JavaWildcardTypeImpl(sourceFactory.createTypeSource(wildcardType));
|
return new JavaWildcardTypeImpl((JavaElementTypeSource<PsiWildcardType>) psiTypeSource);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ public class JavaValueParameterImpl extends JavaElementImpl<PsiParameter>
|
|||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public JavaType getType() {
|
public JavaType getType() {
|
||||||
return JavaTypeImpl.create(createTypeSource(getPsi().getType()));
|
return JavaTypeImpl.create(getPsi().getType(), createVariableReturnTypeSource(psiElementSource));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+23
-2
@@ -6,12 +6,15 @@
|
|||||||
package org.jetbrains.kotlin.load.java.structure.impl.source
|
package org.jetbrains.kotlin.load.java.structure.impl.source
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiType
|
|
||||||
|
|
||||||
abstract class JavaElementSourceFactory {
|
abstract class JavaElementSourceFactory {
|
||||||
abstract fun <PSI : PsiElement> createPsiSource(psi: PSI): JavaElementPsiSource<PSI>
|
abstract fun <PSI : PsiElement> createPsiSource(psi: PSI): JavaElementPsiSource<PSI>
|
||||||
abstract fun <TYPE : PsiType> createTypeSource(type: TYPE): JavaElementTypeSource<TYPE>
|
abstract fun <TYPE : PsiType> createTypeSource(type: TYPE): 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> createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource<out PsiExpression>): JavaElementTypeSource<TYPE>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -29,4 +32,22 @@ class JavaFixedElementSourceFactory : JavaElementSourceFactory() {
|
|||||||
override fun <TYPE : PsiType> createTypeSource(type: TYPE): JavaElementTypeSource<TYPE> {
|
override fun <TYPE : PsiType> createTypeSource(type: TYPE): JavaElementTypeSource<TYPE> {
|
||||||
return JavaElementTypeSourceWithFixedType(type, this)
|
return JavaElementTypeSourceWithFixedType(type, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun <TYPE : PsiType> createVariableReturnTypeSource(psiVariableSource: JavaElementPsiSource<out PsiVariable>): JavaElementTypeSource<TYPE> {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return createTypeSource(psiVariableSource.psi.type as TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun <TYPE : PsiType> createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource<out PsiExpression>): JavaElementTypeSource<TYPE> {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return createTypeSource(psiExpressionSource.psi.type as TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <TYPE : PsiType> createMethodReturnTypeSource(psiMethodSource: JavaElementPsiSource<out PsiMethod>): JavaElementTypeSource<TYPE> {
|
||||||
|
val psiType: PsiType = psiMethodSource.psi.returnType
|
||||||
|
?: error("Method is not a constructor and has no return type: " + psiMethodSource.psi.name)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return createTypeSource(psiType as TYPE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -6,7 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.load.java.structure.impl.source
|
package org.jetbrains.kotlin.load.java.structure.impl.source
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
import com.intellij.psi.PsiType
|
import com.intellij.psi.PsiType
|
||||||
|
import com.intellij.psi.PsiVariable
|
||||||
|
|
||||||
interface JavaSourceFactoryOwner {
|
interface JavaSourceFactoryOwner {
|
||||||
val sourceFactory: JavaElementSourceFactory
|
val sourceFactory: JavaElementSourceFactory
|
||||||
@@ -18,4 +20,13 @@ interface JavaSourceFactoryOwner {
|
|||||||
fun <TYPE : PsiType> createTypeSource(type: TYPE): JavaElementTypeSource<TYPE> {
|
fun <TYPE : PsiType> createTypeSource(type: TYPE): JavaElementTypeSource<TYPE> {
|
||||||
return sourceFactory.createTypeSource(type)
|
return sourceFactory.createTypeSource(type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <TYPE : PsiType> createVariableReturnTypeSource(psiVariableSource: JavaElementPsiSource<out PsiVariable>): JavaElementTypeSource<TYPE> {
|
||||||
|
return sourceFactory.createVariableReturnTypeSource(psiVariableSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <TYPE : PsiType> createMethodReturnTypeSource(psiMethodSource: JavaElementPsiSource<out PsiMethod>): JavaElementTypeSource<TYPE> {
|
||||||
|
return sourceFactory.createMethodReturnTypeSource(psiMethodSource)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user