From d4af35d7947b9e2234b82aa7d7e7b82541595137 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 29 Oct 2019 18:08:44 +0300 Subject: [PATCH] FIR: add substitution for Java fields --- .../java/scopes/JavaClassEnhancementScope.kt | 2 +- .../scopes/impl/FirClassSubstitutionScope.kt | 48 +++++++++- .../diagnostics/j+k/FieldSubstitution.txt | 2 +- .../fir/declarations/impl/FirFieldImpl.kt | 92 +++++++++++++++++++ .../fir/tree/generator/FirTreeBuilder.kt | 2 +- .../generator/ImplementationConfigurator.kt | 14 ++- ...rtCastOnFieldReceiverOfGenericType.fir.txt | 4 +- 7 files changed, 153 insertions(+), 11 deletions(-) create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt index 208b2a5da01..b6bf054714e 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt @@ -77,7 +77,7 @@ class JavaClassEnhancementScope( name: Name ): FirCallableSymbol<*> { when (val firElement = original.fir) { - is FirJavaField -> { + is FirField -> { if (firElement.returnTypeRef !is FirJavaTypeRef) return original val memberContext = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, firElement.annotations) val newReturnTypeRef = enhanceReturnType(firElement, emptyList(), memberContext, null) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt index 7ec82ce1751..7ee2d839d7e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt @@ -6,8 +6,10 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirField import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.declarations.impl.FirFieldImpl import org.jetbrains.kotlin.fir.declarations.impl.FirPropertyImpl import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl @@ -33,6 +35,7 @@ class FirClassSubstitutionScope( private val fakeOverrideFunctions = mutableMapOf, FirFunctionSymbol<*>>() private val fakeOverrideProperties = mutableMapOf() + private val fakeOverrideFields = mutableMapOf() private val substitutor = substitutorByMap(substitution) @@ -49,11 +52,18 @@ class FirClassSubstitutionScope( override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> ProcessorAction): ProcessorAction { return useSiteMemberScope.processPropertiesByName(name) process@{ original -> - if (original is FirPropertySymbol) { - val property = fakeOverrideProperties.getOrPut(original) { createFakeOverrideProperty(original) } - processor(property) - } else { - processor(original) + when (original) { + is FirPropertySymbol -> { + val property = fakeOverrideProperties.getOrPut(original) { createFakeOverrideProperty(original) } + processor(property) + } + is FirFieldSymbol -> { + val field = fakeOverrideFields.getOrPut(original) { createFakeOverrideField(original) } + processor(field) + } + else -> { + processor(original) + } } } } @@ -104,6 +114,15 @@ class FirClassSubstitutionScope( return createFakeOverrideProperty(session, member, original, newReceiverType, newReturnType) } + private fun createFakeOverrideField(original: FirFieldSymbol): FirFieldSymbol { + val member = original.fir + + val returnType = typeCalculator.tryCalculateReturnType(member).type + val newReturnType = returnType.substitute() ?: return original + + return createFakeOverrideField(session, member, original, newReturnType) + } + companion object { fun createFakeOverrideFunction( session: FirSession, @@ -176,6 +195,25 @@ class FirClassSubstitutionScope( } return symbol } + + fun createFakeOverrideField( + session: FirSession, + baseField: FirField, + baseSymbol: FirFieldSymbol, + newReturnType: ConeKotlinType? = null + ): FirFieldSymbol { + val symbol = FirFieldSymbol(baseSymbol.callableId) + with(baseField) { + FirFieldImpl( + source, session, + baseField.returnTypeRef.withReplacedConeType(newReturnType), + name, symbol, isVar, baseField.status + ).apply { + resolvePhase = baseField.resolvePhase + } + } + return symbol + } } } diff --git a/compiler/fir/resolve/testData/diagnostics/j+k/FieldSubstitution.txt b/compiler/fir/resolve/testData/diagnostics/j+k/FieldSubstitution.txt index 852203eaf5d..a5a1acc2cac 100644 --- a/compiler/fir/resolve/testData/diagnostics/j+k/FieldSubstitution.txt +++ b/compiler/fir/resolve/testData/diagnostics/j+k/FieldSubstitution.txt @@ -5,7 +5,7 @@ FILE: Derived.kt } public final fun test(): R|kotlin/Unit| { - this@R|/JavaClass|.R|/JavaClass.myHost|.# + this@R|/JavaClass|.R|/JavaClass.myHost|.R|kotlin/String.length| } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt new file mode 100644 index 00000000000..3dceaa15e2f --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt @@ -0,0 +1,92 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.declarations.impl + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus +import org.jetbrains.kotlin.fir.declarations.FirField +import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement +import org.jetbrains.kotlin.fir.symbols.impl.FirDelegateFieldSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource +import org.jetbrains.kotlin.fir.visitors.* + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ + +class FirFieldImpl( + override val source: FirSourceElement?, + override val session: FirSession, + override var returnTypeRef: FirTypeRef, + override val name: Name, + override val symbol: FirVariableSymbol, + override val isVar: Boolean, + override var status: FirDeclarationStatus +) : FirField(), FirAbstractAnnotatedElement { + override var resolvePhase: FirResolvePhase = FirResolvePhase.DECLARATIONS + override val receiverTypeRef: FirTypeRef? get() = null + override val initializer: FirExpression? get() = null + override val delegate: FirExpression? get() = null + override val delegateFieldSymbol: FirDelegateFieldSymbol? get() = null + override val isVal: Boolean get() = !isVar + override val getter: FirPropertyAccessor? get() = null + override val setter: FirPropertyAccessor? get() = null + override val annotations: MutableList = mutableListOf() + override val typeParameters: MutableList = mutableListOf() + override var containerSource: DeserializedContainerSource? = null + + init { + symbol.bind(this) + delegateFieldSymbol?.bind(this) + } + + override fun acceptChildren(visitor: FirVisitor, data: D) { + returnTypeRef.accept(visitor, data) + annotations.forEach { it.accept(visitor, data) } + typeParameters.forEach { it.accept(visitor, data) } + status.accept(visitor, data) + } + + override fun transformChildren(transformer: FirTransformer, data: D): FirFieldImpl { + transformReturnTypeRef(transformer, data) + transformOtherChildren(transformer, data) + return this + } + + override fun transformReturnTypeRef(transformer: FirTransformer, data: D): FirFieldImpl { + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + return this + } + + override fun transformGetter(transformer: FirTransformer, data: D): FirFieldImpl { + return this + } + + override fun transformSetter(transformer: FirTransformer, data: D): FirFieldImpl { + return this + } + + override fun transformOtherChildren(transformer: FirTransformer, data: D): FirFieldImpl { + annotations.transformInplace(transformer, data) + typeParameters.transformInplace(transformer, data) + status = status.transformSingle(transformer, data) + return this + } + + override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) { + resolvePhase = newResolvePhase + } +} diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt index 77bf3ef3522..f3cd27fcbbc 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt @@ -39,7 +39,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() { val variable = element("Variable", Declaration, callableDeclaration, namedDeclaration, statement) val valueParameter = element("ValueParameter", Declaration, variable) val property = element("Property", Declaration, variable, controlFlowGraphOwner, typeParametersOwner, callableMemberDeclaration) - val field = element("Field", Declaration, variable, callableMemberDeclaration) // TODO: add noImpl + val field = element("Field", Declaration, variable, callableMemberDeclaration) val classLikeDeclaration = element("ClassLikeDeclaration", Declaration, declaration, statement, symbolOwner) val klass = element("Class", Declaration, classLikeDeclaration, statement, annotationContainer) val regularClass = element("RegularClass", Declaration, memberDeclaration, typeParametersOwner, klass) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index 56fac0ae727..2a4483f108a 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -49,7 +49,6 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() noImpl(declarationStatus) noImpl(resolvedDeclarationStatus) - noImpl(field) val modifiableClass = impl(klass, "FirModifiableClass") @@ -280,6 +279,19 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() useTypes(backingFieldSymbolType, delegateFieldSymbolType) } + impl(field) { + default("isVal") { + value = "!isVar" + withGetter = true + } + + default("resolvePhase") { + value = "FirResolvePhase.DECLARATIONS" + } + + defaultNull("delegateFieldSymbol", "receiverTypeRef", "initializer", "delegate", "getter", "setter", withGetter = true) + } + impl(namedArgumentExpression) { default("typeRef") { delegate = "expression" diff --git a/compiler/testData/ir/irText/types/smartCastOnFieldReceiverOfGenericType.fir.txt b/compiler/testData/ir/irText/types/smartCastOnFieldReceiverOfGenericType.fir.txt index 33675caf217..50530520130 100644 --- a/compiler/testData/ir/irText/types/smartCastOnFieldReceiverOfGenericType.fir.txt +++ b/compiler/testData/ir/irText/types/smartCastOnFieldReceiverOfGenericType.fir.txt @@ -7,7 +7,7 @@ FILE fqName: fileName:/smartCastOnFieldReceiverOfGenericType.kt GET_VAR 'a: kotlin.Any declared in .testSetField' type=kotlin.Any origin=null TYPE_OP type=kotlin.String origin=CAST typeOperand=kotlin.String GET_VAR 'b: kotlin.Any declared in .testSetField' type=kotlin.Any origin=null - SET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:value type:T of .JCell? visibility:public' type=kotlin.Unit origin=null + SET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:value type:kotlin.String? visibility:public' type=kotlin.Unit origin=null receiver: GET_VAR 'a: kotlin.Any declared in .testSetField' type=.JCell origin=null value: GET_VAR 'b: kotlin.Any declared in .testSetField' type=kotlin.String origin=null FUN name:testGetField visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.String @@ -16,5 +16,5 @@ FILE fqName: fileName:/smartCastOnFieldReceiverOfGenericType.kt TYPE_OP type=.JCell origin=CAST typeOperand=.JCell GET_VAR 'a: kotlin.Any declared in .testGetField' type=kotlin.Any origin=null RETURN type=kotlin.Nothing from='public final fun testGetField (a: kotlin.Any): kotlin.String declared in ' - GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:value type:T of .JCell? visibility:public' type=T of .JCell? origin=GET_PROPERTY + GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:value type:kotlin.String? visibility:public' type=kotlin.String? origin=GET_PROPERTY receiver: GET_VAR 'a: kotlin.Any declared in .testGetField' type=.JCell origin=null