Fir2Ir: deal with Java fields in FirIrProvider

This commit is contained in:
Georgy Bronnikov
2022-02-11 22:08:38 +03:00
committed by Alexander Udalov
parent 5605463ecf
commit ad625a4631
5 changed files with 72 additions and 22 deletions
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
@@ -282,30 +283,39 @@ open class FirJvmMangleComputer(
anonymousObject.mangleSimpleDeclaration("<anonymous>")
}
override fun visitProperty(property: FirProperty, data: Boolean) {
isRealExpect = isRealExpect or property.isExpect
typeParameterContainer.add(property)
property.visitParent()
override fun visitVariable(variable: FirVariable, data: Boolean) {
isRealExpect = isRealExpect or variable.isExpect
typeParameterContainer.add(variable)
variable.visitParent()
val isStaticProperty = property.isStatic
val isStaticProperty = variable.isStatic
if (isStaticProperty) {
builder.appendSignature(MangleConstant.STATIC_MEMBER_MARK)
}
property.receiverTypeRef?.let {
variable.receiverTypeRef?.let {
builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX)
mangleType(builder, it.coneType)
}
property.typeParameters.withIndex().toList().collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { (index, typeParameter) ->
mangleTypeParameter(this, typeParameter, index)
variable.typeParameters.withIndex().toList().collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { (index, typeParameter) ->
mangleTypeParameter(this, typeParameter.symbol.fir, index)
}
builder.append(property.name.asString())
builder.append(variable.name.asString())
}
override fun visitField(field: FirField, data: Boolean) =
field.mangleSimpleDeclaration(field.name.asString())
override fun visitProperty(property: FirProperty, data: Boolean) {
visitVariable(property, data)
}
override fun visitField(field: FirField, data: Boolean) {
if (field is FirJavaField) {
field.mangleSimpleDeclaration(field.name.asString())
} else {
visitVariable(field, data)
}
}
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Boolean) {
enumEntry.mangleSimpleDeclaration(enumEntry.name.asString())
@@ -1021,14 +1021,29 @@ class Fir2IrDeclarationStorage(
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
): IrField = convertCatching(field) {
val type = typeRef.toIrType()
val signature = signatureComposer.composeSignature(field)
return field.convertWithOffsets { startOffset, endOffset ->
irFactory.createField(
startOffset, endOffset, origin, IrFieldSymbolImpl(),
field.name, type, components.visibilityConverter.convertToDescriptorVisibility(field.visibility),
isFinal = field.modality == Modality.FINAL,
isExternal = false,
isStatic = field.isStatic
).apply {
if (signature != null) {
symbolTable.declareField(
signature, symbolFactory = { IrFieldPublicSymbolImpl(signature) }
) { symbol ->
irFactory.createField(
startOffset, endOffset, origin, symbol,
field.name, type, components.visibilityConverter.convertToDescriptorVisibility(field.visibility),
isFinal = field.modality == Modality.FINAL,
isExternal = false,
isStatic = field.isStatic
)
}
} else {
irFactory.createField(
startOffset, endOffset, origin, IrFieldSymbolImpl(),
field.name, type, components.visibilityConverter.convertToDescriptorVisibility(field.visibility),
isFinal = field.modality == Modality.FINAL,
isExternal = false,
isStatic = field.isStatic
)
}.apply {
fieldCache[field] = this
val initializer = field.initializer
if (initializer is FirConstExpression<*>) {
@@ -1445,16 +1460,16 @@ class Fir2IrDeclarationStorage(
else -> parentOrigin
}
fun getIrFieldSymbol(firFieldSymbol: FirFieldSymbol): IrSymbol {
fun getIrFieldSymbol(firFieldSymbol: FirFieldSymbol): IrFieldSymbol {
val fir = firFieldSymbol.fir
val irProperty = fieldCache[fir] ?: run {
val irField = fieldCache[fir] ?: run {
// In case of type parameters from the parent as the field's return type, find the parent ahead to cache type parameters.
val irParent = findIrParent(fir)
createIrField(fir).apply {
setAndModifyParent(irParent)
}
}
return irProperty.symbol
return irField.symbol
}
fun getIrBackingFieldSymbol(firBackingFieldSymbol: FirBackingFieldSymbol): IrSymbol {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
@@ -116,6 +117,9 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
} else functionSymbol.fir
functions.add(function)
}
firClass.staticScopeForCallables?.processFunctionsByName(lastName) { functionSymbol ->
functions.add(functionSymbol.fir)
}
firCandidates = functions
}
SymbolKind.PROPERTY_SYMBOL -> {
@@ -132,6 +136,18 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
}
firCandidates = properties
}
SymbolKind.FIELD_SYMBOL -> {
parent = classifierStorage.getIrClassSymbol(firClass.symbol).owner
val lastName = Name.guessByFirstCharacter(nameSegments.last())
val fields = mutableListOf<FirVariable>()
scope.processPropertiesByName(lastName) { propertySymbol ->
fields.add(propertySymbol.fir)
}
firClass.staticScopeForCallables?.processPropertiesByName(lastName) { propertySymbol ->
fields.add(propertySymbol.fir)
}
firCandidates = fields
}
else -> {
val lastName = nameSegments.last()
firCandidates = firClass.declarations.filter { it is FirCallableDeclaration && it.symbol.name.asString() == lastName }
@@ -160,7 +176,7 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
}
SymbolKind.FIELD_SYMBOL -> {
val firField = firDeclaration as FirField
declarationStorage.getOrCreateIrPropertyByPureField(firField, parent)
declarationStorage.getIrFieldSymbol(firField.symbol).owner
}
else -> error("Don't know how to deal with this symbol kind: $kind")
}
@@ -176,4 +192,7 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
with(fir2IrComponents.signatureComposer.mangler) { candidate.signatureMangle(compatibleMode = false) == hash }
}
}
private val FirClass.staticScopeForCallables: FirScope?
get() = scopeProvider.getStaticMemberScopeForCallables(this, fir2IrComponents.session, fir2IrComponents.scopeSession)
}
@@ -66,6 +66,11 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat
setExpected(property.isExpect)
}
override fun visitField(field: FirField, data: Any?) {
hashId = mangler.run { field.signatureMangle(compatibleMode = false) }
setExpected(field.isExpect)
}
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Any?) {
setExpected(enumEntry.isExpect)
}
@@ -20,6 +20,7 @@ fun IrSymbol.kind(): BinarySymbolData.SymbolKind {
is IrConstructorSymbol -> BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL
is IrSimpleFunctionSymbol -> BinarySymbolData.SymbolKind.FUNCTION_SYMBOL
is IrPropertySymbol -> BinarySymbolData.SymbolKind.PROPERTY_SYMBOL
is IrFieldSymbol -> BinarySymbolData.SymbolKind.FIELD_SYMBOL
is IrEnumEntrySymbol -> BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL
is IrTypeAliasSymbol -> BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL
is IrTypeParameterSymbol -> BinarySymbolData.SymbolKind.TYPE_PARAMETER_SYMBOL