[FIR] Support when exhaustiveness for java enum

The problem appear because for java enum its entries was represented by
FirJavaField. To fix this FirEnumEntry was used

#KT-39621 Fixed
This commit is contained in:
Ivan Kylchik
2020-07-08 19:44:01 +03:00
parent 307871a050
commit dcae6f1415
17 changed files with 247 additions and 92 deletions
@@ -11,16 +11,10 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.addDefaultBoundIfNecessary
import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParameterBuilder
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructedClassTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.builder.buildOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.generateValueOfFunction
import org.jetbrains.kotlin.fir.generateValuesFunction
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.java.declarations.*
import org.jetbrains.kotlin.fir.resolve.constructType
import org.jetbrains.kotlin.fir.resolve.providers.AbstractFirSymbolProvider
@@ -30,7 +24,6 @@ import org.jetbrains.kotlin.fir.scopes.impl.lazyNestedClassifierScope
import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.toFirPsiSourceElement
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.load.java.JavaClassFinder
@@ -191,22 +184,39 @@ class JavaSymbolProvider(
for (javaField in javaClass.fields) {
val fieldName = javaField.name
val fieldId = CallableId(classId.packageFqName, classId.relativeClassName, fieldName)
val fieldSymbol = FirFieldSymbol(fieldId)
val returnType = javaField.type
val firJavaField = buildJavaField {
source = (javaField as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
session = this@JavaSymbolProvider.session
symbol = fieldSymbol
name = fieldName
visibility = javaField.visibility
modality = javaField.modality
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
isVar = !javaField.isFinal
isStatic = javaField.isStatic
isEnumEntry = javaField.isEnumEntry
addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack)
val firJavaDeclaration = when {
javaField.isEnumEntry -> buildEnumEntry {
source = (javaField as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
session = this@JavaSymbolProvider.session
symbol = FirVariableSymbol(fieldId)
name = fieldName
status = FirDeclarationStatusImpl(javaField.visibility, javaField.modality).apply {
isStatic = javaField.isStatic
isExpect = false
isActual = false
isOverride = false
}
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
origin = FirDeclarationOrigin.Java
addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack)
}
else -> buildJavaField {
source = (javaField as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
session = this@JavaSymbolProvider.session
symbol = FirFieldSymbol(fieldId)
name = fieldName
visibility = javaField.visibility
modality = javaField.modality
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
isVar = !javaField.isFinal
isStatic = javaField.isStatic
isEnumEntry = javaField.isEnumEntry
addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack)
}
}
declarations += firJavaField
declarations += firJavaDeclaration
}
for (javaMethod in javaClass.methods) {
val methodName = javaMethod.name
@@ -69,21 +69,22 @@ class FirSignatureEnhancement(
name: Name
): FirVariableSymbol<*> {
when (val firElement = original.fir) {
is FirField -> {
is FirEnumEntry -> {
if (firElement.returnTypeRef !is FirJavaTypeRef) return original
val memberContext = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, firElement.annotations)
val isEnumEntry = (firElement as? FirJavaField)?.isEnumEntry ?: false
val predefinedInfo = if (isEnumEntry) {
val predefinedInfo =
PredefinedFunctionEnhancementInfo(
TypeEnhancementInfo(0 to JavaTypeQualifiers(NullabilityQualifier.NOT_NULL, null, false)),
emptyList()
)
} else {
null
}
val newReturnTypeRef = enhanceReturnType(firElement, emptyList(), memberContext, predefinedInfo)
return firElement.symbol.apply { this.fir.replaceReturnTypeRef(newReturnTypeRef) }
}
is FirField -> {
if (firElement.returnTypeRef !is FirJavaTypeRef) return original
val memberContext = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, firElement.annotations)
val newReturnTypeRef = enhanceReturnType(firElement, emptyList(), memberContext, null)
val symbol = FirFieldSymbol(original.callableId)
buildJavaField {