[FIR] Split creating fir for java declarations to separate methods
This commit is contained in:
@@ -7,12 +7,10 @@ package org.jetbrains.kotlin.fir.java
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||
@@ -26,6 +24,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.SymbolProviderCache
|
||||
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||
@@ -57,7 +56,8 @@ class JavaSymbolProvider(
|
||||
private val scopeProvider = JavaScopeProvider(::wrapScopeWithJvmMapped, this)
|
||||
|
||||
private val facade: KotlinJavaPsiFacade get() = KotlinJavaPsiFacade.getInstance(project)
|
||||
private val parentClassTypeParameterStackCache: SymbolProviderCache<FirRegularClassSymbol, JavaTypeParameterStack> = SymbolProviderCache()
|
||||
private val parentClassTypeParameterStackCache: SymbolProviderCache<FirRegularClassSymbol, JavaTypeParameterStack> =
|
||||
SymbolProviderCache()
|
||||
|
||||
private fun findClass(
|
||||
classId: ClassId,
|
||||
@@ -65,7 +65,8 @@ class JavaSymbolProvider(
|
||||
): JavaClass? = facade.findClass(JavaClassFinder.Request(classId, previouslyFoundClassFileContent = content?.content), searchScope)
|
||||
|
||||
@FirSymbolProviderInternals
|
||||
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {}
|
||||
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||
}
|
||||
|
||||
private fun JavaTypeParameter.toFirTypeParameterSymbol(
|
||||
javaTypeParameterStack: JavaTypeParameterStack
|
||||
@@ -140,254 +141,312 @@ class JavaSymbolProvider(
|
||||
}
|
||||
},
|
||||
) { firSymbol, foundClass ->
|
||||
foundClass?.let { javaClass ->
|
||||
val javaTypeParameterStack = JavaTypeParameterStack()
|
||||
val outerClassId = classId.outerClassId
|
||||
val parentClassSymbol = if (outerClassId != null) {
|
||||
getClassLikeSymbolByFqName(outerClassId)
|
||||
} else null
|
||||
if (parentClassSymbol != null) {
|
||||
val parentStack = parentClassTypeParameterStackCache[parentClassSymbol]
|
||||
?: (parentClassSymbol.fir as? FirJavaClass)?.javaTypeParameterStack
|
||||
if (parentStack != null) {
|
||||
javaTypeParameterStack.addStack(parentStack)
|
||||
}
|
||||
convertJavaClassToFir(firSymbol, foundClass)
|
||||
}
|
||||
}
|
||||
|
||||
private class ValueParametersForAnnotationConstructor {
|
||||
val valueParameters: MutableList<FirJavaValueParameter> = mutableListOf()
|
||||
var valueParameterForValue: FirJavaValueParameter? = null
|
||||
}
|
||||
|
||||
private fun convertJavaClassToFir(classSymbol: FirRegularClassSymbol, javaClass: JavaClass?): FirJavaClass? {
|
||||
if (javaClass == null) return null
|
||||
val classId = classSymbol.classId
|
||||
val javaTypeParameterStack = JavaTypeParameterStack()
|
||||
val outerClassId = classId.outerClassId
|
||||
val parentClassSymbol = if (outerClassId != null) {
|
||||
getClassLikeSymbolByFqName(outerClassId)
|
||||
} else null
|
||||
if (parentClassSymbol != null) {
|
||||
val parentStack = parentClassTypeParameterStackCache[parentClassSymbol]
|
||||
?: (parentClassSymbol.fir as? FirJavaClass)?.javaTypeParameterStack
|
||||
if (parentStack != null) {
|
||||
javaTypeParameterStack.addStack(parentStack)
|
||||
}
|
||||
}
|
||||
val firJavaClass = buildJavaClass {
|
||||
source = (javaClass as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
|
||||
session = this@JavaSymbolProvider.session
|
||||
symbol = classSymbol
|
||||
name = javaClass.name
|
||||
visibility = javaClass.visibility
|
||||
modality = javaClass.modality
|
||||
classKind = javaClass.classKind
|
||||
this.isTopLevel = outerClassId == null
|
||||
isStatic = javaClass.isStatic
|
||||
this.javaTypeParameterStack = javaTypeParameterStack
|
||||
parentClassTypeParameterStackCache[classSymbol] = javaTypeParameterStack
|
||||
existingNestedClassifierNames += javaClass.innerClassNames
|
||||
scopeProvider = this@JavaSymbolProvider.scopeProvider
|
||||
val classTypeParameters = javaClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
typeParameters += classTypeParameters
|
||||
if (!isStatic && parentClassSymbol != null) {
|
||||
typeParameters += parentClassSymbol.fir.typeParameters.map {
|
||||
buildOuterClassTypeParameterRef { symbol = it.symbol }
|
||||
}
|
||||
val firJavaClass = buildJavaClass {
|
||||
source = (javaClass as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
|
||||
session = this@JavaSymbolProvider.session
|
||||
symbol = firSymbol
|
||||
name = javaClass.name
|
||||
visibility = javaClass.visibility
|
||||
modality = javaClass.modality
|
||||
classKind = javaClass.classKind
|
||||
this.isTopLevel = outerClassId == null
|
||||
isStatic = javaClass.isStatic
|
||||
this.javaTypeParameterStack = javaTypeParameterStack
|
||||
parentClassTypeParameterStackCache[firSymbol] = javaTypeParameterStack
|
||||
existingNestedClassifierNames += javaClass.innerClassNames
|
||||
scopeProvider = this@JavaSymbolProvider.scopeProvider
|
||||
val classTypeParameters = foundClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
typeParameters += classTypeParameters
|
||||
if (!isStatic && parentClassSymbol != null) {
|
||||
typeParameters += parentClassSymbol.fir.typeParameters.map {
|
||||
buildOuterClassTypeParameterRef { symbol = it.symbol }
|
||||
}
|
||||
}
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
javaClass.visibility,
|
||||
javaClass.modality
|
||||
).apply {
|
||||
this.isInner = !isTopLevel && !this@buildJavaClass.isStatic
|
||||
isCompanion = false
|
||||
isData = false
|
||||
isInline = false
|
||||
isFun = classKind == ClassKind.INTERFACE
|
||||
}
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
|
||||
// TODO: may be we can process fields & methods later.
|
||||
// However, they should be built up to override resolve stage
|
||||
for (javaField in javaClass.fields) {
|
||||
val fieldName = javaField.name
|
||||
val fieldId = CallableId(classId.packageFqName, classId.relativeClassName, fieldName)
|
||||
val returnType = javaField.type
|
||||
val firJavaDeclaration = when {
|
||||
javaField.isEnumEntry -> buildEnumEntry {
|
||||
source = (javaField as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
|
||||
session = this@JavaSymbolProvider.session
|
||||
symbol = FirVariableSymbol(fieldId)
|
||||
name = fieldName
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
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
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
javaField.visibility,
|
||||
javaField.modality
|
||||
).apply {
|
||||
isStatic = javaField.isStatic
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isOverride = false
|
||||
}
|
||||
visibility = javaField.visibility
|
||||
modality = javaField.modality
|
||||
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
|
||||
isVar = !javaField.isFinal
|
||||
isStatic = javaField.isStatic
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack)
|
||||
}
|
||||
}
|
||||
declarations += firJavaDeclaration
|
||||
}
|
||||
val valueParametersForAnnotationConstructor = mutableListOf<FirJavaValueParameter>()
|
||||
var valueParameterForValueInAnnotationConstructor: FirJavaValueParameter? = null
|
||||
val classIsAnnotation = classKind == ClassKind.ANNOTATION_CLASS
|
||||
}
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
javaClass.visibility,
|
||||
javaClass.modality
|
||||
).apply {
|
||||
this.isInner = !isTopLevel && !this@buildJavaClass.isStatic
|
||||
isCompanion = false
|
||||
isData = false
|
||||
isInline = false
|
||||
isFun = classKind == ClassKind.INTERFACE
|
||||
}
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
|
||||
// TODO: may be we can process fields & methods later.
|
||||
// However, they should be built up to override resolve stage
|
||||
for (javaField in javaClass.fields) {
|
||||
declarations += convertJavaFieldToFir(javaField, classId, javaTypeParameterStack)
|
||||
}
|
||||
val valueParametersForAnnotationConstructor = ValueParametersForAnnotationConstructor()
|
||||
val classIsAnnotation = classKind == ClassKind.ANNOTATION_CLASS
|
||||
|
||||
for (javaMethod in javaClass.methods) {
|
||||
val methodName = javaMethod.name
|
||||
val methodId = CallableId(classId.packageFqName, classId.relativeClassName, methodName)
|
||||
val methodSymbol = FirNamedFunctionSymbol(methodId)
|
||||
val returnType = javaMethod.returnType
|
||||
val firJavaMethod = buildJavaMethod {
|
||||
session = this@JavaSymbolProvider.session
|
||||
source = (javaMethod as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
|
||||
symbol = methodSymbol
|
||||
name = methodName
|
||||
visibility = javaMethod.visibility
|
||||
modality = javaMethod.modality
|
||||
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
|
||||
isStatic = javaMethod.isStatic
|
||||
typeParameters += javaMethod.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaMethod, javaTypeParameterStack)
|
||||
for ((index, valueParameter) in javaMethod.valueParameters.withIndex()) {
|
||||
valueParameters += valueParameter.toFirValueParameter(
|
||||
this@JavaSymbolProvider.session, index, javaTypeParameterStack,
|
||||
)
|
||||
}
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
javaMethod.visibility,
|
||||
javaMethod.modality
|
||||
).apply {
|
||||
isStatic = javaMethod.isStatic
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isOverride = false
|
||||
// Approximation: all Java methods with name that allows to use it in operator form are considered operators
|
||||
// We need here more detailed checks (see modifierChecks.kt)
|
||||
isOperator = name in ALL_JAVA_OPERATION_NAMES || OperatorNameConventions.COMPONENT_REGEX.matches(name.asString())
|
||||
isInfix = false
|
||||
isInline = false
|
||||
isTailRec = false
|
||||
isExternal = false
|
||||
isSuspend = false
|
||||
}
|
||||
}
|
||||
if (classIsAnnotation) {
|
||||
val parameterForAnnotationConstructor = buildJavaValueParameter {
|
||||
session = this@JavaSymbolProvider.session
|
||||
returnTypeRef = firJavaMethod.returnTypeRef
|
||||
name = firJavaMethod.name
|
||||
if (javaMethod.hasAnnotationParameterDefaultValue) {
|
||||
defaultValue = buildExpressionStub()
|
||||
}
|
||||
isVararg = javaMethod.returnType is JavaArrayType
|
||||
}
|
||||
if (firJavaMethod.name == VALUE_METHOD_NAME) {
|
||||
valueParameterForValueInAnnotationConstructor = parameterForAnnotationConstructor
|
||||
} else {
|
||||
valueParametersForAnnotationConstructor += parameterForAnnotationConstructor
|
||||
}
|
||||
}
|
||||
declarations += firJavaMethod
|
||||
}
|
||||
val javaClassDeclaredConstructors = javaClass.constructors
|
||||
val constructorId = CallableId(classId.packageFqName, classId.relativeClassName, classId.shortClassName)
|
||||
|
||||
fun buildSelfTypeRef() = firSymbol.constructType(
|
||||
this@buildJavaClass.typeParameters.map {
|
||||
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
||||
}.toTypedArray(),
|
||||
false,
|
||||
)
|
||||
|
||||
fun prepareJavaConstructor(
|
||||
visibility: Visibility = this.visibility,
|
||||
psi: PsiElement? = null,
|
||||
isPrimary: Boolean = false,
|
||||
): FirJavaConstructorBuilder {
|
||||
val constructorSymbol = FirConstructorSymbol(constructorId)
|
||||
return FirJavaConstructorBuilder().apply {
|
||||
source = psi?.toFirPsiSourceElement()
|
||||
session = this@JavaSymbolProvider.session
|
||||
symbol = constructorSymbol
|
||||
isInner = javaClass.outerClass != null && !javaClass.isStatic
|
||||
val isThisInner = this.isInner
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
visibility,
|
||||
Modality.FINAL
|
||||
).apply {
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isOverride = false
|
||||
isInner = isThisInner
|
||||
}
|
||||
this.visibility = visibility
|
||||
this.isPrimary = isPrimary
|
||||
returnTypeRef = buildResolvedTypeRef {
|
||||
type = buildSelfTypeRef()
|
||||
}
|
||||
typeParameters += classTypeParameters.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } }
|
||||
}
|
||||
}
|
||||
|
||||
if (javaClassDeclaredConstructors.isEmpty()
|
||||
&& javaClass.classKind == ClassKind.CLASS
|
||||
&& javaClass.hasDefaultConstructor()) {
|
||||
declarations += prepareJavaConstructor(isPrimary = true).build()
|
||||
}
|
||||
for (javaConstructor in javaClassDeclaredConstructors) {
|
||||
declarations += prepareJavaConstructor(
|
||||
visibility = javaConstructor.visibility,
|
||||
psi = (javaConstructor as? JavaElementImpl<*>)?.psi,
|
||||
).apply {
|
||||
this.typeParameters += javaConstructor.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaConstructor, javaTypeParameterStack)
|
||||
for ((index, valueParameter) in javaConstructor.valueParameters.withIndex()) {
|
||||
valueParameters += valueParameter.toFirValueParameter(
|
||||
this@JavaSymbolProvider.session, index, javaTypeParameterStack,
|
||||
)
|
||||
}
|
||||
}.build()
|
||||
}
|
||||
|
||||
if (classKind == ClassKind.ENUM_CLASS) {
|
||||
generateValuesFunction(session, classId.packageFqName, classId.relativeClassName)
|
||||
generateValueOfFunction(session, classId.packageFqName, classId.relativeClassName)
|
||||
}
|
||||
if (classIsAnnotation) {
|
||||
declarations += buildJavaConstructor {
|
||||
session = this@JavaSymbolProvider.session
|
||||
symbol = FirConstructorSymbol(constructorId)
|
||||
status = FirResolvedDeclarationStatusImpl(Visibilities.Public, Modality.FINAL)
|
||||
returnTypeRef = buildResolvedTypeRef {
|
||||
type = buildSelfTypeRef()
|
||||
}
|
||||
valueParameters.addIfNotNull(valueParameterForValueInAnnotationConstructor)
|
||||
valueParameters += valueParametersForAnnotationConstructor
|
||||
visibility = Visibilities.Public
|
||||
isInner = false
|
||||
isPrimary = true
|
||||
}
|
||||
}
|
||||
parentClassTypeParameterStackCache.remove(firSymbol)
|
||||
}
|
||||
firJavaClass.replaceSuperTypeRefs(
|
||||
javaClass.supertypes.map { supertype ->
|
||||
supertype.toFirResolvedTypeRef(
|
||||
this@JavaSymbolProvider.session, javaTypeParameterStack, isForSupertypes = true, forTypeParameterBounds = false
|
||||
)
|
||||
}
|
||||
for (javaMethod in javaClass.methods) {
|
||||
declarations += convertJavaMethodToFir(
|
||||
javaMethod,
|
||||
classId,
|
||||
javaTypeParameterStack,
|
||||
classIsAnnotation,
|
||||
valueParametersForAnnotationConstructor
|
||||
)
|
||||
}
|
||||
val javaClassDeclaredConstructors = javaClass.constructors
|
||||
val constructorId = CallableId(classId.packageFqName, classId.relativeClassName, classId.shortClassName)
|
||||
|
||||
if (javaClassDeclaredConstructors.isEmpty()
|
||||
&& javaClass.classKind == ClassKind.CLASS
|
||||
&& javaClass.hasDefaultConstructor()
|
||||
) {
|
||||
declarations += convertJavaConstructorToFir(
|
||||
javaConstructor = null,
|
||||
constructorId,
|
||||
javaClass,
|
||||
ownerClassBuilder = this,
|
||||
classTypeParameters,
|
||||
javaTypeParameterStack
|
||||
)
|
||||
}
|
||||
for (javaConstructor in javaClassDeclaredConstructors) {
|
||||
declarations += convertJavaConstructorToFir(
|
||||
javaConstructor,
|
||||
constructorId,
|
||||
javaClass,
|
||||
ownerClassBuilder = this,
|
||||
classTypeParameters,
|
||||
javaTypeParameterStack,
|
||||
)
|
||||
}
|
||||
|
||||
if (classKind == ClassKind.ENUM_CLASS) {
|
||||
generateValuesFunction(session, classId.packageFqName, classId.relativeClassName)
|
||||
generateValueOfFunction(session, classId.packageFqName, classId.relativeClassName)
|
||||
}
|
||||
if (classIsAnnotation) {
|
||||
declarations += buildConstructorForAnnotationClass(constructorId, this, valueParametersForAnnotationConstructor)
|
||||
}
|
||||
parentClassTypeParameterStackCache.remove(classSymbol)
|
||||
}
|
||||
firJavaClass.replaceSuperTypeRefs(
|
||||
javaClass.supertypes.map { supertype ->
|
||||
supertype.toFirResolvedTypeRef(
|
||||
this@JavaSymbolProvider.session, javaTypeParameterStack, isForSupertypes = true, forTypeParameterBounds = false
|
||||
)
|
||||
}
|
||||
)
|
||||
return firJavaClass
|
||||
}
|
||||
|
||||
private fun convertJavaFieldToFir(
|
||||
javaField: JavaField,
|
||||
classId: ClassId,
|
||||
javaTypeParameterStack: JavaTypeParameterStack
|
||||
): FirDeclaration {
|
||||
val fieldName = javaField.name
|
||||
val fieldId = CallableId(classId.packageFqName, classId.relativeClassName, fieldName)
|
||||
val returnType = javaField.type
|
||||
return when {
|
||||
javaField.isEnumEntry -> buildEnumEntry {
|
||||
source = (javaField as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
|
||||
session = this@JavaSymbolProvider.session
|
||||
symbol = FirVariableSymbol(fieldId)
|
||||
name = fieldName
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
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
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
javaField.visibility,
|
||||
javaField.modality
|
||||
).apply {
|
||||
isStatic = javaField.isStatic
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isOverride = false
|
||||
}
|
||||
visibility = javaField.visibility
|
||||
modality = javaField.modality
|
||||
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
|
||||
isVar = !javaField.isFinal
|
||||
isStatic = javaField.isStatic
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertJavaMethodToFir(
|
||||
javaMethod: JavaMethod,
|
||||
classId: ClassId,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
classIsAnnotation: Boolean,
|
||||
valueParametersForAnnotationConstructor: ValueParametersForAnnotationConstructor
|
||||
): FirJavaMethod {
|
||||
val methodName = javaMethod.name
|
||||
val methodId = CallableId(classId.packageFqName, classId.relativeClassName, methodName)
|
||||
val methodSymbol = FirNamedFunctionSymbol(methodId)
|
||||
val returnType = javaMethod.returnType
|
||||
val firJavaMethod = buildJavaMethod {
|
||||
session = this@JavaSymbolProvider.session
|
||||
source = (javaMethod as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
|
||||
symbol = methodSymbol
|
||||
name = methodName
|
||||
visibility = javaMethod.visibility
|
||||
modality = javaMethod.modality
|
||||
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
|
||||
isStatic = javaMethod.isStatic
|
||||
typeParameters += javaMethod.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaMethod, javaTypeParameterStack)
|
||||
for ((index, valueParameter) in javaMethod.valueParameters.withIndex()) {
|
||||
valueParameters += valueParameter.toFirValueParameter(
|
||||
this@JavaSymbolProvider.session, index, javaTypeParameterStack,
|
||||
)
|
||||
}
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
javaMethod.visibility,
|
||||
javaMethod.modality
|
||||
).apply {
|
||||
isStatic = javaMethod.isStatic
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isOverride = false
|
||||
// Approximation: all Java methods with name that allows to use it in operator form are considered operators
|
||||
// We need here more detailed checks (see modifierChecks.kt)
|
||||
isOperator = name in ALL_JAVA_OPERATION_NAMES || OperatorNameConventions.COMPONENT_REGEX.matches(name.asString())
|
||||
isInfix = false
|
||||
isInline = false
|
||||
isTailRec = false
|
||||
isExternal = false
|
||||
isSuspend = false
|
||||
}
|
||||
}
|
||||
if (classIsAnnotation) {
|
||||
val parameterForAnnotationConstructor = buildJavaValueParameter {
|
||||
session = this@JavaSymbolProvider.session
|
||||
returnTypeRef = firJavaMethod.returnTypeRef
|
||||
name = firJavaMethod.name
|
||||
if (javaMethod.hasAnnotationParameterDefaultValue) {
|
||||
defaultValue = buildExpressionStub()
|
||||
}
|
||||
isVararg = javaMethod.returnType is JavaArrayType
|
||||
}
|
||||
if (firJavaMethod.name == VALUE_METHOD_NAME) {
|
||||
valueParametersForAnnotationConstructor.valueParameterForValue = parameterForAnnotationConstructor
|
||||
} else {
|
||||
valueParametersForAnnotationConstructor.valueParameters += parameterForAnnotationConstructor
|
||||
}
|
||||
}
|
||||
return firJavaMethod
|
||||
}
|
||||
|
||||
private fun convertJavaConstructorToFir(
|
||||
javaConstructor: JavaConstructor?,
|
||||
constructorId: CallableId,
|
||||
javaClass: JavaClass,
|
||||
ownerClassBuilder: FirJavaClassBuilder,
|
||||
classTypeParameters: List<FirTypeParameter>,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
): FirJavaConstructor {
|
||||
val constructorSymbol = FirConstructorSymbol(constructorId)
|
||||
return buildJavaConstructor {
|
||||
source = (javaConstructor as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
|
||||
session = this@JavaSymbolProvider.session
|
||||
symbol = constructorSymbol
|
||||
isInner = javaClass.outerClass != null && !javaClass.isStatic
|
||||
val isThisInner = this.isInner
|
||||
val visibility = javaConstructor?.visibility ?: ownerClassBuilder.visibility
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
visibility,
|
||||
Modality.FINAL
|
||||
).apply {
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isOverride = false
|
||||
isInner = isThisInner
|
||||
}
|
||||
this.visibility = visibility
|
||||
isPrimary = javaConstructor == null
|
||||
returnTypeRef = buildResolvedTypeRef {
|
||||
type = ownerClassBuilder.buildSelfTypeRef()
|
||||
}
|
||||
typeParameters += classTypeParameters.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } }
|
||||
|
||||
if (javaConstructor != null) {
|
||||
this.typeParameters += javaConstructor.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaConstructor, javaTypeParameterStack)
|
||||
for ((index, valueParameter) in javaConstructor.valueParameters.withIndex()) {
|
||||
valueParameters += valueParameter.toFirValueParameter(
|
||||
this@JavaSymbolProvider.session, index, javaTypeParameterStack,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildConstructorForAnnotationClass(
|
||||
constructorId: CallableId,
|
||||
ownerClassBuilder: FirJavaClassBuilder,
|
||||
valueParametersForAnnotationConstructor: ValueParametersForAnnotationConstructor
|
||||
): FirJavaConstructor {
|
||||
return buildJavaConstructor {
|
||||
session = this@JavaSymbolProvider.session
|
||||
symbol = FirConstructorSymbol(constructorId)
|
||||
status = FirResolvedDeclarationStatusImpl(Visibilities.Public, Modality.FINAL)
|
||||
returnTypeRef = buildResolvedTypeRef {
|
||||
type = ownerClassBuilder.buildSelfTypeRef()
|
||||
}
|
||||
valueParameters.addIfNotNull(valueParametersForAnnotationConstructor.valueParameterForValue)
|
||||
valueParameters += valueParametersForAnnotationConstructor.valueParameters
|
||||
visibility = Visibilities.Public
|
||||
isInner = false
|
||||
isPrimary = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirJavaClassBuilder.buildSelfTypeRef(): ConeKotlinType = symbol.constructType(
|
||||
typeParameters.map {
|
||||
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), isNullable = false)
|
||||
}.toTypedArray(),
|
||||
isNullable = false,
|
||||
)
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? {
|
||||
return packageCache.lookupCacheOrCalculate(fqName) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user