From 06cb24db7cfedf95cf4501494c4022c546d6aad8 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 10 Apr 2018 18:17:49 +0300 Subject: [PATCH] FIR builder: do various stub-based optimizations #KT-24090 Fixed --- .../kotlin/fir/builder/RawFirBuilder.kt | 70 ++++++++++--------- .../rawBuilder/declarations/derivedClass.txt | 2 +- .../rawBuilder/declarations/nestedClass.txt | 2 +- .../testData/fir/resolve/derivedClass.txt | 2 +- .../fir/resolve/multifile/Annotations.txt | 2 +- compiler/testData/fir/resolve/nestedClass.txt | 2 +- 6 files changed, 42 insertions(+), 38 deletions(-) diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index ed045526f17..b412ed0c2b0 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -24,14 +24,13 @@ import org.jetbrains.kotlin.fir.types.FirType import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier -import org.jetbrains.kotlin.psi.psiUtil.modalityModifierType -import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType import org.jetbrains.kotlin.types.Variance class RawFirBuilder(val session: FirSession) { @@ -43,26 +42,24 @@ class RawFirBuilder(val session: FirSession) { } private val KtModifierListOwner.visibility: Visibility - get() { - val modifierType = visibilityModifierType() - return when (modifierType) { - KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC - KtTokens.PROTECTED_KEYWORD -> Visibilities.PROTECTED - KtTokens.INTERNAL_KEYWORD -> Visibilities.INTERNAL - KtTokens.PRIVATE_KEYWORD -> Visibilities.PRIVATE - else -> Visibilities.UNKNOWN + get() = with(modifierList) { + when { + this == null -> Visibilities.UNKNOWN + hasModifier(PRIVATE_KEYWORD) -> Visibilities.PRIVATE + hasModifier(PUBLIC_KEYWORD) -> Visibilities.PUBLIC + hasModifier(PROTECTED_KEYWORD) -> Visibilities.PROTECTED + else -> if (hasModifier(INTERNAL_KEYWORD)) Visibilities.INTERNAL else Visibilities.UNKNOWN } } private val KtDeclaration.modality: Modality? - get() { - val modifierType = modalityModifierType() - return when (modifierType) { - KtTokens.FINAL_KEYWORD -> Modality.FINAL - KtTokens.SEALED_KEYWORD -> Modality.SEALED - KtTokens.ABSTRACT_KEYWORD -> Modality.ABSTRACT - KtTokens.OPEN_KEYWORD -> Modality.OPEN - else -> null + get() = with(modifierList) { + when { + this == null -> null + hasModifier(FINAL_KEYWORD) -> Modality.FINAL + hasModifier(SEALED_KEYWORD) -> Modality.SEALED + hasModifier(ABSTRACT_KEYWORD) -> Modality.ABSTRACT + else -> if (hasModifier(OPEN_KEYWORD)) Modality.OPEN else null } } @@ -91,11 +88,16 @@ class RawFirBuilder(val session: FirSession) { private fun KtTypeReference?.toFirOrErrorType(): FirType = convertSafe() ?: FirErrorTypeImpl(session, this, if (this == null) "Incomplete code" else "Conversion failed") - private fun KtExpression?.toFirBody(): FirBody? = - convertSafe()?.let { it as? FirBody ?: FirExpressionBodyImpl(session, it) } + private fun KtDeclarationWithBody.buildFirBody(): FirBody? = + when { + !hasBody() -> null + hasBlockBody() -> FirBlockBodyImpl(session, this) + else -> FirExpressionBodyImpl(session, FirExpressionStub(session, null)) + } - private fun KtExpression?.toFirExpression(): FirExpression = + private fun ValueArgument?.toFirExpression(): FirExpression = with(this as? KtElement) { convertSafe() ?: FirErrorExpressionImpl(session, this) + } private fun KtPropertyAccessor?.toFirPropertyAccessor( property: KtProperty, @@ -119,7 +121,7 @@ class RawFirBuilder(val session: FirSession) { } else { returnTypeReference.toFirOrUnitType() }, - bodyExpression.toFirBody() + this.buildFirBody() ) extractAnnotationsTo(firAccessor) extractValueParametersTo(firAccessor, propertyType) @@ -139,7 +141,7 @@ class RawFirBuilder(val session: FirSession) { defaultType != null -> defaultType else -> null.toFirOrErrorType() }, - defaultValue?.convert(), + if (hasDefaultValue()) FirExpressionStub(session, this) else null, isCrossinline = hasModifier(KtTokens.CROSSINLINE_KEYWORD), isNoinline = hasModifier(KtTokens.NOINLINE_KEYWORD), isVararg = isVarArg @@ -163,7 +165,7 @@ class RawFirBuilder(val session: FirSession) { isLateInit = false, receiverType = null, returnType = type, - isVar = valOrVarKeyword?.node?.elementType == KtTokens.VAR_KEYWORD, + isVar = isMutable, initializer = null, getter = FirDefaultPropertyGetter(session, this, type), setter = FirDefaultPropertySetter(session, this, type), @@ -196,7 +198,7 @@ class RawFirBuilder(val session: FirSession) { private fun KtCallElement.extractArgumentsTo(container: FirAbstractCall) { for (argument in this.valueArguments) { - container.arguments += argument.getArgumentExpression().toFirExpression() + container.arguments += argument.toFirExpression() } } @@ -215,7 +217,7 @@ class RawFirBuilder(val session: FirSession) { val type = superTypeListEntry.typeReference.toFirOrErrorType() container.superTypes += FirDelegatedTypeImpl( type, - superTypeListEntry.delegateExpression.convertSafe() + FirExpressionStub(session, superTypeListEntry) ) } } @@ -233,7 +235,8 @@ class RawFirBuilder(val session: FirSession) { FirErrorTypeImpl(session, constructorCallee, "Not implemented yet"), isThis = false ).apply { - superTypeCallEntry.extractArgumentsTo(this) + // TODO: arguments are not needed for light classes, but will be needed later + //superTypeCallEntry.extractArgumentsTo(this) } } val firConstructor = FirPrimaryConstructorImpl( @@ -385,7 +388,7 @@ class RawFirBuilder(val session: FirSession) { } else { typeReference.toFirOrImplicitType() }, - function.bodyExpression.toFirBody() + function.buildFirBody() ) function.extractAnnotationsTo(firFunction) function.extractTypeParametersTo(firFunction) @@ -401,7 +404,7 @@ class RawFirBuilder(val session: FirSession) { constructor, constructor.visibility, constructor.getDelegationCall().convert(), - constructor.bodyExpression.toFirBody() + constructor.buildFirBody() ) constructor.extractAnnotationsTo(firConstructor) constructor.extractValueParametersTo(firConstructor) @@ -415,7 +418,8 @@ class RawFirBuilder(val session: FirSession) { FirErrorTypeImpl(session, call, "Not implemented yet"), call.isCallToThis || call.isImplicit ) - call.extractArgumentsTo(firConstructorCall) + // TODO: arguments are not needed for light classes, but will be needed later + // call.extractArgumentsTo(firConstructorCall) return firConstructorCall } @@ -423,7 +427,7 @@ class RawFirBuilder(val session: FirSession) { return FirAnonymousInitializerImpl( session, initializer, - initializer.body.toFirBody() + FirBlockBodyImpl(session, initializer) ) } @@ -442,10 +446,10 @@ class RawFirBuilder(val session: FirSession) { property.receiverTypeReference.convertSafe(), propertyType, property.isVar, - property.initializer?.convert(), + if (property.hasInitializer()) FirExpressionStub(session, property) else null, property.getter.toFirPropertyAccessor(property, propertyType, isGetter = true), property.setter.toFirPropertyAccessor(property, propertyType, isGetter = false), - property.delegateExpression?.convert() + if (property.hasDelegate()) FirExpressionStub(session, property) else null ) property.extractAnnotationsTo(firProperty) property.extractTypeParametersTo(firProperty) diff --git a/compiler/testData/fir/rawBuilder/declarations/derivedClass.txt b/compiler/testData/fir/rawBuilder/declarations/derivedClass.txt index 5a718db4fd5..54b1d23c76a 100644 --- a/compiler/testData/fir/rawBuilder/declarations/derivedClass.txt +++ b/compiler/testData/fir/rawBuilder/declarations/derivedClass.txt @@ -7,7 +7,7 @@ FILE: derivedClass.kt } public? final class Derived : Base { - public? constructor(x: T): super(STUB) + public? constructor(x: T): super() } public? final? function create(x: T): Derived { diff --git a/compiler/testData/fir/rawBuilder/declarations/nestedClass.txt b/compiler/testData/fir/rawBuilder/declarations/nestedClass.txt index 81d2912f5f2..d2b21c17e55 100644 --- a/compiler/testData/fir/rawBuilder/declarations/nestedClass.txt +++ b/compiler/testData/fir/rawBuilder/declarations/nestedClass.txt @@ -8,7 +8,7 @@ FILE: nestedClass.kt } public? final class Outer { public? final class Derived : Base { - public? constructor(s: String): super(STUB) + public? constructor(s: String): super() } diff --git a/compiler/testData/fir/resolve/derivedClass.txt b/compiler/testData/fir/resolve/derivedClass.txt index 2983f813880..f8c491e58a2 100644 --- a/compiler/testData/fir/resolve/derivedClass.txt +++ b/compiler/testData/fir/resolve/derivedClass.txt @@ -7,7 +7,7 @@ FILE: derivedClass.kt } public? final class Derived : R|Base| { - public? constructor(x: R|T|): super(STUB) + public? constructor(x: R|T|): super() } public? final? function create(x: R|T|): R|Derived| { diff --git a/compiler/testData/fir/resolve/multifile/Annotations.txt b/compiler/testData/fir/resolve/multifile/Annotations.txt index eca2b81f360..bd697ddcfc1 100644 --- a/compiler/testData/fir/resolve/multifile/Annotations.txt +++ b/compiler/testData/fir/resolve/multifile/Annotations.txt @@ -21,7 +21,7 @@ FILE: Annotations.kt STUB } - @R|annotations/WithString|(STUB) public? constructor(): this(STUB) + @R|annotations/WithString|(STUB) public? constructor(): this() } @R|annotations/WithInt|(STUB) @R|annotations/WithInt|(STUB) public? final typealias Third = @R|annotations/Simple|() R|test/Second| diff --git a/compiler/testData/fir/resolve/nestedClass.txt b/compiler/testData/fir/resolve/nestedClass.txt index bd707f7ec65..47f1172f638 100644 --- a/compiler/testData/fir/resolve/nestedClass.txt +++ b/compiler/testData/fir/resolve/nestedClass.txt @@ -8,7 +8,7 @@ FILE: nestedClass.kt } public? final class Outer { public? final class Derived : R|Base| { - public? constructor(s: R|kotlin/String|): super(STUB) + public? constructor(s: R|kotlin/String|): super() }