FIR: implement Java fields (in provider, type enhancement, scopes)
Related to KT-29218
This commit is contained in:
@@ -8,10 +8,11 @@ package org.jetbrains.kotlin.fir.java
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableMember
|
||||
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.resolve.AbstractFirSymbolProvider
|
||||
@@ -19,6 +20,7 @@ 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.load.java.JavaClassFinder
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
@@ -45,11 +47,13 @@ class JavaSymbolProvider(
|
||||
val firClass = classSymbol.fir as FirModifiableClass
|
||||
val callableSymbols = mutableListOf<ConeCallableSymbol>()
|
||||
for (declaration in firClass.declarations) {
|
||||
if (declaration is FirNamedFunction) {
|
||||
val methodId = CallableId(callableId.packageName, callableId.className, declaration.name)
|
||||
if (methodId == callableId) {
|
||||
val symbol = declaration.symbol as ConeCallableSymbol
|
||||
callableSymbols += symbol
|
||||
when (declaration) {
|
||||
is FirCallableMember -> {
|
||||
val declarationId = CallableId(callableId.packageName, callableId.className, declaration.name)
|
||||
if (declarationId == callableId) {
|
||||
val symbol = declaration.symbol as ConeCallableSymbol
|
||||
callableSymbols += symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,9 +84,24 @@ class JavaSymbolProvider(
|
||||
for (supertype in javaClass.supertypes) {
|
||||
superTypeRefs += supertype.toFirResolvedTypeRef(session)
|
||||
}
|
||||
// TODO: fields
|
||||
// TODO: may be we can process methods later.
|
||||
// TODO: may be we can process fields & methods later.
|
||||
// However, they should be built up to override resolve stage
|
||||
for (javaField in javaClass.fields) {
|
||||
if (javaField.isStatic) continue // TODO: statics
|
||||
val fieldName = javaField.name
|
||||
val fieldId = CallableId(classId.packageFqName, classId.relativeClassName, fieldName)
|
||||
val fieldSymbol = FirFieldSymbol(fieldId)
|
||||
val returnType = javaField.type
|
||||
val firJavaField = FirJavaField(
|
||||
session, fieldSymbol, fieldName,
|
||||
javaField.visibility, javaField.modality,
|
||||
returnTypeRef = returnType.toFirJavaTypeRef(session),
|
||||
isVar = !javaField.isFinal
|
||||
).apply {
|
||||
addAnnotationsFrom(javaField)
|
||||
}
|
||||
declarations += firJavaField
|
||||
}
|
||||
for (javaMethod in javaClass.methods) {
|
||||
if (javaMethod.isStatic) continue // TODO: statics
|
||||
val methodName = javaMethod.name
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.FirField
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirAbstractCallableMember
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class FirJavaField(
|
||||
session: FirSession,
|
||||
symbol: FirFieldSymbol,
|
||||
name: Name,
|
||||
visibility: Visibility,
|
||||
modality: Modality?,
|
||||
returnTypeRef: FirJavaTypeRef,
|
||||
override val isVar: Boolean
|
||||
) : FirAbstractCallableMember(
|
||||
session, psi = null, symbol = symbol, name = name,
|
||||
visibility = visibility, modality = modality,
|
||||
isExpect = false, isActual = false, isOverride = false,
|
||||
receiverTypeRef = null, returnTypeRef = returnTypeRef
|
||||
), FirField {
|
||||
override val delegate: FirExpression?
|
||||
get() = null
|
||||
|
||||
override val initializer: FirExpression?
|
||||
get() = null
|
||||
}
|
||||
+49
-19
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.fir.java.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirMemberFunctionImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationContainer
|
||||
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.java.enhancement.EnhancementSignatureParts
|
||||
@@ -21,8 +21,10 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver
|
||||
@@ -48,6 +50,16 @@ class JavaClassEnhancementScope(
|
||||
|
||||
private val enhancements = mutableMapOf<ConeCallableSymbol, ConeCallableSymbol>()
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction {
|
||||
useSiteScope.processPropertiesByName(name) process@{ original ->
|
||||
|
||||
val field = enhancements.getOrPut(original) { enhance(original, name) }
|
||||
processor(field as ConePropertySymbol)
|
||||
}
|
||||
|
||||
return super.processPropertiesByName(name, processor)
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction {
|
||||
useSiteScope.processFunctionsByName(name) process@{ original ->
|
||||
|
||||
@@ -58,20 +70,41 @@ class JavaClassEnhancementScope(
|
||||
return super.processFunctionsByName(name, processor)
|
||||
}
|
||||
|
||||
private fun enhance(
|
||||
original: ConePropertySymbol,
|
||||
name: Name
|
||||
): FirPropertySymbol {
|
||||
val firField = (original as FirBasedSymbol<*>).fir as? FirJavaField ?: error("Can't make enhancement for $original")
|
||||
|
||||
val memberContext = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, firField.annotations)
|
||||
val newReturnTypeRef = enhanceReturnType(firField, memberContext, null)
|
||||
|
||||
val symbol = FirPropertySymbol(original.callableId)
|
||||
with(firField) {
|
||||
FirMemberPropertyImpl(
|
||||
session, null, symbol, name,
|
||||
visibility, modality, isExpect, isActual, isOverride,
|
||||
isConst = false, isLateInit = false,
|
||||
receiverTypeRef = null,
|
||||
returnTypeRef = newReturnTypeRef,
|
||||
isVar = isVar, initializer = null,
|
||||
getter = FirDefaultPropertyGetter(session, null, newReturnTypeRef, visibility),
|
||||
setter = FirDefaultPropertySetter(session, null, newReturnTypeRef, visibility),
|
||||
delegate = null
|
||||
).apply {
|
||||
annotations += firField.annotations
|
||||
}
|
||||
}
|
||||
return symbol
|
||||
}
|
||||
|
||||
private fun enhance(
|
||||
original: ConeFunctionSymbol,
|
||||
name: Name
|
||||
): FirFunctionSymbol {
|
||||
val firMethod = (original as FirBasedSymbol<*>).fir as? FirJavaMethod ?: error("Can't fake override for $original")
|
||||
val firMethod = (original as FirBasedSymbol<*>).fir as? FirJavaMethod ?: error("Can't make enhancement for $original")
|
||||
|
||||
val memberContext = context.copyWithNewDefaultTypeQualifiers(
|
||||
typeQualifierResolver, jsr305State, firMethod.annotations
|
||||
)
|
||||
// TODO: When loading method as an override for a property, all annotations are stick to its getter
|
||||
// if (this is FirProperty && getter !is FirDefaultPropertyAccessor)
|
||||
// getter
|
||||
// else
|
||||
// this
|
||||
val memberContext = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, firMethod.annotations)
|
||||
|
||||
val predefinedEnhancementInfo =
|
||||
SignatureBuildingComponents.signature(owner.symbol.classId, firMethod.computeJvmDescriptor()).let { signature ->
|
||||
@@ -95,7 +128,6 @@ class JavaClassEnhancementScope(
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
val symbol = FirFunctionSymbol(original.callableId)
|
||||
with(firMethod) {
|
||||
FirMemberFunctionImpl(
|
||||
@@ -177,19 +209,17 @@ class JavaClassEnhancementScope(
|
||||
}
|
||||
|
||||
private fun enhanceReturnType(
|
||||
ownerFunction: FirJavaMethod,
|
||||
owner: FirCallableMember,
|
||||
memberContext: FirJavaEnhancementContext,
|
||||
predefinedEnhancementInfo: PredefinedFunctionEnhancementInfo?
|
||||
): FirResolvedTypeRef {
|
||||
val signatureParts = ownerFunction.parts(
|
||||
val signatureParts = owner.parts(
|
||||
typeQualifierResolver,
|
||||
typeContainer = ownerFunction, isCovariant = true,
|
||||
typeContainer = owner, isCovariant = true,
|
||||
containerContext = memberContext,
|
||||
containerApplicabilityType =
|
||||
if (false) // TODO: this.safeAs<FirProperty>()?.isJavaField == true
|
||||
AnnotationTypeQualifierResolver.QualifierApplicabilityType.FIELD
|
||||
else
|
||||
AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE
|
||||
if (owner is FirJavaField) AnnotationTypeQualifierResolver.QualifierApplicabilityType.FIELD
|
||||
else AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE
|
||||
) { it.returnTypeRef }.enhance(jsr305State, predefinedEnhancementInfo?.returnTypeInfo)
|
||||
return signatureParts.type
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractProviderBasedScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
@@ -97,4 +98,15 @@ class JavaClassUseSiteScope(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction {
|
||||
val seen = mutableSetOf<ConePropertySymbol>()
|
||||
if (!declaredMemberScope.processPropertiesByName(name) {
|
||||
seen += it
|
||||
processor(it)
|
||||
}
|
||||
) return ProcessorAction.STOP
|
||||
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user