[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.progress.ProcessCanceledException
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
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.Visibility
|
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
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.resolve.scopes.wrapScopeWithJvmMapped
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
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.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||||
@@ -57,7 +56,8 @@ class JavaSymbolProvider(
|
|||||||
private val scopeProvider = JavaScopeProvider(::wrapScopeWithJvmMapped, this)
|
private val scopeProvider = JavaScopeProvider(::wrapScopeWithJvmMapped, this)
|
||||||
|
|
||||||
private val facade: KotlinJavaPsiFacade get() = KotlinJavaPsiFacade.getInstance(project)
|
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(
|
private fun findClass(
|
||||||
classId: ClassId,
|
classId: ClassId,
|
||||||
@@ -65,7 +65,8 @@ class JavaSymbolProvider(
|
|||||||
): JavaClass? = facade.findClass(JavaClassFinder.Request(classId, previouslyFoundClassFileContent = content?.content), searchScope)
|
): JavaClass? = facade.findClass(JavaClassFinder.Request(classId, previouslyFoundClassFileContent = content?.content), searchScope)
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
@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(
|
private fun JavaTypeParameter.toFirTypeParameterSymbol(
|
||||||
javaTypeParameterStack: JavaTypeParameterStack
|
javaTypeParameterStack: JavaTypeParameterStack
|
||||||
@@ -140,254 +141,312 @@ class JavaSymbolProvider(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
) { firSymbol, foundClass ->
|
) { firSymbol, foundClass ->
|
||||||
foundClass?.let { javaClass ->
|
convertJavaClassToFir(firSymbol, foundClass)
|
||||||
val javaTypeParameterStack = JavaTypeParameterStack()
|
}
|
||||||
val outerClassId = classId.outerClassId
|
}
|
||||||
val parentClassSymbol = if (outerClassId != null) {
|
|
||||||
getClassLikeSymbolByFqName(outerClassId)
|
private class ValueParametersForAnnotationConstructor {
|
||||||
} else null
|
val valueParameters: MutableList<FirJavaValueParameter> = mutableListOf()
|
||||||
if (parentClassSymbol != null) {
|
var valueParameterForValue: FirJavaValueParameter? = null
|
||||||
val parentStack = parentClassTypeParameterStackCache[parentClassSymbol]
|
}
|
||||||
?: (parentClassSymbol.fir as? FirJavaClass)?.javaTypeParameterStack
|
|
||||||
if (parentStack != null) {
|
private fun convertJavaClassToFir(classSymbol: FirRegularClassSymbol, javaClass: JavaClass?): FirJavaClass? {
|
||||||
javaTypeParameterStack.addStack(parentStack)
|
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()
|
status = FirResolvedDeclarationStatusImpl(
|
||||||
session = this@JavaSymbolProvider.session
|
javaClass.visibility,
|
||||||
symbol = firSymbol
|
javaClass.modality
|
||||||
name = javaClass.name
|
).apply {
|
||||||
visibility = javaClass.visibility
|
this.isInner = !isTopLevel && !this@buildJavaClass.isStatic
|
||||||
modality = javaClass.modality
|
isCompanion = false
|
||||||
classKind = javaClass.classKind
|
isData = false
|
||||||
this.isTopLevel = outerClassId == null
|
isInline = false
|
||||||
isStatic = javaClass.isStatic
|
isFun = classKind == ClassKind.INTERFACE
|
||||||
this.javaTypeParameterStack = javaTypeParameterStack
|
}
|
||||||
parentClassTypeParameterStackCache[firSymbol] = javaTypeParameterStack
|
addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
|
||||||
existingNestedClassifierNames += javaClass.innerClassNames
|
// TODO: may be we can process fields & methods later.
|
||||||
scopeProvider = this@JavaSymbolProvider.scopeProvider
|
// However, they should be built up to override resolve stage
|
||||||
val classTypeParameters = foundClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
for (javaField in javaClass.fields) {
|
||||||
typeParameters += classTypeParameters
|
declarations += convertJavaFieldToFir(javaField, classId, javaTypeParameterStack)
|
||||||
if (!isStatic && parentClassSymbol != null) {
|
}
|
||||||
typeParameters += parentClassSymbol.fir.typeParameters.map {
|
val valueParametersForAnnotationConstructor = ValueParametersForAnnotationConstructor()
|
||||||
buildOuterClassTypeParameterRef { symbol = it.symbol }
|
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) {
|
|
||||||
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
|
|
||||||
|
|
||||||
for (javaMethod in javaClass.methods) {
|
for (javaMethod in javaClass.methods) {
|
||||||
val methodName = javaMethod.name
|
declarations += convertJavaMethodToFir(
|
||||||
val methodId = CallableId(classId.packageFqName, classId.relativeClassName, methodName)
|
javaMethod,
|
||||||
val methodSymbol = FirNamedFunctionSymbol(methodId)
|
classId,
|
||||||
val returnType = javaMethod.returnType
|
javaTypeParameterStack,
|
||||||
val firJavaMethod = buildJavaMethod {
|
classIsAnnotation,
|
||||||
session = this@JavaSymbolProvider.session
|
valueParametersForAnnotationConstructor
|
||||||
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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
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? {
|
override fun getPackage(fqName: FqName): FqName? {
|
||||||
return packageCache.lookupCacheOrCalculate(fqName) {
|
return packageCache.lookupCacheOrCalculate(fqName) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user