FIR: Add synthetic values/valueOf methods to Java classes

This commit is contained in:
Denis Zharkov
2019-11-21 14:48:50 +03:00
parent 256f5ca0a1
commit f659dc0bea
14 changed files with 96 additions and 14 deletions
@@ -11,8 +11,13 @@ import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* 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.impl.FirTypeParameterImpl import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
import org.jetbrains.kotlin.fir.declarations.visibility
import org.jetbrains.kotlin.fir.generateValueOfFunction
import org.jetbrains.kotlin.fir.generateValuesFunction
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
@@ -284,6 +289,11 @@ class JavaSymbolProvider(
} }
} }
} }
if (classKind == ClassKind.ENUM_CLASS) {
generateValuesFunction(session, classId.packageFqName, classId.relativeClassName)
generateValueOfFunction(session, classId.packageFqName, classId.relativeClassName)
}
} }
} }
} }
@@ -13,9 +13,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.NAME_FOR_DEFAULT_VALUE_PARAMETER
import org.jetbrains.kotlin.fir.builder.* import org.jetbrains.kotlin.fir.builder.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.* import org.jetbrains.kotlin.fir.declarations.impl.*
@@ -13,6 +13,12 @@ public/*package*/ open class A : R|kotlin/Any| {
public final enum class Mixed : R|kotlin/Enum<Mixed>| { public final enum class Mixed : R|kotlin/Enum<Mixed>| {
public final static field NOT_ENTRY_EITHER: R|ft<Mixed, Mixed?>!| public final static field NOT_ENTRY_EITHER: R|ft<Mixed, Mixed?>!|
public final static fun values(): R|kotlin/Array<Mixed>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|Mixed| {
}
} }
public final enum class Signs : R|kotlin/Enum<Signs>| { public final enum class Signs : R|kotlin/Enum<Signs>| {
public final static field HELLO: R|ft<Signs, Signs?>!| public final static field HELLO: R|ft<Signs, Signs?>!|
@@ -21,4 +27,10 @@ public final enum class Signs : R|kotlin/Enum<Signs>| {
public final static field X: R|ft<Signs, Signs?>!| public final static field X: R|ft<Signs, Signs?>!|
public final static fun values(): R|kotlin/Array<Signs>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|Signs| {
}
} }
@@ -0,0 +1,10 @@
// FILE: JavaEnum.java
public enum JavaEnum {
X, Y
}
// FILE: main.kt
fun foo() {
JavaEnum.values()
JavaEnum.valueOf("")
}
@@ -0,0 +1,5 @@
FILE: main.kt
public final fun foo(): R|kotlin/Unit| {
Q|JavaEnum|.R|/JavaEnum.values|()
Q|JavaEnum|.R|/JavaEnum.valueOf|(String())
}
@@ -103,6 +103,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
runTest("compiler/fir/resolve/testData/resolve/stdlib/implicitReceiverOrder.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/implicitReceiverOrder.kt");
} }
@TestMetadata("javaEnumSynthetic.kt")
public void testJavaEnumSynthetic() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/javaEnumSynthetic.kt");
}
@TestMetadata("listPlusAssign.kt") @TestMetadata("listPlusAssign.kt")
public void testListPlusAssign() throws Exception { public void testListPlusAssign() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/listPlusAssign.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/listPlusAssign.kt");
@@ -3,14 +3,14 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.fir.builder package org.jetbrains.kotlin.fir
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.addDeclaration import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableRegularClass import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableClass
import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
@@ -29,14 +29,14 @@ private val ENUM_VALUES = Name.identifier("values")
private val ENUM_VALUE_OF = Name.identifier("valueOf") private val ENUM_VALUE_OF = Name.identifier("valueOf")
private val VALUE = Name.identifier("value") private val VALUE = Name.identifier("value")
fun FirModifiableRegularClass.generateValuesFunction( fun FirModifiableClass<out FirRegularClass>.generateValuesFunction(
session: FirSession, packageFqName: FqName, classFqName: FqName session: FirSession, packageFqName: FqName, classFqName: FqName
) { ) {
val symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, ENUM_VALUES)) val symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, ENUM_VALUES))
val status = FirDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL).apply { val status = FirDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL).apply {
isStatic = true isStatic = true
} }
addDeclaration( declarations +=
FirSimpleFunctionImpl( FirSimpleFunctionImpl(
source, session, source, session,
FirResolvedTypeRefImpl( FirResolvedTypeRefImpl(
@@ -50,19 +50,19 @@ fun FirModifiableRegularClass.generateValuesFunction(
), ),
null, ENUM_VALUES, status, symbol null, ENUM_VALUES, status, symbol
).apply { ).apply {
resolvePhase = FirResolvePhase.BODY_RESOLVE
body = FirEmptyExpressionBlock() body = FirEmptyExpressionBlock()
} }
)
} }
fun FirModifiableRegularClass.generateValueOfFunction( fun FirModifiableClass<out FirRegularClass>.generateValueOfFunction(
session: FirSession, packageFqName: FqName, classFqName: FqName session: FirSession, packageFqName: FqName, classFqName: FqName
) { ) {
val symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, ENUM_VALUE_OF)) val symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, ENUM_VALUE_OF))
val status = FirDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL).apply { val status = FirDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL).apply {
isStatic = true isStatic = true
} }
addDeclaration( declarations +=
FirSimpleFunctionImpl( FirSimpleFunctionImpl(
source, session, source, session,
FirResolvedTypeRefImpl( FirResolvedTypeRefImpl(
@@ -74,6 +74,7 @@ fun FirModifiableRegularClass.generateValueOfFunction(
), ),
null, ENUM_VALUE_OF, status, symbol null, ENUM_VALUE_OF, status, symbol
).apply { ).apply {
resolvePhase = FirResolvePhase.BODY_RESOLVE
valueParameters += FirValueParameterImpl( valueParameters += FirValueParameterImpl(
source, session, FirImplicitStringTypeRef(source), source, session, FirImplicitStringTypeRef(source),
VALUE, FirVariableSymbol(VALUE), VALUE, FirVariableSymbol(VALUE),
@@ -81,5 +82,4 @@ fun FirModifiableRegularClass.generateValueOfFunction(
) )
body = FirEmptyExpressionBlock() body = FirEmptyExpressionBlock()
} }
)
} }
@@ -5,4 +5,10 @@ public final enum class AnnotatedEnumEntry : R|kotlin/Enum<test/AnnotatedEnumEnt
public final static field E3: R|ft<test/AnnotatedEnumEntry, test/AnnotatedEnumEntry?>!| public final static field E3: R|ft<test/AnnotatedEnumEntry, test/AnnotatedEnumEntry?>!|
public final static fun values(): R|kotlin/Array<test/AnnotatedEnumEntry>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|test/AnnotatedEnumEntry| {
}
} }
@@ -5,4 +5,10 @@ public final enum class EnumConstructorParameter : R|kotlin/Enum<test/EnumConstr
private constructor(x: R|kotlin/Int|): R|test/EnumConstructorParameter| private constructor(x: R|kotlin/Int|): R|test/EnumConstructorParameter|
public final static fun values(): R|kotlin/Array<test/EnumConstructorParameter>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|test/EnumConstructorParameter| {
}
} }
@@ -9,4 +9,10 @@ public final enum class EnumMembers : R|kotlin/Enum<test/EnumMembers>| {
private constructor(isFirst: R|kotlin/Boolean|): R|test/EnumMembers| private constructor(isFirst: R|kotlin/Boolean|): R|test/EnumMembers|
public final static fun values(): R|kotlin/Array<test/EnumMembers>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|test/EnumMembers| {
}
} }
@@ -3,4 +3,10 @@ public open enum class EnumWithSpecializedEntry : R|kotlin/Enum<test/EnumWithSpe
public final static field E2: R|ft<test/EnumWithSpecializedEntry, test/EnumWithSpecializedEntry?>!| public final static field E2: R|ft<test/EnumWithSpecializedEntry, test/EnumWithSpecializedEntry?>!|
public final static fun values(): R|kotlin/Array<test/EnumWithSpecializedEntry>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|test/EnumWithSpecializedEntry| {
}
} }
@@ -3,4 +3,10 @@ public final enum class JavaEnum : R|kotlin/Enum<test/JavaEnum>| {
public final static field ANOTHER: R|ft<test/JavaEnum, test/JavaEnum?>!| public final static field ANOTHER: R|ft<test/JavaEnum, test/JavaEnum?>!|
public final static fun values(): R|kotlin/Array<test/JavaEnum>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|test/JavaEnum| {
}
} }
@@ -5,4 +5,10 @@ public final enum class Enum : R|kotlin/Enum<test/Enum>| {
public final static field C: R|ft<test/Enum, test/Enum?>!| public final static field C: R|ft<test/Enum, test/Enum?>!|
public final static fun values(): R|kotlin/Array<test/Enum>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|test/Enum| {
}
} }
@@ -9,6 +9,12 @@ public final enum class StaticMembersInEnum : R|kotlin/Enum<test/StaticMembersIn
public open static operator fun values(x: R|kotlin/Int|): R|kotlin/Unit| public open static operator fun values(x: R|kotlin/Int|): R|kotlin/Unit|
public final static fun values(): R|kotlin/Array<test/StaticMembersInEnum>| {
}
public open static operator fun valueOf(x: R|kotlin/Int|): R|kotlin/Unit| public open static operator fun valueOf(x: R|kotlin/Int|): R|kotlin/Unit|
public final static fun valueOf(value: R|kotlin/String|): R|test/StaticMembersInEnum| {
}
} }