AA: handle erroneous type in nested type argument

This commit is contained in:
Jinseong Jeon
2022-11-10 22:50:08 -08:00
committed by Ilya Kirillov
parent ac514849f4
commit fcba1f215a
9 changed files with 57 additions and 15 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.load.kotlin.getOptimalModeForReturnType
import org.jetbrains.kotlin.load.kotlin.getOptimalModeForValueParameter
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
import java.text.StringCharacterIterator
internal class KtFe10PsiTypeProvider(
@@ -43,8 +44,10 @@ internal class KtFe10PsiTypeProvider(
): PsiType? {
val kotlinType = (type as KtFe10Type).type
if (kotlinType.isError || kotlinType.arguments.any { !it.isStarProjection && it.type.isError }) {
return null
with(typeMapper.typeContext) {
if (kotlinType.contains { it.isError() }) {
return null
}
}
return asPsiType(simplifyType(kotlinType), useSitePosition, mode.toTypeMappingMode(type, isAnnotationMethod))
@@ -79,6 +82,8 @@ internal class KtFe10PsiTypeProvider(
}
private fun asPsiType(type: KotlinType, useSitePosition: PsiElement, mode: TypeMappingMode): PsiType? {
if (type !is SimpleTypeMarker) return null
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.SKIP_CHECKS)
typeMapper.mapType(type, mode, signatureWriter)
@@ -64,6 +64,12 @@ public class Fe10IdeNormalAnalysisSourceModuleAnalysisApiPsiTypeProviderTestGene
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/anonymousObject_exposedAsReturnValue.kt");
}
@Test
@TestMetadata("errorTypeInNestedTypeArgument.kt")
public void testErrorTypeInNestedTypeArgument() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/errorTypeInNestedTypeArgument.kt");
}
@Test
@TestMetadata("localClass_exposedAsReturnValue.kt")
public void testLocalClass_exposedAsReturnValue() throws Exception {
@@ -53,12 +53,18 @@ internal class KtFirPsiTypeProvider(
useSitePosition: PsiElement,
mode: KtTypeMappingMode,
isAnnotationMethod: Boolean,
): PsiType? = type.coneType.asPsiType(
rootModuleSession,
mode.toTypeMappingMode(type, isAnnotationMethod),
useSitePosition
)
): PsiType? {
val coneType = type.coneType
with(rootModuleSession.typeContext) {
if (coneType.contains { it.isError() }) {
return null
}
}
return coneType.simplifyType(rootModuleSession, useSitePosition)
.asPsiType(rootModuleSession, mode.toTypeMappingMode(type, isAnnotationMethod), useSitePosition)
}
private fun KtTypeMappingMode.toTypeMappingMode(type: KtType, isAnnotationMethod: Boolean): TypeMappingMode {
require(type is KtFirType)
@@ -174,21 +180,17 @@ private fun ConeKotlinType.isLocalButAvailableAtPosition(
context.parents.any { it == localPsi }
}
internal fun ConeKotlinType.asPsiType(
private fun ConeKotlinType.asPsiType(
session: FirSession,
mode: TypeMappingMode,
useSitePosition: PsiElement,
): PsiType? {
val correctedType = simplifyType(session, useSitePosition)
if (correctedType is ConeErrorType || correctedType !is SimpleTypeMarker) return null
if (correctedType.typeArguments.any { it is ConeErrorType }) return null
if (this !is SimpleTypeMarker) return null
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.SKIP_CHECKS)
//TODO Check thread safety
session.jvmTypeMapper.mapType(correctedType, mode, signatureWriter)
session.jvmTypeMapper.mapType(this, mode, signatureWriter)
val canonicalSignature = signatureWriter.toString()
require(!canonicalSignature.contains(SpecialNames.ANONYMOUS_STRING))
@@ -64,6 +64,12 @@ public class FirIdeDependentAnalysisSourceModuleAnalysisApiPsiTypeProviderTestGe
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/anonymousObject_exposedAsReturnValue.kt");
}
@Test
@TestMetadata("errorTypeInNestedTypeArgument.kt")
public void testErrorTypeInNestedTypeArgument() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/errorTypeInNestedTypeArgument.kt");
}
@Test
@TestMetadata("localClass_exposedAsReturnValue.kt")
public void testLocalClass_exposedAsReturnValue() throws Exception {
@@ -64,6 +64,12 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiPsiTypeProviderTestGener
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/anonymousObject_exposedAsReturnValue.kt");
}
@Test
@TestMetadata("errorTypeInNestedTypeArgument.kt")
public void testErrorTypeInNestedTypeArgument() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/errorTypeInNestedTypeArgument.kt");
}
@Test
@TestMetadata("localClass_exposedAsReturnValue.kt")
public void testLocalClass_exposedAsReturnValue() throws Exception {
@@ -64,6 +64,12 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiPsiTypeProviderTe
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/anonymousObject_exposedAsReturnValue.kt");
}
@Test
@TestMetadata("errorTypeInNestedTypeArgument.kt")
public void testErrorTypeInNestedTypeArgument() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/errorTypeInNestedTypeArgument.kt");
}
@Test
@TestMetadata("localClass_exposedAsReturnValue.kt")
public void testLocalClass_exposedAsReturnValue() throws Exception {
@@ -0,0 +1,9 @@
class A<T>
class B<T1, T2>
class C {
fun foo<caret>() = object : B<String, A<Unknown>> {
}
}
@@ -0,0 +1,2 @@
KtType: B<kotlin.String, A<Unknown>>
PsiType: null
@@ -362,7 +362,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
* - type for type parameter
* - captured type
*
* Such types can contains error types in our arguments, but type constructor isn't errorTypeConstructor
* Such types can contain error types in our arguments, but type constructor isn't errorTypeConstructor
*/
override fun SimpleTypeMarker.isSingleClassifierType(): Boolean {
require(this is SimpleType, this::errorMessage)