From 7bfe7061e764eeece2021e72d547c77b38c6a9a1 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 20 Mar 2020 13:54:12 +0300 Subject: [PATCH] [FIR] Add proper nullability for java enums --- .../signatureAnnotations/DefaultEnum.fir.txt | 6 +++--- .../kotlin/fir/java/JavaSymbolProvider.kt | 2 ++ .../fir/java/declarations/FirJavaField.kt | 5 ++++- .../java/scopes/JavaClassEnhancementScope.kt | 17 ++++++++++++++--- .../testData/ir/irText/stubs/javaEnum.fir.txt | 10 +++++----- .../annotations/AnnotatedEnumEntry.fir.txt | 6 +++--- .../EnumConstructorParameter.fir.txt | 2 +- .../compiledJava/enum/EnumMembers.fir.txt | 4 ++-- .../enum/EnumWithSpecializedEntry.fir.txt | 4 ++-- .../loadJava/compiledJava/enum/JavaEnum.fir.txt | 4 ++-- .../loadJava/compiledJava/static/Enum.fir.txt | 6 +++--- .../static/StaticMembersInEnum.fir.txt | 2 +- 12 files changed, 42 insertions(+), 26 deletions(-) diff --git a/compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultEnum.fir.txt b/compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultEnum.fir.txt index 657cc039ace..0a4deeaf888 100644 --- a/compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultEnum.fir.txt +++ b/compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultEnum.fir.txt @@ -11,7 +11,7 @@ public/*package*/ open class A : R|kotlin/Any| { } public final enum class Mixed : R|kotlin/Enum!>| { - public final static field NOT_ENTRY_EITHER: R|ft!| + public final static field NOT_ENTRY_EITHER: R|Mixed| public final static fun values(): R|kotlin/Array| { } @@ -21,9 +21,9 @@ public final enum class Mixed : R|kotlin/Enum!>| { } public final enum class Signs : R|kotlin/Enum!>| { - public final static field HELLO: R|ft!| + public final static field HELLO: R|Signs| - public final static field WORLD: R|ft!| + public final static field WORLD: R|Signs| public final static field X: R|ft!| diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index 152637971c9..08c5ebe5372 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -16,6 +16,7 @@ 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.expressions.builder.buildAnnotationCall import org.jetbrains.kotlin.fir.java.declarations.* import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider import org.jetbrains.kotlin.fir.resolve.constructType @@ -194,6 +195,7 @@ class JavaSymbolProvider( returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack) isVar = !javaField.isFinal isStatic = javaField.isStatic + isEnumEntry = javaField.isEnumEntry addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack) } declarations += firJavaField diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt index 1634cc93670..38cc04e8c81 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt @@ -42,6 +42,7 @@ class FirJavaField @FirImplementationDetail constructor( override val isVar: Boolean, override val annotations: MutableList, override val typeParameters: MutableList, + val isEnumEntry: Boolean ) : FirField() { init { symbol.bind(this) @@ -127,6 +128,7 @@ internal class FirJavaFieldBuilder : FirFieldBuilder() { var modality: Modality? = null lateinit var visibility: Visibility var isStatic: Boolean by Delegates.notNull() + var isEnumEntry: Boolean by Delegates.notNull() override var resolvePhase: FirResolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES @@ -149,7 +151,8 @@ internal class FirJavaFieldBuilder : FirFieldBuilder() { status, isVar, annotations, - typeParameters + typeParameters, + isEnumEntry ) } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt index ac97716f397..5c5f5c007e6 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt @@ -33,8 +33,7 @@ import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue -import org.jetbrains.kotlin.load.java.typeEnhancement.PREDEFINED_FUNCTION_ENHANCEMENT_INFO_BY_SIGNATURE -import org.jetbrains.kotlin.load.java.typeEnhancement.PredefinedFunctionEnhancementInfo +import org.jetbrains.kotlin.load.java.typeEnhancement.* import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.Jsr305State @@ -89,7 +88,18 @@ class JavaClassEnhancementScope( 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 isEnumEntry = (firElement as? FirJavaField)?.isEnumEntry ?: false + + val predefinedInfo = if (isEnumEntry) { + PredefinedFunctionEnhancementInfo( + TypeEnhancementInfo(0 to JavaTypeQualifiers(NullabilityQualifier.NOT_NULL, null, false)), + emptyList() + ) + } else { + null + } + + val newReturnTypeRef = enhanceReturnType(firElement, emptyList(), memberContext, predefinedInfo) val symbol = FirFieldSymbol(original.callableId) buildJavaField { @@ -103,6 +113,7 @@ class JavaClassEnhancementScope( isVar = firElement.isVar isStatic = firElement.isStatic annotations += firElement.annotations + this.isEnumEntry = isEnumEntry } return symbol } diff --git a/compiler/testData/ir/irText/stubs/javaEnum.fir.txt b/compiler/testData/ir/irText/stubs/javaEnum.fir.txt index f816a599a8f..c342ca97b84 100644 --- a/compiler/testData/ir/irText/stubs/javaEnum.fir.txt +++ b/compiler/testData/ir/irText/stubs/javaEnum.fir.txt @@ -1,10 +1,10 @@ FILE fqName: fileName:/javaEnum.kt PROPERTY name:test visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:test type:.JEnum? visibility:private [final,static] + FIELD PROPERTY_BACKING_FIELD name:test type:.JEnum visibility:private [final,static] EXPRESSION_BODY - GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:ONE type:.JEnum? visibility:public [final,static]' type=.JEnum? origin=GET_PROPERTY - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:.JEnum? + GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:ONE type:.JEnum visibility:public [final,static]' type=.JEnum origin=GET_PROPERTY + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:.JEnum correspondingProperty: PROPERTY name:test visibility:public modality:FINAL [val] BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): .JEnum? declared in ' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test type:.JEnum? visibility:private [final,static]' type=.JEnum? origin=null + RETURN type=kotlin.Nothing from='public final fun (): .JEnum declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test type:.JEnum visibility:private [final,static]' type=.JEnum origin=null diff --git a/compiler/testData/loadJava/compiledJava/annotations/AnnotatedEnumEntry.fir.txt b/compiler/testData/loadJava/compiledJava/annotations/AnnotatedEnumEntry.fir.txt index 1f862839fc3..79e7c951286 100644 --- a/compiler/testData/loadJava/compiledJava/annotations/AnnotatedEnumEntry.fir.txt +++ b/compiler/testData/loadJava/compiledJava/annotations/AnnotatedEnumEntry.fir.txt @@ -1,9 +1,9 @@ public final enum class AnnotatedEnumEntry : R|kotlin/Enum!>| { - @R|test/AnnotatedEnumEntry.Anno|(String(a)) public final static field E1: R|ft!| + @R|test/AnnotatedEnumEntry.Anno|(String(a)) public final static field E1: R|test/AnnotatedEnumEntry| - @R|test/AnnotatedEnumEntry.Anno|(String(b)) @R|test/AnnotatedEnumEntry.Anno2|() public final static field E2: R|ft!| + @R|test/AnnotatedEnumEntry.Anno|(String(b)) @R|test/AnnotatedEnumEntry.Anno2|() public final static field E2: R|test/AnnotatedEnumEntry| - public final static field E3: R|ft!| + public final static field E3: R|test/AnnotatedEnumEntry| public final static fun values(): R|kotlin/Array| { } diff --git a/compiler/testData/loadJava/compiledJava/annotations/EnumConstructorParameter.fir.txt b/compiler/testData/loadJava/compiledJava/annotations/EnumConstructorParameter.fir.txt index cef9b39dfb9..063e0684ad1 100644 --- a/compiler/testData/loadJava/compiledJava/annotations/EnumConstructorParameter.fir.txt +++ b/compiler/testData/loadJava/compiledJava/annotations/EnumConstructorParameter.fir.txt @@ -1,5 +1,5 @@ public final enum class EnumConstructorParameter : R|kotlin/Enum!>| { - public final static field INSTANCE: R|ft!| + public final static field INSTANCE: R|test/EnumConstructorParameter| private constructor(@R|test/EnumConstructorParameter.Anno|(String(string)) s: R|ft!|): R|test/EnumConstructorParameter| diff --git a/compiler/testData/loadJava/compiledJava/enum/EnumMembers.fir.txt b/compiler/testData/loadJava/compiledJava/enum/EnumMembers.fir.txt index 1d630211fca..2a104cd13f0 100644 --- a/compiler/testData/loadJava/compiledJava/enum/EnumMembers.fir.txt +++ b/compiler/testData/loadJava/compiledJava/enum/EnumMembers.fir.txt @@ -1,7 +1,7 @@ public final enum class EnumMembers : R|kotlin/Enum!>| { - public final static field FIRST: R|ft!| + public final static field FIRST: R|test/EnumMembers| - public final static field SECOND: R|ft!| + public final static field SECOND: R|test/EnumMembers| public final field isFirst: R|kotlin/Boolean| diff --git a/compiler/testData/loadJava/compiledJava/enum/EnumWithSpecializedEntry.fir.txt b/compiler/testData/loadJava/compiledJava/enum/EnumWithSpecializedEntry.fir.txt index 5b0fc8a8638..e725afd41ab 100644 --- a/compiler/testData/loadJava/compiledJava/enum/EnumWithSpecializedEntry.fir.txt +++ b/compiler/testData/loadJava/compiledJava/enum/EnumWithSpecializedEntry.fir.txt @@ -1,7 +1,7 @@ public open enum class EnumWithSpecializedEntry : R|kotlin/Enum!>| { - public final static field E1: R|ft!| + public final static field E1: R|test/EnumWithSpecializedEntry| - public final static field E2: R|ft!| + public final static field E2: R|test/EnumWithSpecializedEntry| public final static fun values(): R|kotlin/Array| { } diff --git a/compiler/testData/loadJava/compiledJava/enum/JavaEnum.fir.txt b/compiler/testData/loadJava/compiledJava/enum/JavaEnum.fir.txt index 633ef06a2e2..8ba9441d88f 100644 --- a/compiler/testData/loadJava/compiledJava/enum/JavaEnum.fir.txt +++ b/compiler/testData/loadJava/compiledJava/enum/JavaEnum.fir.txt @@ -1,7 +1,7 @@ public final enum class JavaEnum : R|kotlin/Enum!>| { - public final static field ENTRY: R|ft!| + public final static field ENTRY: R|test/JavaEnum| - public final static field ANOTHER: R|ft!| + public final static field ANOTHER: R|test/JavaEnum| public final static fun values(): R|kotlin/Array| { } diff --git a/compiler/testData/loadJava/compiledJava/static/Enum.fir.txt b/compiler/testData/loadJava/compiledJava/static/Enum.fir.txt index 0cd00dc98fc..d9e2fa162ec 100644 --- a/compiler/testData/loadJava/compiledJava/static/Enum.fir.txt +++ b/compiler/testData/loadJava/compiledJava/static/Enum.fir.txt @@ -1,9 +1,9 @@ public final enum class Enum : R|kotlin/Enum!>| { - public final static field A: R|ft!| + public final static field A: R|test/Enum| - public final static field B: R|ft!| + public final static field B: R|test/Enum| - public final static field C: R|ft!| + public final static field C: R|test/Enum| public final static fun values(): R|kotlin/Array| { } diff --git a/compiler/testData/loadJava/compiledJava/static/StaticMembersInEnum.fir.txt b/compiler/testData/loadJava/compiledJava/static/StaticMembersInEnum.fir.txt index d3a626aba55..a46622ba144 100644 --- a/compiler/testData/loadJava/compiledJava/static/StaticMembersInEnum.fir.txt +++ b/compiler/testData/loadJava/compiledJava/static/StaticMembersInEnum.fir.txt @@ -1,5 +1,5 @@ public final enum class StaticMembersInEnum : R|kotlin/Enum!>| { - public final static field ENTRY: R|ft!| + public final static field ENTRY: R|test/StaticMembersInEnum| public open static field STATIC_FIELD: R|kotlin/Int|