Support Java constructors in FIR (related to KT-29218)
This commit is contained in:
@@ -9,24 +9,24 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableMember
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableClass
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirCall
|
||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
|
||||
class JavaSymbolProvider(
|
||||
@@ -44,17 +44,21 @@ class JavaSymbolProvider(
|
||||
val classId = callableId.classId ?: return@lookupCacheOrCalculate emptyList()
|
||||
val classSymbol = getClassLikeSymbolByFqName(classId) as? FirClassSymbol
|
||||
?: return@lookupCacheOrCalculate emptyList()
|
||||
val firClass = classSymbol.fir as FirModifiableClass
|
||||
val firClass = classSymbol.fir
|
||||
val callableSymbols = mutableListOf<ConeCallableSymbol>()
|
||||
for (declaration in firClass.declarations) {
|
||||
when (declaration) {
|
||||
is FirCallableMember -> {
|
||||
val declarationId = CallableId(callableId.packageName, callableId.className, declaration.name)
|
||||
if (declarationId == callableId) {
|
||||
val symbol = declaration.symbol as ConeCallableSymbol
|
||||
callableSymbols += symbol
|
||||
}
|
||||
val declarationId = when (declaration) {
|
||||
is FirConstructor -> {
|
||||
CallableId(callableId.packageName, callableId.className, firClass.name)
|
||||
}
|
||||
is FirCallableMember -> {
|
||||
CallableId(callableId.packageName, callableId.className, declaration.name)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
if (declarationId == callableId) {
|
||||
val symbol = (declaration as FirCallableMember).symbol as ConeCallableSymbol
|
||||
callableSymbols += symbol
|
||||
}
|
||||
}
|
||||
callableSymbols
|
||||
@@ -118,18 +122,32 @@ class JavaSymbolProvider(
|
||||
}
|
||||
addAnnotationsFrom(javaMethod)
|
||||
for (valueParameter in javaMethod.valueParameters) {
|
||||
val parameterType = valueParameter.type
|
||||
valueParameters += FirJavaValueParameter(
|
||||
session, valueParameter.name ?: Name.special("<anonymous Java parameter>"),
|
||||
returnTypeRef = parameterType.toFirJavaTypeRef(session),
|
||||
isVararg = valueParameter.isVararg
|
||||
).apply {
|
||||
addAnnotationsFrom(valueParameter)
|
||||
}
|
||||
valueParameters += valueParameter.toFirValueParameters(session)
|
||||
}
|
||||
}
|
||||
declarations += firJavaMethod
|
||||
}
|
||||
for (javaConstructor in javaClass.constructors) {
|
||||
val constructorId = CallableId(classId.packageFqName, classId.relativeClassName, classId.shortClassName)
|
||||
val constructorSymbol = FirFunctionSymbol(constructorId)
|
||||
val firJavaConstructor = FirJavaConstructor(
|
||||
session, constructorSymbol, javaConstructor.visibility,
|
||||
FirResolvedTypeRefImpl(
|
||||
session, null,
|
||||
firSymbol.constructType(emptyArray(), false),
|
||||
false, emptyList()
|
||||
)
|
||||
).apply {
|
||||
for (typeParameter in javaConstructor.typeParameters) {
|
||||
typeParameters += createTypeParameterSymbol(session, typeParameter.name).fir
|
||||
}
|
||||
addAnnotationsFrom(javaConstructor)
|
||||
for (valueParameter in javaConstructor.valueParameters) {
|
||||
valueParameters += valueParameter.toFirValueParameters(session)
|
||||
}
|
||||
}
|
||||
declarations += firJavaConstructor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,13 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaValueParameter
|
||||
import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
@@ -176,6 +178,16 @@ internal fun FirAbstractAnnotatedElement.addAnnotationsFrom(javaAnnotationOwner:
|
||||
}
|
||||
}
|
||||
|
||||
internal fun JavaValueParameter.toFirValueParameters(session: FirSession): FirValueParameter {
|
||||
return FirJavaValueParameter(
|
||||
session, name ?: Name.special("<anonymous Java parameter>"),
|
||||
returnTypeRef = type.toFirJavaTypeRef(session),
|
||||
isVararg = isVararg
|
||||
).apply {
|
||||
addAnnotationsFrom(this@toFirValueParameters)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun JavaType?.toConeProjection(session: FirSession, boundTypeParameter: FirTypeParameter?): ConeKotlinTypeProjection {
|
||||
return when (this) {
|
||||
null -> ConeStarProjection
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. 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.java.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirAbstractCallableMember
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirConstructorImpl.Companion.NAME
|
||||
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
|
||||
class FirJavaConstructor(
|
||||
session: FirSession,
|
||||
symbol: FirFunctionSymbol,
|
||||
visibility: Visibility,
|
||||
delegatedSelfTypeRef: FirTypeRef
|
||||
) : FirAbstractCallableMember(
|
||||
session, psi = null, symbol = symbol, name = NAME, visibility = visibility, modality = Modality.FINAL,
|
||||
isExpect = false, isActual = false, isOverride = false, receiverTypeRef = null, returnTypeRef = delegatedSelfTypeRef
|
||||
), FirConstructor {
|
||||
override val delegatedConstructor: FirDelegatedConstructorCall?
|
||||
get() = null
|
||||
|
||||
override val body: FirBlock?
|
||||
get() = null
|
||||
|
||||
override val valueParameters = mutableListOf<FirValueParameter>()
|
||||
}
|
||||
+21
-8
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaValueParameter
|
||||
@@ -102,7 +103,9 @@ class JavaClassEnhancementScope(
|
||||
original: ConeFunctionSymbol,
|
||||
name: Name
|
||||
): FirFunctionSymbol {
|
||||
val firMethod = (original as FirFunctionSymbol).fir as? FirJavaMethod ?: return original
|
||||
val firMethod = (original as FirFunctionSymbol).fir as? FirFunction
|
||||
|
||||
if (firMethod !is FirJavaMethod && firMethod !is FirJavaConstructor || firMethod !is FirCallableMember) return original
|
||||
|
||||
val memberContext = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, firMethod.annotations)
|
||||
|
||||
@@ -117,8 +120,14 @@ class JavaClassEnhancementScope(
|
||||
}
|
||||
}
|
||||
|
||||
val newReceiverTypeRef = if (firMethod.receiverTypeRef != null) enhanceReceiverType(firMethod, memberContext) else null
|
||||
val newReturnTypeRef = enhanceReturnType(firMethod, memberContext, predefinedEnhancementInfo)
|
||||
val newReceiverTypeRef = if (firMethod is FirJavaMethod && firMethod.receiverTypeRef != null) {
|
||||
enhanceReceiverType(firMethod, memberContext)
|
||||
} else null
|
||||
val newReturnTypeRef = if (firMethod is FirJavaConstructor) {
|
||||
firMethod.returnTypeRef
|
||||
} else {
|
||||
enhanceReturnType(firMethod, memberContext, predefinedEnhancementInfo)
|
||||
}
|
||||
|
||||
val newValueParameterTypeRefs = mutableListOf<FirResolvedTypeRef>()
|
||||
|
||||
@@ -134,7 +143,7 @@ class JavaClassEnhancementScope(
|
||||
session, null, symbol, name,
|
||||
newReceiverTypeRef, newReturnTypeRef
|
||||
).apply {
|
||||
status = firMethod.status
|
||||
status = firMethod.status as FirDeclarationStatusImpl
|
||||
annotations += firMethod.annotations
|
||||
valueParameters += firMethod.valueParameters.zip(newValueParameterTypeRefs) { valueParameter, newTypeRef ->
|
||||
with(valueParameter) {
|
||||
@@ -152,8 +161,12 @@ class JavaClassEnhancementScope(
|
||||
return symbol
|
||||
}
|
||||
|
||||
private fun FirJavaMethod.computeJvmDescriptor(): String = buildString {
|
||||
append(name.asString()) // TODO: Java constructors
|
||||
private fun FirFunction.computeJvmDescriptor(): String = buildString {
|
||||
if (this@computeJvmDescriptor is FirJavaMethod) {
|
||||
append(name.asString())
|
||||
} else {
|
||||
append("<init>")
|
||||
}
|
||||
|
||||
append("(")
|
||||
for (parameter in valueParameters) {
|
||||
@@ -161,7 +174,7 @@ class JavaClassEnhancementScope(
|
||||
}
|
||||
append(")")
|
||||
|
||||
if ((returnTypeRef as FirJavaTypeRef).isVoid()) {
|
||||
if (this@computeJvmDescriptor !is FirJavaMethod || (returnTypeRef as FirJavaTypeRef).isVoid()) {
|
||||
append("V")
|
||||
} else {
|
||||
// TODO: appendErasedType(returnTypeRef)
|
||||
@@ -189,7 +202,7 @@ class JavaClassEnhancementScope(
|
||||
}
|
||||
|
||||
private fun enhanceValueParameterType(
|
||||
ownerFunction: FirJavaMethod,
|
||||
ownerFunction: FirCallableMember,
|
||||
memberContext: FirJavaEnhancementContext,
|
||||
predefinedEnhancementInfo: PredefinedFunctionEnhancementInfo?,
|
||||
ownerParameter: FirJavaValueParameter,
|
||||
|
||||
Reference in New Issue
Block a user