diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementDelegatingTypeSourceWithSmartPointer.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementDelegatingTypeSourceWithSmartPointer.kt new file mode 100644 index 00000000000..3cb08d5888a --- /dev/null +++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementDelegatingTypeSourceWithSmartPointer.kt @@ -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 : JavaElementTypeSource() { + abstract val psiPointer: SmartPsiElementPointer + 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( + override val psiPointer: SmartPsiElementPointer, + override val factory: JavaElementSourceFactory, +) : JavaElementDelegatingTypeSourceWithSmartPointer() { + + override fun getType(psi: PsiVariable): TYPE { + @Suppress("UNCHECKED_CAST") + return psi.type as TYPE + } +} + +internal class JavaElementDelegatingMethodReturnTypeSourceWithSmartPointer( + override val psiPointer: SmartPsiElementPointer, + override val factory: JavaElementSourceFactory, +) : JavaElementDelegatingTypeSourceWithSmartPointer() { + + override fun getType(psi: PsiMethod): TYPE { + @Suppress("UNCHECKED_CAST") + return psi.returnType as TYPE + } +} +internal class JavaElementDelegatingExpressionTypeSourceWithSmartPointer( + override val psiPointer: SmartPsiElementPointer, + override val factory: JavaElementSourceFactory, +) : JavaElementDelegatingTypeSourceWithSmartPointer() { + + override fun getType(psi: PsiExpression): TYPE { + @Suppress("UNCHECKED_CAST") + return psi.type as TYPE + } +} diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementPsiSourceWithSmartPointer.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementPsiSourceWithSmartPointer.kt index 82c05d58032..d1e5bc4dfda 100644 --- a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementPsiSourceWithSmartPointer.kt +++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementPsiSourceWithSmartPointer.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementPsiSource import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementSourceFactory internal class JavaElementPsiSourceWithSmartPointer( - private val pointer: SmartPsiElementPointer, + val pointer: SmartPsiElementPointer, override val factory: JavaElementSourceFactory, ) : JavaElementPsiSource() { @@ -20,9 +20,5 @@ internal class JavaElementPsiSourceWithSmartPointer( return pointer.element ?: error("Cannot restore a PsiElement from $pointer") } - - override fun toString(): String { - return pointer.element?.toString() ?: "Cannot restore a PsiElement from $pointer" - } } diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementSourceWithSmartPointerFactory.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementSourceWithSmartPointerFactory.kt index 3cfb561e2fe..4aca20cc55a 100644 --- a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementSourceWithSmartPointerFactory.kt +++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/java/source/JavaElementSourceWithSmartPointerFactory.kt @@ -6,15 +6,12 @@ package org.jetbrains.kotlin.analysis.api.impl.base.java.source import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiType -import com.intellij.psi.SmartPointerManager -import com.intellij.psi.SmartTypePointerManager +import com.intellij.psi.* 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.JavaElementTypeSource - class JavaElementSourceWithSmartPointerFactory(project: Project) : JavaElementSourceFactory() { +class JavaElementSourceWithSmartPointerFactory(project: Project) : JavaElementSourceFactory() { private val smartTypePointerManager = SmartTypePointerManager.getInstance(project) private val smartPsiPointerManager = SmartPointerManager.getInstance(project) @@ -25,4 +22,19 @@ import org.jetbrains.kotlin.load.java.structure.impl.source.JavaElementTypeSourc override fun createTypeSource(type: TYPE): JavaElementTypeSource { return JavaElementTypeSourceWithSmartPointer(smartTypePointerManager.createSmartTypePointer(type), this) } + + override fun createVariableReturnTypeSource(psiVariableSource: JavaElementPsiSource): JavaElementTypeSource { + require(psiVariableSource is JavaElementPsiSourceWithSmartPointer) + return JavaElementDelegatingVariableReturnTypeSourceWithSmartPointer(psiVariableSource.pointer, psiVariableSource.factory) + } + + override fun createMethodReturnTypeSource(psiMethodSource: JavaElementPsiSource): JavaElementTypeSource { + require(psiMethodSource is JavaElementPsiSourceWithSmartPointer) + return JavaElementDelegatingMethodReturnTypeSourceWithSmartPointer(psiMethodSource.pointer, psiMethodSource.factory) + } + + override fun createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource): JavaElementTypeSource { + require(psiExpressionSource is JavaElementPsiSourceWithSmartPointer) + return JavaElementDelegatingExpressionTypeSourceWithSmartPointer(psiExpressionSource.pointer, psiExpressionSource.factory) + } } \ No newline at end of file diff --git a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaMethodImpl.java b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaMethodImpl.java index a6d91ae4801..2b6dd2618b8 100644 --- a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaMethodImpl.java +++ b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaMethodImpl.java @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.load.java.structure.impl; import com.intellij.psi.PsiAnnotationMemberValue; import com.intellij.psi.PsiAnnotationMethod; import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; 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 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.valueParameters; @@ -80,8 +80,6 @@ public class JavaMethodImpl extends JavaMemberImpl implements JavaMet @Override @NotNull public JavaType getReturnType() { - PsiType psiType = getPsi().getReturnType(); - assert psiType != null : "Method is not a constructor and has no return type: " + getName(); - return JavaTypeImpl.create(createTypeSource(psiType)); + return JavaTypeImpl.create(Objects.requireNonNull(getPsi().getReturnType()), createMethodReturnTypeSource(psiElementSource)); } } diff --git a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaRecordComponentImpl.kt b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaRecordComponentImpl.kt index 8f6d1215ddf..bfea621a130 100644 --- a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaRecordComponentImpl.kt +++ b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaRecordComponentImpl.kt @@ -14,7 +14,7 @@ class JavaRecordComponentImpl( psiRecordComponentSource: JavaElementPsiSource ) : JavaMemberImpl(psiRecordComponentSource), JavaRecordComponent { override val type: JavaType - get() = JavaTypeImpl.create(sourceFactory.createTypeSource(psiElementSource.psi.type)) + get() = JavaTypeImpl.create(psi.type, sourceFactory.createVariableReturnTypeSource(psiElementSource)) override val isVararg: Boolean get() = psi.isVarArgs diff --git a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaTypeImpl.java b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaTypeImpl.java index 60af68429dd..c737efce38c 100644 --- a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaTypeImpl.java +++ b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaTypeImpl.java @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.load.java.structure.impl.source.JavaSourceFactoryOwn import org.jetbrains.kotlin.name.FqName; import java.util.Collection; +import java.util.function.Function; public abstract class JavaTypeImpl implements JavaType, JavaAnnotationOwnerImpl, JavaSourceFactoryOwner { private final JavaElementTypeSource psiType; @@ -54,9 +55,13 @@ public abstract class JavaTypeImpl implements JavaType, Jav } @NotNull - public static JavaTypeImpl create(@NotNull JavaElementTypeSource psiTypeSource) { - JavaElementSourceFactory sourceFactory = psiTypeSource.getFactory(); - return psiTypeSource.getType().accept(new PsiTypeVisitor>() { + public static JavaTypeImpl create(JavaElementTypeSource psiTypeSource) { + return create(psiTypeSource.getType(), psiTypeSource); + } + + @NotNull + public static JavaTypeImpl create(@NotNull PsiType psiType, JavaElementTypeSource psiTypeSource) { + return psiType.accept(new PsiTypeVisitor>() { @Nullable @Override @@ -66,26 +71,30 @@ public abstract class JavaTypeImpl implements JavaType, Jav @Nullable @Override + @SuppressWarnings("unchecked") public JavaTypeImpl visitPrimitiveType(@NotNull PsiPrimitiveType primitiveType) { - return new JavaPrimitiveTypeImpl(sourceFactory.createTypeSource(primitiveType)); + return new JavaPrimitiveTypeImpl((JavaElementTypeSource)psiTypeSource ); } @Nullable @Override + @SuppressWarnings("unchecked") public JavaTypeImpl visitArrayType(@NotNull PsiArrayType arrayType) { - return new JavaArrayTypeImpl(sourceFactory.createTypeSource(arrayType)); + return new JavaArrayTypeImpl((JavaElementTypeSource) psiTypeSource); } @Nullable @Override + @SuppressWarnings("unchecked") public JavaTypeImpl visitClassType(@NotNull PsiClassType classType) { - return new JavaClassifierTypeImpl(sourceFactory.createTypeSource(classType)); + return new JavaClassifierTypeImpl((JavaElementTypeSource) psiTypeSource); } @Nullable @Override + @SuppressWarnings("unchecked") public JavaTypeImpl visitWildcardType(@NotNull PsiWildcardType wildcardType) { - return new JavaWildcardTypeImpl(sourceFactory.createTypeSource(wildcardType)); + return new JavaWildcardTypeImpl((JavaElementTypeSource) psiTypeSource); } }); } diff --git a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaValueParameterImpl.java b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaValueParameterImpl.java index f2526edbff6..cf48617b169 100644 --- a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaValueParameterImpl.java +++ b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/JavaValueParameterImpl.java @@ -102,7 +102,7 @@ public class JavaValueParameterImpl extends JavaElementImpl @Override @NotNull public JavaType getType() { - return JavaTypeImpl.create(createTypeSource(getPsi().getType())); + return JavaTypeImpl.create(getPsi().getType(), createVariableReturnTypeSource(psiElementSource)); } @Override diff --git a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/source/JavaElementSourceFactory.kt b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/source/JavaElementSourceFactory.kt index a71b69c8091..a2a951407a2 100644 --- a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/source/JavaElementSourceFactory.kt +++ b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/source/JavaElementSourceFactory.kt @@ -6,12 +6,15 @@ package org.jetbrains.kotlin.load.java.structure.impl.source import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiType +import com.intellij.psi.* abstract class JavaElementSourceFactory { abstract fun createPsiSource(psi: PSI): JavaElementPsiSource abstract fun createTypeSource(type: TYPE): JavaElementTypeSource + abstract fun createVariableReturnTypeSource(psiVariableSource: JavaElementPsiSource): JavaElementTypeSource + abstract fun createMethodReturnTypeSource(psiMethodSource: JavaElementPsiSource): JavaElementTypeSource + + abstract fun createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource): JavaElementTypeSource companion object { @JvmStatic @@ -29,4 +32,22 @@ class JavaFixedElementSourceFactory : JavaElementSourceFactory() { override fun createTypeSource(type: TYPE): JavaElementTypeSource { return JavaElementTypeSourceWithFixedType(type, this) } + + override fun createVariableReturnTypeSource(psiVariableSource: JavaElementPsiSource): JavaElementTypeSource { + @Suppress("UNCHECKED_CAST") + return createTypeSource(psiVariableSource.psi.type as TYPE) + } + + + override fun createExpressionTypeSource(psiExpressionSource: JavaElementPsiSource): JavaElementTypeSource { + @Suppress("UNCHECKED_CAST") + return createTypeSource(psiExpressionSource.psi.type as TYPE) + } + + override fun createMethodReturnTypeSource(psiMethodSource: JavaElementPsiSource): JavaElementTypeSource { + 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) + } } diff --git a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/source/JavaSourceFactoryOwner.kt b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/source/JavaSourceFactoryOwner.kt index 1615eaf87ab..4f7f8b96a40 100644 --- a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/source/JavaSourceFactoryOwner.kt +++ b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/load/java/structure/impl/source/JavaSourceFactoryOwner.kt @@ -6,7 +6,9 @@ package org.jetbrains.kotlin.load.java.structure.impl.source import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod import com.intellij.psi.PsiType +import com.intellij.psi.PsiVariable interface JavaSourceFactoryOwner { val sourceFactory: JavaElementSourceFactory @@ -18,4 +20,13 @@ interface JavaSourceFactoryOwner { fun createTypeSource(type: TYPE): JavaElementTypeSource { return sourceFactory.createTypeSource(type) } + + fun createVariableReturnTypeSource(psiVariableSource: JavaElementPsiSource): JavaElementTypeSource { + return sourceFactory.createVariableReturnTypeSource(psiVariableSource) + } + + fun createMethodReturnTypeSource(psiMethodSource: JavaElementPsiSource): JavaElementTypeSource { + return sourceFactory.createMethodReturnTypeSource(psiMethodSource) + } + } \ No newline at end of file