AA: handle erroneous type in nested type argument
This commit is contained in:
committed by
Ilya Kirillov
parent
ac514849f4
commit
fcba1f215a
+7
-2
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.load.kotlin.getOptimalModeForReturnType
|
|||||||
import org.jetbrains.kotlin.load.kotlin.getOptimalModeForValueParameter
|
import org.jetbrains.kotlin.load.kotlin.getOptimalModeForValueParameter
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||||
import java.text.StringCharacterIterator
|
import java.text.StringCharacterIterator
|
||||||
|
|
||||||
internal class KtFe10PsiTypeProvider(
|
internal class KtFe10PsiTypeProvider(
|
||||||
@@ -43,8 +44,10 @@ internal class KtFe10PsiTypeProvider(
|
|||||||
): PsiType? {
|
): PsiType? {
|
||||||
val kotlinType = (type as KtFe10Type).type
|
val kotlinType = (type as KtFe10Type).type
|
||||||
|
|
||||||
if (kotlinType.isError || kotlinType.arguments.any { !it.isStarProjection && it.type.isError }) {
|
with(typeMapper.typeContext) {
|
||||||
return null
|
if (kotlinType.contains { it.isError() }) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return asPsiType(simplifyType(kotlinType), useSitePosition, mode.toTypeMappingMode(type, isAnnotationMethod))
|
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? {
|
private fun asPsiType(type: KotlinType, useSitePosition: PsiElement, mode: TypeMappingMode): PsiType? {
|
||||||
|
if (type !is SimpleTypeMarker) return null
|
||||||
|
|
||||||
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.SKIP_CHECKS)
|
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.SKIP_CHECKS)
|
||||||
typeMapper.mapType(type, mode, signatureWriter)
|
typeMapper.mapType(type, mode, signatureWriter)
|
||||||
|
|
||||||
|
|||||||
+6
@@ -64,6 +64,12 @@ public class Fe10IdeNormalAnalysisSourceModuleAnalysisApiPsiTypeProviderTestGene
|
|||||||
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/anonymousObject_exposedAsReturnValue.kt");
|
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
|
@Test
|
||||||
@TestMetadata("localClass_exposedAsReturnValue.kt")
|
@TestMetadata("localClass_exposedAsReturnValue.kt")
|
||||||
public void testLocalClass_exposedAsReturnValue() throws Exception {
|
public void testLocalClass_exposedAsReturnValue() throws Exception {
|
||||||
|
|||||||
+14
-12
@@ -53,12 +53,18 @@ internal class KtFirPsiTypeProvider(
|
|||||||
useSitePosition: PsiElement,
|
useSitePosition: PsiElement,
|
||||||
mode: KtTypeMappingMode,
|
mode: KtTypeMappingMode,
|
||||||
isAnnotationMethod: Boolean,
|
isAnnotationMethod: Boolean,
|
||||||
): PsiType? = type.coneType.asPsiType(
|
): PsiType? {
|
||||||
rootModuleSession,
|
val coneType = type.coneType
|
||||||
mode.toTypeMappingMode(type, isAnnotationMethod),
|
|
||||||
useSitePosition
|
|
||||||
)
|
|
||||||
|
|
||||||
|
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 {
|
private fun KtTypeMappingMode.toTypeMappingMode(type: KtType, isAnnotationMethod: Boolean): TypeMappingMode {
|
||||||
require(type is KtFirType)
|
require(type is KtFirType)
|
||||||
@@ -174,21 +180,17 @@ private fun ConeKotlinType.isLocalButAvailableAtPosition(
|
|||||||
context.parents.any { it == localPsi }
|
context.parents.any { it == localPsi }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ConeKotlinType.asPsiType(
|
private fun ConeKotlinType.asPsiType(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
mode: TypeMappingMode,
|
mode: TypeMappingMode,
|
||||||
useSitePosition: PsiElement,
|
useSitePosition: PsiElement,
|
||||||
): PsiType? {
|
): PsiType? {
|
||||||
val correctedType = simplifyType(session, useSitePosition)
|
if (this !is SimpleTypeMarker) return null
|
||||||
|
|
||||||
if (correctedType is ConeErrorType || correctedType !is SimpleTypeMarker) return null
|
|
||||||
|
|
||||||
if (correctedType.typeArguments.any { it is ConeErrorType }) return null
|
|
||||||
|
|
||||||
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.SKIP_CHECKS)
|
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.SKIP_CHECKS)
|
||||||
|
|
||||||
//TODO Check thread safety
|
//TODO Check thread safety
|
||||||
session.jvmTypeMapper.mapType(correctedType, mode, signatureWriter)
|
session.jvmTypeMapper.mapType(this, mode, signatureWriter)
|
||||||
|
|
||||||
val canonicalSignature = signatureWriter.toString()
|
val canonicalSignature = signatureWriter.toString()
|
||||||
require(!canonicalSignature.contains(SpecialNames.ANONYMOUS_STRING))
|
require(!canonicalSignature.contains(SpecialNames.ANONYMOUS_STRING))
|
||||||
|
|||||||
+6
@@ -64,6 +64,12 @@ public class FirIdeDependentAnalysisSourceModuleAnalysisApiPsiTypeProviderTestGe
|
|||||||
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/anonymousObject_exposedAsReturnValue.kt");
|
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
|
@Test
|
||||||
@TestMetadata("localClass_exposedAsReturnValue.kt")
|
@TestMetadata("localClass_exposedAsReturnValue.kt")
|
||||||
public void testLocalClass_exposedAsReturnValue() throws Exception {
|
public void testLocalClass_exposedAsReturnValue() throws Exception {
|
||||||
|
|||||||
+6
@@ -64,6 +64,12 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiPsiTypeProviderTestGener
|
|||||||
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/anonymousObject_exposedAsReturnValue.kt");
|
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
|
@Test
|
||||||
@TestMetadata("localClass_exposedAsReturnValue.kt")
|
@TestMetadata("localClass_exposedAsReturnValue.kt")
|
||||||
public void testLocalClass_exposedAsReturnValue() throws Exception {
|
public void testLocalClass_exposedAsReturnValue() throws Exception {
|
||||||
|
|||||||
+6
@@ -64,6 +64,12 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiPsiTypeProviderTe
|
|||||||
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forDeclaration/anonymousObject_exposedAsReturnValue.kt");
|
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
|
@Test
|
||||||
@TestMetadata("localClass_exposedAsReturnValue.kt")
|
@TestMetadata("localClass_exposedAsReturnValue.kt")
|
||||||
public void testLocalClass_exposedAsReturnValue() throws Exception {
|
public void testLocalClass_exposedAsReturnValue() throws Exception {
|
||||||
|
|||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class A<T>
|
||||||
|
|
||||||
|
class B<T1, T2>
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo<caret>() = object : B<String, A<Unknown>> {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
KtType: B<kotlin.String, A<Unknown>>
|
||||||
|
PsiType: null
|
||||||
@@ -362,7 +362,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
* - type for type parameter
|
* - type for type parameter
|
||||||
* - captured type
|
* - 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 {
|
override fun SimpleTypeMarker.isSingleClassifierType(): Boolean {
|
||||||
require(this is SimpleType, this::errorMessage)
|
require(this is SimpleType, this::errorMessage)
|
||||||
|
|||||||
Reference in New Issue
Block a user