diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt index ec5a3eb69a7..2c8e2ee9003 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.components.* import org.jetbrains.kotlin.analysis.api.descriptors.components.* import org.jetbrains.kotlin.analysis.api.impl.base.components.KtAnalysisScopeProviderImpl +import org.jetbrains.kotlin.analysis.api.impl.base.components.KtRendererProviderImpl import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolProvider @@ -41,7 +42,7 @@ class KtFe10AnalysisSession( override val symbolDeclarationOverridesProviderImpl: KtSymbolDeclarationOverridesProvider = KtFe10SymbolDeclarationOverridesProvider(this) override val referenceShortenerImpl: KtReferenceShortener = KtFe10ReferenceShortener(this) - override val symbolDeclarationRendererProviderImpl: KtSymbolDeclarationRendererProvider = KtFe10SymbolDeclarationRendererProvider(this) + override val symbolDeclarationRendererProviderImpl: KtSymbolDeclarationRendererProvider = KtRendererProviderImpl(this, token) override val expressionTypeProviderImpl: KtExpressionTypeProvider = KtFe10ExpressionTypeProvider(this) override val psiTypeProviderImpl: KtPsiTypeProvider = KtFe10PsiTypeProvider(this) override val typeProviderImpl: KtTypeProvider = KtFe10TypeProvider(this) diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolDeclarationRendererProvider.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolDeclarationRendererProvider.kt deleted file mode 100644 index 9d8fce4c8a8..00000000000 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolDeclarationRendererProvider.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2010-2021 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.analysis.api.descriptors.components - -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.api.components.KtSymbolDeclarationRendererProvider -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions -import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession -import org.jetbrains.kotlin.analysis.api.descriptors.components.base.Fe10KtAnalysisSessionComponent -import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.getSymbolDescriptor -import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.render -import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type -import org.jetbrains.kotlin.analysis.api.descriptors.utils.KtFe10TypeRenderer -import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol -import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken -import org.jetbrains.kotlin.analysis.api.signatures.KtCallableSignature -import org.jetbrains.kotlin.analysis.api.types.KtType -import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint - -internal class KtFe10SymbolDeclarationRendererProvider( - override val analysisSession: KtFe10AnalysisSession -) : KtSymbolDeclarationRendererProvider(), Fe10KtAnalysisSessionComponent { - override val token: KtLifetimeToken - get() = analysisSession.token - - override fun renderDeclaration(symbol: KtDeclarationSymbol, options: KtDeclarationRendererOptions): String { - val descriptor = getSymbolDescriptor(symbol) - if (descriptor != null) { - return descriptor.render(analysisContext, options) - } - - // Rendering for unresolved symbols is not implemented - return "" - } - - override fun render(type: KtType, options: KtTypeRendererOptions): String { - require(type is KtFe10Type) - return prettyPrint { KtFe10TypeRenderer(options).render(type.type, this) } - } -} \ No newline at end of file diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeProvider.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeProvider.kt index 614a70c8f08..a6529fcccf0 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeProvider.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeProvider.kt @@ -67,9 +67,14 @@ internal class KtFe10TypeProvider( override val builtinTypes: KtBuiltinTypes by lazy(LazyThreadSafetyMode.PUBLICATION) { KtFe10BuiltinTypes(analysisContext) } - override fun approximateToSuperPublicDenotableType(type: KtType): KtType? { + override fun approximateToSuperPublicDenotableType(type: KtType, approximateLocalTypes: Boolean): KtType? { require(type is KtFe10Type) - return typeApproximator.approximateToSuperType(type.type, PublicApproximatorConfiguration)?.toKtType(analysisContext) + return typeApproximator.approximateToSuperType(type.type, PublicApproximatorConfiguration(approximateLocalTypes))?.toKtType(analysisContext) + } + + override fun approximateToSubPublicDenotableType(type: KtType, approximateLocalTypes: Boolean): KtType? { + require(type is KtFe10Type) + return typeApproximator.approximateToSubType(type.type, PublicApproximatorConfiguration(approximateLocalTypes))?.toKtType(analysisContext) } override fun buildSelfClassType(symbol: KtNamedClassOrObjectSymbol): KtType { diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10Renderer.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10Renderer.kt index 25ab240320f..73402910dec 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10Renderer.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10Renderer.kt @@ -73,7 +73,7 @@ internal class KtFe10Renderer( private fun KtFe10RendererConsumer.renderType(type: KotlinType, shouldApproximate: Boolean = false) { if (shouldApproximate) { - val approximatedType = typeApproximator.approximateToSuperType(type.unwrap(), PublicApproximatorConfiguration) + val approximatedType = typeApproximator.approximateToSuperType(type.unwrap(), PublicApproximatorConfiguration(localTypes = true)) ?: type.takeIf { it.constructor.declarationDescriptor?.name != SpecialNames.NO_NAME_PROVIDED } ?: analysisContext.builtIns.anyType diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/PublicApproximatorConfiguration.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/PublicApproximatorConfiguration.kt index 150f75fe4d1..1403553d8ec 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/PublicApproximatorConfiguration.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/PublicApproximatorConfiguration.kt @@ -8,11 +8,10 @@ package org.jetbrains.kotlin.analysis.api.descriptors.utils import org.jetbrains.kotlin.types.TypeApproximatorConfiguration @Suppress("SpellCheckingInspection") -internal object PublicApproximatorConfiguration : TypeApproximatorConfiguration.AllFlexibleSameValue() { +internal class PublicApproximatorConfiguration(override val localTypes: Boolean) : TypeApproximatorConfiguration.AllFlexibleSameValue() { override val allFlexible: Boolean get() = false override val errorType: Boolean get() = true override val definitelyNotNullType: Boolean get() = false override val integerLiteralConstantType: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true - override val localTypes: Boolean get() = true } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt index 485464e7add..dae39ce6f8c 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt @@ -77,8 +77,7 @@ private constructor( override val importOptimizerImpl: KtImportOptimizer = KtFirImportOptimizer(token, firResolveSession) - override val symbolDeclarationRendererProviderImpl: KtSymbolDeclarationRendererProvider = - KtFirSymbolDeclarationRendererProvider(this, token) + override val symbolDeclarationRendererProviderImpl: KtSymbolDeclarationRendererProvider = KtFirRendererProvider(this, token) override val expressionInfoProviderImpl = KtFirExpressionInfoProvider(this, token) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirRendererProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirRendererProvider.kt new file mode 100644 index 00000000000..eb61e0bdc62 --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirRendererProvider.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2022 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.analysis.api.fir.components + +import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.fir.utils.firSymbol +import org.jetbrains.kotlin.analysis.api.impl.base.components.KtRendererProviderImpl +import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase + +@OptIn(KtAnalysisApiInternals::class) +internal class KtFirRendererProvider( + analysisSession: KtAnalysisSession, + token: KtLifetimeToken +) : KtRendererProviderImpl(analysisSession, token) { + override fun renderDeclaration(symbol: KtDeclarationSymbol, renderer: KtDeclarationRenderer): String { + symbol.firSymbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) + return super.renderDeclaration(symbol, renderer) + } +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationRendererProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationRendererProvider.kt deleted file mode 100644 index 265aebb607b..00000000000 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationRendererProvider.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2010-2021 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.analysis.api.fir.components - -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.api.components.KtSymbolDeclarationRendererProvider -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions -import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession -import org.jetbrains.kotlin.analysis.api.fir.renderer.ConeTypeIdeRenderer -import org.jetbrains.kotlin.analysis.api.fir.renderer.FirIdeRenderer -import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol -import org.jetbrains.kotlin.analysis.api.fir.types.KtFirType -import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken -import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol -import org.jetbrains.kotlin.analysis.api.types.KtType -import org.jetbrains.kotlin.fir.declarations.FirResolvePhase -import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase - -internal class KtFirSymbolDeclarationRendererProvider( - override val analysisSession: KtFirAnalysisSession, - override val token: KtLifetimeToken -) : KtSymbolDeclarationRendererProvider() { - - override fun render(type: KtType, options: KtTypeRendererOptions): String { - require(type is KtFirType) - return ConeTypeIdeRenderer(analysisSession.firResolveSession.useSiteFirSession, options).renderType(type.coneType) - } - - override fun renderDeclaration(symbol: KtDeclarationSymbol, options: KtDeclarationRendererOptions): String { - require(symbol is KtFirSymbol<*>) - symbol.firSymbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) - return FirIdeRenderer.render(symbol.firSymbol.fir, options, symbol.firSymbol.fir.moduleData.session) - } -} diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt index a5b01e1690d..44854e87791 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt @@ -51,13 +51,24 @@ internal class KtFirTypeProvider( ) : KtTypeProvider(), KtFirAnalysisSessionComponent { override val builtinTypes: KtBuiltinTypes = KtFirBuiltInTypes(rootModuleSession.builtinTypes, firSymbolBuilder, token) - override fun approximateToSuperPublicDenotableType(type: KtType): KtType? { + override fun approximateToSuperPublicDenotableType(type: KtType, approximateLocalTypes: Boolean): KtType? { require(type is KtFirType) val coneType = type.coneType val approximatedConeType = PublicTypeApproximator.approximateTypeToPublicDenotable( coneType, rootModuleSession, - approximateLocalTypes = true, + approximateLocalTypes = approximateLocalTypes, + ) + + return approximatedConeType?.asKtType() + } + + override fun approximateToSubPublicDenotableType(type: KtType, approximateLocalTypes: Boolean): KtType? { + require(type is KtFirType) + val coneType = type.coneType + val approximatedConeType = rootModuleSession.typeApproximator.approximateToSubType( + coneType, + PublicTypeApproximator.PublicApproximatorConfiguration(localTypes = approximateLocalTypes), ) return approximatedConeType?.asKtType() diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirTypeParameterSymbol.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirTypeParameterSymbol.kt index 5a2569f5e7d..d6fa949946e 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirTypeParameterSymbol.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirTypeParameterSymbol.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession import org.jetbrains.kotlin.fir.analysis.checkers.typeParameterSymbols import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol +import org.jetbrains.kotlin.fir.types.isNullableAny import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance @@ -41,7 +42,10 @@ internal class KtFirTypeParameterSymbol( override val name: Name get() = withValidityAssertion { firSymbol.name } override val upperBounds: List by cached { - firSymbol.resolvedBounds.map { type -> builder.typeBuilder.buildKtType(type) } + firSymbol.resolvedBounds.mapNotNull { type -> + if (type.isNullableAny) return@mapNotNull null + builder.typeBuilder.buildKtType(type) + } } override val variance: Variance get() = withValidityAssertion { firSymbol.variance } diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/KtRendererProvider.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/KtRendererProvider.kt new file mode 100644 index 00000000000..e5cbc1fb8fd --- /dev/null +++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/KtRendererProvider.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2022 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.analysis.api.impl.base.components + +import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.components.KtSymbolDeclarationRendererProvider +import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtRendererTypeApproximator +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint +import org.jetbrains.kotlin.types.Variance + +@KtAnalysisApiInternals +open class KtRendererProviderImpl( + override val analysisSession: KtAnalysisSession, + override val token: KtLifetimeToken +) : KtSymbolDeclarationRendererProvider() { + + override fun renderType(type: KtType, renderer: KtTypeRenderer, position: Variance): String { + return with(analysisSession) { + val approximatedType = KtRendererTypeApproximator.TO_DENNOTABLE.approximateType(type, position) + prettyPrint { renderer.renderType(approximatedType, this) } + } + } + + override fun renderDeclaration(symbol: KtDeclarationSymbol, renderer: KtDeclarationRenderer): String { + return with(analysisSession) { + prettyPrint { renderer.renderDeclaration(symbol, this) } + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/expressionTypeProvider/AbstractDeclarationReturnTypeTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/expressionTypeProvider/AbstractDeclarationReturnTypeTest.kt index 3dae84eb514..20491601d2e 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/expressionTypeProvider/AbstractDeclarationReturnTypeTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/expressionTypeProvider/AbstractDeclarationReturnTypeTest.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance abstract class AbstractDeclarationReturnTypeTest : AbstractAnalysisApiSingleFileTest() { override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { @@ -26,7 +27,7 @@ abstract class AbstractDeclarationReturnTypeTest : AbstractAnalysisApiSingleFile val returnType = declaration.getReturnKtType() append(declaration.getNameWithPositionString()) append(" : ") - appendLine(returnType.render()) + appendLine(returnType.render(position = Variance.INVARIANT)) } } return super.visitDeclaration(declaration, indent + 2) diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/expressionTypeProvider/AbstractHLExpressionTypeTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/expressionTypeProvider/AbstractHLExpressionTypeTest.kt index 7d121e0c937..afcb9f9a015 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/expressionTypeProvider/AbstractHLExpressionTypeTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/expressionTypeProvider/AbstractHLExpressionTypeTest.kt @@ -5,9 +5,9 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.expressionTypeProvider -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions -import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider +import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForDebug import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest +import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.KtExpression @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.psi.KtValueArgument import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance abstract class AbstractHLExpressionTypeTest : AbstractAnalysisApiSingleFileTest() { override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { @@ -32,7 +33,7 @@ abstract class AbstractHLExpressionTypeTest : AbstractAnalysisApiSingleFileTest( else -> null } ?: error("expect an expression but got ${selected.text}") val type = executeOnPooledThreadInReadAction { - analyseForTest(expression) { expression.getKtType()?.render(TYPE_RENDERING_OPTIONS) } + analyseForTest(expression) { expression.getKtType()?.render(renderer, position = Variance.INVARIANT) } } val actual = buildString { appendLine("expression: ${expression.text}") @@ -42,6 +43,6 @@ abstract class AbstractHLExpressionTypeTest : AbstractAnalysisApiSingleFileTest( } companion object { - private val TYPE_RENDERING_OPTIONS = KtTypeRendererOptions.DEFAULT.copy(renderUnresolvedTypeAsResolved = false) + private val renderer = KtTypeRendererForDebug.WITH_QUALIFIED_NAMES } } \ No newline at end of file diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiExpressionPsiTypeProviderTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiExpressionPsiTypeProviderTest.kt index ca13f1dd227..72ed94e9b2e 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiExpressionPsiTypeProviderTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiExpressionPsiTypeProviderTest.kt @@ -6,13 +6,14 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.psiTypeProvider import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest +import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance abstract class AbstractAnalysisApiExpressionPsiTypeProviderTest : AbstractAnalysisApiSingleFileTest(){ override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { @@ -22,7 +23,7 @@ abstract class AbstractAnalysisApiExpressionPsiTypeProviderTest : AbstractAnalys ?: error("Not a typable expression ${declarationAtCaret::class} ${declarationAtCaret.text}") val psiType = returnType.asPsiType(declarationAtCaret) buildString { - appendLine("KtType: ${returnType.render()}") + appendLine("KtType: ${returnType.render(position = Variance.INVARIANT)}") appendLine("PsiType: $psiType") } } diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt index 3cf3db32282..d47560c19d8 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt @@ -17,6 +17,8 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.services.TestModuleStructure import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull abstract class AbstractAnalysisApiPsiTypeProviderTest : AbstractAnalysisApiBasedTest() { override fun doTestByModuleStructure(moduleStructure: TestModuleStructure, testServices: TestServices) { @@ -31,7 +33,7 @@ abstract class AbstractAnalysisApiPsiTypeProviderTest : AbstractAnalysisApiBased executeOnPooledThreadInReadAction { analyze(declaration) { val ktType = declaration.getReturnKtType() - appendLine("KtType: ${ktType.render()}") + appendLine("KtType: ${ktType.render(position = Variance.INVARIANT)}") appendLine("PsiType: ${ktType.asPsiType(psiContext)}") } } diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/smartCastProvider/AbstractHLSmartCastInfoTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/smartCastProvider/AbstractHLSmartCastInfoTest.kt index 8b73149a13d..45004c76031 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/smartCastProvider/AbstractHLSmartCastInfoTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/smartCastProvider/AbstractHLSmartCastInfoTest.kt @@ -5,14 +5,15 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.smartCastProvider -import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest +import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance abstract class AbstractHLSmartCastInfoTest : AbstractAnalysisApiSingleFileTest() { override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { @@ -23,12 +24,12 @@ abstract class AbstractHLSmartCastInfoTest : AbstractAnalysisApiSingleFileTest() buildString { appendLine("expression: ${expression.text}") appendLine("isStable: ${smartCastInfo?.isStable}") - appendLine("smartCastType: ${smartCastInfo?.smartCastType?.render()}") + appendLine("smartCastType: ${smartCastInfo?.smartCastType?.render(position = Variance.INVARIANT)}") val receiverSmartCasts = expression.getImplicitReceiverSmartCast() for (receiverSmartCast in receiverSmartCasts) { appendLine("receiver: ${receiverSmartCast.kind}") - appendLine(" smartCastType: ${receiverSmartCast.type.render()}") + appendLine(" smartCastType: ${receiverSmartCast.type.render(position = Variance.INVARIANT)}") } } } diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/symbolDeclarationOverridesProvider/AbstractOverriddenDeclarationProviderTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/symbolDeclarationOverridesProvider/AbstractOverriddenDeclarationProviderTest.kt index 7b82a53302d..4010c41f3e4 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/symbolDeclarationOverridesProvider/AbstractOverriddenDeclarationProviderTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/symbolDeclarationOverridesProvider/AbstractOverriddenDeclarationProviderTest.kt @@ -6,12 +6,12 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.symbolDeclarationOverridesProvider import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions -import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider -import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedSingleModuleTest +import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForSource import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSyntheticJavaPropertySymbol +import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedSingleModuleTest +import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType import org.jetbrains.kotlin.psi.KtDeclaration @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance abstract class AbstractOverriddenDeclarationProviderTest : AbstractAnalysisApiBasedSingleModuleTest() { override fun doTestByFileStructure(ktFiles: List, module: TestModule, testServices: TestServices) { @@ -47,7 +48,7 @@ abstract class AbstractOverriddenDeclarationProviderTest : AbstractAnalysisApiBa symbol.valueParameters.forEachIndexed { index, parameter -> append(parameter.name.identifier) append(": ") - append(parameter.returnType.render(KtTypeRendererOptions.SHORT_NAMES)) + append(parameter.returnType.render(KtTypeRendererForSource.WITH_SHORT_NAMES, position = Variance.INVARIANT)) if (index != symbol.valueParameters.lastIndex) { append(", ") } @@ -55,7 +56,7 @@ abstract class AbstractOverriddenDeclarationProviderTest : AbstractAnalysisApiBa append(")") } append(": ") - append(symbol.returnType.render(KtTypeRendererOptions.SHORT_NAMES)) + append(symbol.returnType.render(KtTypeRendererForSource.WITH_SHORT_NAMES, position = Variance.INVARIANT)) } @Suppress("unused") diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/symbolDeclarationRenderer/AbstractRendererTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/symbolDeclarationRenderer/AbstractRendererTest.kt index 19768d1e4f8..2c779ba6ce9 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/symbolDeclarationRenderer/AbstractRendererTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/symbolDeclarationRenderer/AbstractRendererTest.kt @@ -5,9 +5,12 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.symbolDeclarationRenderer -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.bodies.KtRendererBodyMemberScopeSorter +import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForSource +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.KtClassifierBodyRenderer import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.psi.KtFile @@ -17,19 +20,24 @@ import org.jetbrains.kotlin.test.services.assertions abstract class AbstractRendererTest : AbstractAnalysisApiSingleFileTest() { override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { - val options = KtDeclarationRendererOptions.DEFAULT.copy( - approximateTypes = true, - renderClassMembers = true, - typeRendererOptions = KtTypeRendererOptions.SHORT_NAMES, - sortNestedDeclarations = true - ) + val renderer = KtDeclarationRendererForSource.WITH_SHORT_NAMES.with { + classifierBodyRenderer = KtClassifierBodyRenderer.BODY_WITH_MEMBERS + bodyMemberScopeSorter = object : KtRendererBodyMemberScopeSorter { + context(KtAnalysisSession) + override fun sortMembers(members: List, owner: KtSymbolWithMembers): List { + return KtRendererBodyMemberScopeSorter.ENUM_ENTRIES_AT_BEGINING + .sortMembers(members, owner) + .sortedBy { it.render() } + } + } + } val actual = executeOnPooledThreadInReadAction { buildString { ktFile.declarations.forEach { declaration -> analyseForTest(declaration) { val symbol = declaration.getSymbol() as? KtDeclarationSymbol ?: return@analyseForTest - append(symbol.render(options)) + append(symbol.render(renderer)) appendLine() appendLine() } diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/testUtils.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/testUtils.kt index 4bb7f3fceb4..77f8c02308c 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/testUtils.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/testUtils.kt @@ -10,11 +10,10 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.calls.KtCall import org.jetbrains.kotlin.analysis.api.calls.KtCallableMemberCall -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic import org.jetbrains.kotlin.analysis.api.impl.base.KtMapBackedSubstitutor -import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.containingDeclarationProvider.AbstractContainingDeclarationProviderByMemberScopeTest +import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForSource +import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.renderers.KtRendererModifierFilter import org.jetbrains.kotlin.analysis.api.scopes.KtScope import org.jetbrains.kotlin.analysis.api.signatures.KtCallableSignature import org.jetbrains.kotlin.analysis.api.signatures.KtFunctionLikeSignature @@ -26,6 +25,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.Variance import kotlin.reflect.KProperty1 import kotlin.reflect.KVisibility import kotlin.reflect.full.memberProperties @@ -118,15 +118,15 @@ internal fun KtAnalysisSession.prettyPrintSignature(signature: KtCallableSignatu when (signature) { is KtFunctionLikeSignature -> { append("fun ") - signature.receiverType?.let { append('.'); append(it.render()) } + signature.receiverType?.let { append('.'); append(it.render(position = Variance.INVARIANT)) } append((signature.symbol as KtNamedSymbol).name.asString()) printCollection(signature.valueParameters, prefix = "(", postfix = ")") { parameter -> append(parameter.name.asString()) append(": ") - append(parameter.returnType.render()) + append(parameter.returnType.render(position = Variance.INVARIANT)) } append(": ") - append(signature.returnType.render()) + append(signature.returnType.render(position = Variance.INVARIANT)) } is KtVariableLikeSignature -> { val symbol = signature.symbol @@ -134,10 +134,10 @@ internal fun KtAnalysisSession.prettyPrintSignature(signature: KtCallableSignatu append(if (symbol.isVal) "val" else "var") append(" ") } - signature.receiverType?.let { append('.'); append(it.render()) } + signature.receiverType?.let { append('.'); append(it.render(position = Variance.INVARIANT)) } append((symbol as KtNamedSymbol).name.asString()) append(": ") - append(signature.returnType.render()) + append(signature.returnType.render(position = Variance.INVARIANT)) } } } @@ -157,10 +157,11 @@ internal fun renderScopeWithParentDeclarations(scope: KtScope): String = prettyP else -> error("unknown symbol $this") } - val renderingOptions = KtDeclarationRendererOptions.DEFAULT.copy( - typeRendererOptions = KtTypeRendererOptions.SHORT_NAMES, - modifiers = emptySet() - ) + val renderingOptions = KtDeclarationRendererForSource.WITH_SHORT_NAMES.with { + modifiersRenderer = modifiersRenderer.with { + modifierFilter = KtRendererModifierFilter.NONE + } + } printCollection(scope.getAllSymbols().toList(), separator = "\n\n") { symbol -> val containingDeclaration = symbol.getContainingSymbol() as KtClassLikeSymbol diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeCreator/AbstractTypeParameterTypeTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeCreator/AbstractTypeParameterTypeTest.kt index a2817847836..b0cc91a2da4 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeCreator/AbstractTypeParameterTypeTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeCreator/AbstractTypeParameterTypeTest.kt @@ -6,13 +6,14 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeCreator import org.jetbrains.kotlin.analysis.api.components.buildTypeParameterType -import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest +import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtTypeParameter import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance abstract class AbstractTypeParameterTypeTest : AbstractAnalysisApiSingleFileTest() { override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { @@ -23,7 +24,7 @@ abstract class AbstractTypeParameterTypeTest : AbstractAnalysisApiSingleFileTest val ktType = buildTypeParameterType(symbol) buildString { appendLine("expression: ${expressionAtCaret.text}") - appendLine("ktType: ${ktType.render()}") + appendLine("ktType: ${ktType.render(position = Variance.INVARIANT)}") } } diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeInfoProvider/AbstractFunctionClassKindTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeInfoProvider/AbstractFunctionClassKindTest.kt index 9e5cdec1ab2..44ec389257e 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeInfoProvider/AbstractFunctionClassKindTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeInfoProvider/AbstractFunctionClassKindTest.kt @@ -5,14 +5,15 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeInfoProvider -import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest +import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance abstract class AbstractFunctionClassKindTest : AbstractAnalysisApiSingleFileTest() { @@ -22,7 +23,7 @@ abstract class AbstractFunctionClassKindTest : AbstractAnalysisApiSingleFileTes val (type, functionClassKind) = executeOnPooledThreadInReadAction { analyseForTest(expressionAtCaret) { val functionType = expressionAtCaret.getExpectedType() - functionType?.render() to functionType?.functionClassKind + functionType?.render(position = Variance.INVARIANT) to functionType?.functionClassKind } } val actual = buildString { diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeInfoProvider/AbstractIsDenotableTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeInfoProvider/AbstractIsDenotableTest.kt index ed0ca8ebe19..70e04aad6d8 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeInfoProvider/AbstractIsDenotableTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeInfoProvider/AbstractIsDenotableTest.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.AdditionalSourceProvider import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance import java.io.File abstract class AbstractIsDenotableTest : AbstractAnalysisApiSingleFileTest() { @@ -68,7 +69,7 @@ abstract class AbstractIsDenotableTest : AbstractAnalysisApiSingleFileTest() { true -> append("@Denotable") false -> append("@Nondenotable") } - append("(\"${ktType.render()}\") ") + append("(\"${ktType.render(position = Variance.INVARIANT)}\") ") append(base.text) } } diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeProvider/AbstractAnalysisApiGetSuperTypesTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeProvider/AbstractAnalysisApiGetSuperTypesTest.kt index 4c0e872bae9..6f1f7397853 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeProvider/AbstractAnalysisApiGetSuperTypesTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/typeProvider/AbstractAnalysisApiGetSuperTypesTest.kt @@ -6,15 +6,16 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions -import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider -import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest +import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForDebug import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest +import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance abstract class AbstractAnalysisApiGetSuperTypesTest : AbstractAnalysisApiSingleFileTest(){ override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { @@ -32,7 +33,7 @@ abstract class AbstractAnalysisApiGetSuperTypesTest : AbstractAnalysisApiSingleF fun List.print(name: String) { appendLine(name) for (type in this) { - appendLine(type.render(KtTypeRendererOptions.DEFAULT)) + appendLine(type.render(KtTypeRendererForDebug.WITH_QUALIFIED_NAMES, position = Variance.INVARIANT)) } appendLine() } diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractReferenceResolveTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractReferenceResolveTest.kt index fd49cd97a0a..69497901c90 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractReferenceResolveTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractReferenceResolveTest.kt @@ -6,10 +6,11 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.api.components.RendererModifier import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.TestReferenceResolveResultRenderer.renderResolvedTo -import org.jetbrains.kotlin.analysis.api.symbols.* +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtRendererAnnotationsFilter +import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForDebug +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.callables.KtPropertyAccessorsRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestDirectives import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedSingleModuleTest import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider @@ -89,9 +90,11 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedSingleModu ) } - private val renderingOptions = KtDeclarationRendererOptions.DEFAULT.copy( - modifiers = RendererModifier.DEFAULT - RendererModifier.ANNOTATIONS, - sortNestedDeclarations = true - ) + private val renderingOptions = KtDeclarationRendererForDebug.WITH_QUALIFIED_NAMES.with { + annotationRenderer = annotationRenderer.with { + annotationFilter = KtRendererAnnotationsFilter.NONE + } + propertyAccessorsRenderer = KtPropertyAccessorsRenderer.NONE + } } diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/TestReferenceResolveResultRenderer.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/TestReferenceResolveResultRenderer.kt index e12d2abf5c4..fc1e56b4d13 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/TestReferenceResolveResultRenderer.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/TestReferenceResolveResultRenderer.kt @@ -6,36 +6,38 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForDebug import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.types.Variance object TestReferenceResolveResultRenderer { fun KtAnalysisSession.renderResolvedTo( symbols: List, - renderingOptions: KtDeclarationRendererOptions = KtDeclarationRendererOptions.DEFAULT + renderer: KtDeclarationRenderer = KtDeclarationRendererForDebug.WITH_QUALIFIED_NAMES, ) = - symbols.map { renderResolveResult(it, renderingOptions) } + symbols.map { renderResolveResult(it, renderer) } .sorted() .withIndex() .joinToString(separator = "\n") { "${it.index}: ${it.value}" } private fun KtAnalysisSession.renderResolveResult( symbol: KtSymbol, - renderingOptions: KtDeclarationRendererOptions + renderer: KtDeclarationRenderer ): String { return buildString { symbolContainerFqName(symbol)?.let { fqName -> append("(in $fqName) ") } when (symbol) { - is KtDeclarationSymbol -> append(symbol.render(renderingOptions)) + is KtDeclarationSymbol -> append(symbol.render(renderer)) is KtPackageSymbol -> append("package ${symbol.fqName}") is KtReceiverParameterSymbol -> { append("extension receiver with type ") - append(symbol.type.render(renderingOptions.typeRendererOptions)) + append(symbol.type.render(renderer.typeRenderer, position = Variance.INVARIANT)) } else -> error("Unexpected symbol ${symbol::class}") } diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/scopes/AbstractTypeScopeTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/scopes/AbstractTypeScopeTest.kt index d46f7555815..a6c2b67cbdc 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/scopes/AbstractTypeScopeTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/scopes/AbstractTypeScopeTest.kt @@ -11,10 +11,10 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.scopes import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.api.components.RendererModifier import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.prettyPrintSignature import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.stringRepresentation +import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForSource +import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.renderers.KtRendererModifierFilter import org.jetbrains.kotlin.analysis.api.scopes.KtScope import org.jetbrains.kotlin.analysis.api.scopes.KtTypeScope import org.jetbrains.kotlin.analysis.api.symbols.DebugSymbolRenderer @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance abstract class AbstractTypeScopeTest : AbstractAnalysisApiSingleFileTest() { override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { @@ -38,7 +39,7 @@ abstract class AbstractTypeScopeTest : AbstractAnalysisApiSingleFileTest() { val scopeStringRepresentation = prettyPrint { appendLine("expression: ${expression.text}") - appendLine("KtType: ${type.render()}") + appendLine("KtType: ${type.render(position = Variance.INVARIANT)}") appendLine() appendLine("KtTypeScope:") appendLine(typeScope?.let { renderForTests(it) } ?: "NO_SCOPE") @@ -95,9 +96,14 @@ abstract class AbstractTypeScopeTest : AbstractAnalysisApiSingleFileTest() { val callables = scope.getCallableSymbols().toList() return prettyPrint { callables.forEach { - appendLine(it.render(options = KtDeclarationRendererOptions.DEFAULT.copy(modifiers = RendererModifier.NONE))) + appendLine(it.render(renderer)) } } } + companion object { + private val renderer = KtDeclarationRendererForSource.WITH_QUALIFIED_NAMES.with { + modifiersRenderer = modifiersRenderer.with { modifierFilter = KtRendererModifierFilter.NONE } + } + } } diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolTest.kt index 9141ffb3831..9290b4fcc23 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolTest.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolTestDirectives.DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolTestDirectives.DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1 import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolTestDirectives.DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K2 @@ -14,6 +13,8 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolTestDirectives.DO_NOT_CHECK_SYMBOL_RESTORE_K1 import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolTestDirectives.DO_NOT_CHECK_SYMBOL_RESTORE_K2 import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolTestDirectives.PRETTY_RENDERING_MODE +import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForDebug +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.KtClassifierBodyRenderer import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer @@ -33,7 +34,7 @@ import org.jetbrains.kotlin.test.services.assertions import kotlin.test.fail abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() { - private val renderingOptions = KtDeclarationRendererOptions.DEFAULT + private val renderer = KtDeclarationRendererForDebug.WITH_QUALIFIED_NAMES open val prettyRenderMode: PrettyRenderingMode = PrettyRenderingMode.RENDER_SYMBOLS_LINE_BY_LINE @@ -52,8 +53,10 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() { val directiveToIgnoreNonPsiSymbolRestore = directives.doNotCheckNonPsiSymbolRestoreDirective() val prettyRenderOptions = when (directives.singleOrZeroValue(PRETTY_RENDERING_MODE) ?: prettyRenderMode) { - PrettyRenderingMode.RENDER_SYMBOLS_LINE_BY_LINE -> renderingOptions - PrettyRenderingMode.RENDER_SYMBOLS_NESTED -> renderingOptions.copy(renderClassMembers = true) + PrettyRenderingMode.RENDER_SYMBOLS_LINE_BY_LINE -> renderer + PrettyRenderingMode.RENDER_SYMBOLS_NESTED -> renderer.with { + classifierBodyRenderer = KtClassifierBodyRenderer.BODY_WITH_MEMBERS + } } fun KtSymbol.safePointer(): PointerWrapper? { diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/types/AbstractAnalysisApiSubstitutorsTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/types/AbstractAnalysisApiSubstitutorsTest.kt index 88616e04afa..47a9930dca3 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/types/AbstractAnalysisApiSubstitutorsTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/types/AbstractAnalysisApiSubstitutorsTest.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance abstract class AbstractAnalysisApiSubstitutorsTest : AbstractAnalysisApiSingleFileTest() { override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { @@ -29,9 +30,9 @@ abstract class AbstractAnalysisApiSubstitutorsTest : AbstractAnalysisApiSingleFi prettyPrint { appendLine("PSI type: ${declaration.typeReference?.text}") - appendLine("KtType: ${type.render()}") - appendLine("substitutor.substitute: ${substituted.render()}") - appendLine("substitutor.substituteOrNull: ${substitutedOrNull?.render()}") + appendLine("KtType: ${type.render(position = Variance.INVARIANT)}") + appendLine("substitutor.substitute: ${substituted.render(position = Variance.INVARIANT)}") + appendLine("substitutor.substituteOrNull: ${substitutedOrNull?.render(position = Variance.INVARIANT)}") } } testServices.assertions.assertEqualsToTestDataFileSibling(actual) diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolDeclarationRendererProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolDeclarationRendererProvider.kt index 34a5978bb2d..dfd82818548 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolDeclarationRendererProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolDeclarationRendererProvider.kt @@ -6,15 +6,19 @@ package org.jetbrains.kotlin.analysis.api.components import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion -import org.jetbrains.kotlin.analysis.api.signatures.KtCallableSignature +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForSource +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForSource import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.types.Variance /** * KtType to string renderer options * @see KtType - * @see KtSymbolDeclarationRendererProvider.render + * @see KtSymbolDeclarationRendererProvider.renderType */ public data class KtTypeRendererOptions( /** @@ -49,7 +53,7 @@ public data class KtTypeRendererOptions( /** * KtSymbol to string renderer options * @see KtSymbol - * @see KtSymbolDeclarationRendererProvider.render + * @see KtSymbolDeclarationRendererProvider.renderType */ public data class KtDeclarationRendererOptions( /** @@ -127,9 +131,9 @@ public enum class RendererModifier(public val includeByDefault: Boolean) { } public abstract class KtSymbolDeclarationRendererProvider : KtAnalysisSessionComponent() { - public abstract fun renderDeclaration(symbol: KtDeclarationSymbol, options: KtDeclarationRendererOptions): String + public abstract fun renderDeclaration(symbol: KtDeclarationSymbol, renderer: KtDeclarationRenderer): String - public abstract fun render(type: KtType, options: KtTypeRendererOptions): String + public abstract fun renderType(type: KtType, renderer: KtTypeRenderer, position: Variance): String } /** @@ -139,12 +143,15 @@ public interface KtSymbolDeclarationRendererMixIn : KtAnalysisSessionMixIn { /** * Render symbol into the representable Kotlin string */ - public fun KtDeclarationSymbol.render(options: KtDeclarationRendererOptions = KtDeclarationRendererOptions.DEFAULT): String = - withValidityAssertion { analysisSession.symbolDeclarationRendererProvider.renderDeclaration(this, options) } + public fun KtDeclarationSymbol.render(renderer: KtDeclarationRenderer = KtDeclarationRendererForSource.WITH_QUALIFIED_NAMES): String = + withValidityAssertion { analysisSession.symbolDeclarationRendererProvider.renderDeclaration(this, renderer) } /** * Render kotlin type into the representable Kotlin type string */ - public fun KtType.render(options: KtTypeRendererOptions = KtTypeRendererOptions.DEFAULT): String = - withValidityAssertion { analysisSession.symbolDeclarationRendererProvider.render(this, options) } + public fun KtType.render( + renderer: KtTypeRenderer = KtTypeRendererForSource.WITH_QUALIFIED_NAMES, + position: Variance, + ): String = + withValidityAssertion { analysisSession.symbolDeclarationRendererProvider.renderType(this, renderer, position) } } \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt index efee8c42fe0..5e401f171da 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt @@ -19,7 +19,9 @@ import org.jetbrains.kotlin.psi.KtTypeReference public abstract class KtTypeProvider : KtAnalysisSessionComponent() { public abstract val builtinTypes: KtBuiltinTypes - public abstract fun approximateToSuperPublicDenotableType(type: KtType): KtType? + public abstract fun approximateToSuperPublicDenotableType(type: KtType, approximateLocalTypes: Boolean): KtType? + + public abstract fun approximateToSubPublicDenotableType(type: KtType, approximateLocalTypes: Boolean): KtType? public abstract fun buildSelfClassType(symbol: KtNamedClassOrObjectSymbol): KtType @@ -50,13 +52,25 @@ public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn { * Approximates [KtType] with the a supertype which can be rendered in a source code * * Return `null` if the type do not need approximation and can be rendered as is - * Otherwise, for type `T` return type `S` such `T <: S` and `T` and every it type argument is [org.jetbrains.kotlin.analysis.api.types.KtDenotableType]` + * Otherwise, for type `T` return type `S` such `T <: S` and `T` and every it type argument is denotable */ - public fun KtType.approximateToSuperPublicDenotable(): KtType? = - withValidityAssertion { analysisSession.typeProvider.approximateToSuperPublicDenotableType(this) } + public fun KtType.approximateToSuperPublicDenotable(approximateLocalTypes: Boolean): KtType? = + withValidityAssertion { analysisSession.typeProvider.approximateToSuperPublicDenotableType(this, approximateLocalTypes) } - public fun KtType.approximateToSuperPublicDenotableOrSelf(): KtType = - withValidityAssertion { approximateToSuperPublicDenotable() ?: this } + /** + * Approximates [KtType] with the a subtype which can be rendered in a source code + * + * Return `null` if the type do not need approximation and can be rendered as is + * Otherwise, for type `T` return type `S` such `S <: T` and `T` and every it type argument is denotable + */ + public fun KtType.approximateToSubPublicDenotable(approximateLocalTypes: Boolean): KtType? = + withValidityAssertion { analysisSession.typeProvider.approximateToSubPublicDenotableType(this, approximateLocalTypes) } + + public fun KtType.approximateToSubPublicDenotableOrSelf(approximateLocalTypes: Boolean): KtType = + withValidityAssertion { approximateToSubPublicDenotable(approximateLocalTypes) ?: this } + + public fun KtType.approximateToSuperPublicDenotableOrSelf(approximateLocalTypes: Boolean): KtType = + withValidityAssertion { approximateToSuperPublicDenotable(approximateLocalTypes) ?: this } public fun KtNamedClassOrObjectSymbol.buildSelfClassType(): KtType = withValidityAssertion { analysisSession.typeProvider.buildSelfClassType(this) } diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/KtKeywordRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/KtKeywordRenderer.kt new file mode 100644 index 00000000000..28cf2580223 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/KtKeywordRenderer.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.base + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtKeywordToken + +public interface KtKeywordRenderer { + context(KtAnalysisSession) + public fun renderKeyword(keyword: KtKeywordToken, owner: KtAnnotated, printer: PrettyPrinter) + + context(KtAnalysisSession) + public fun renderKeywords(keywords: List, owner: KtAnnotated, printer: PrettyPrinter) { + printer.printCollection(keywords, separator = " ") { + renderKeyword(it, owner, this) + } + } + + public object AS_WORD : KtKeywordRenderer { + context(KtAnalysisSession) + override fun renderKeyword(keyword: KtKeywordToken, owner: KtAnnotated, printer: PrettyPrinter) { + printer.append(keyword.value) + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/KtAnnotationRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/KtAnnotationRenderer.kt new file mode 100644 index 00000000000..126029ed17d --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/KtAnnotationRenderer.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.base.annotations + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.renderers.KtAnnotationArgumentsRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.renderers.KtAnnotationListRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.renderers.KtAnnotationQualifierRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.renderers.KtAnnotationUseSiteTargetRenderer +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public class KtAnnotationRenderer internal constructor( + public val annotationListRenderer: KtAnnotationListRenderer, + public val annotationFilter: KtRendererAnnotationsFilter, + public val annotationsQualifiedNameRenderer: KtAnnotationQualifierRenderer, + public val annotationUseSiteTargetRenderer: KtAnnotationUseSiteTargetRenderer, + public val annotationArgumentsRenderer: KtAnnotationArgumentsRenderer, +) { + context(KtAnalysisSession) + public fun renderAnnotations(owner: KtAnnotated, printer: PrettyPrinter) { + annotationListRenderer.renderAnnotations(owner, printer) + } + + public inline fun with(action: Builder.() -> Unit): KtAnnotationRenderer { + val renderer = this + return KtAnnotationRenderer { + this.annotationListRenderer = renderer.annotationListRenderer + this.annotationFilter = renderer.annotationFilter + this.annotationsQualifiedNameRenderer = renderer.annotationsQualifiedNameRenderer + this.annotationUseSiteTargetRenderer = renderer.annotationUseSiteTargetRenderer + this.annotationArgumentsRenderer = renderer.annotationArgumentsRenderer + + action() + } + } + + public class Builder { + public lateinit var annotationListRenderer: KtAnnotationListRenderer + public lateinit var annotationFilter: KtRendererAnnotationsFilter + public lateinit var annotationsQualifiedNameRenderer: KtAnnotationQualifierRenderer + public lateinit var annotationUseSiteTargetRenderer: KtAnnotationUseSiteTargetRenderer + public lateinit var annotationArgumentsRenderer: KtAnnotationArgumentsRenderer + + + public fun build(): KtAnnotationRenderer = KtAnnotationRenderer( + annotationListRenderer, + annotationFilter, + annotationsQualifiedNameRenderer, + annotationUseSiteTargetRenderer, + annotationArgumentsRenderer + ) + + } + + public companion object { + public inline operator fun invoke(action: Builder.() -> Unit): KtAnnotationRenderer = + Builder().apply(action).build() + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/KtAnnotationRendererForSource.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/KtAnnotationRendererForSource.kt new file mode 100644 index 00000000000..534972a1e80 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/KtAnnotationRendererForSource.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.base.annotations + +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.renderers.KtAnnotationArgumentsRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.renderers.KtAnnotationListRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.renderers.KtAnnotationQualifierRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.renderers.KtAnnotationUseSiteTargetRenderer + +public object KtAnnotationRendererForSource { + public val WITH_QUALIFIED_NAMES: KtAnnotationRenderer = KtAnnotationRenderer { + annotationListRenderer = KtAnnotationListRenderer.FOR_SOURCE + annotationFilter = KtRendererAnnotationsFilter.NO_NULLABILITY and KtRendererAnnotationsFilter.NO_PARAMETER_NAME + annotationsQualifiedNameRenderer = KtAnnotationQualifierRenderer.WITH_QUALIFIED_NAMES + annotationUseSiteTargetRenderer = KtAnnotationUseSiteTargetRenderer.WITH_NON_DEFAULT_USE_SITE + annotationArgumentsRenderer = KtAnnotationArgumentsRenderer.IF_ANY + } + + public val WITH_SHORT_NAMES: KtAnnotationRenderer = WITH_QUALIFIED_NAMES.with { + annotationsQualifiedNameRenderer = KtAnnotationQualifierRenderer.WITH_SHORT_NAMES + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/KtRendererAnnotationsFilter.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/KtRendererAnnotationsFilter.kt new file mode 100644 index 00000000000..ed3a78a3745 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/KtRendererAnnotationsFilter.kt @@ -0,0 +1,67 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.base.annotations + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication +import org.jetbrains.kotlin.builtins.StandardNames +import org.jetbrains.kotlin.load.java.NULLABILITY_ANNOTATIONS + +public interface KtRendererAnnotationsFilter { + context(KtAnalysisSession) + public fun filter(annotation: KtAnnotationApplication, owner: KtAnnotated): Boolean + + public infix fun and(other: KtRendererAnnotationsFilter): KtRendererAnnotationsFilter = + KtRendererAnnotationsFilter { annotation, owner -> + filter(annotation, owner) && other.filter(annotation, owner) + } + + public infix fun or(other: KtRendererAnnotationsFilter): KtRendererAnnotationsFilter = + KtRendererAnnotationsFilter { annotation, owner -> + filter(annotation, owner) || other.filter(annotation, owner) + } + + public object ALL : KtRendererAnnotationsFilter { + context(KtAnalysisSession) + override fun filter(annotation: KtAnnotationApplication, owner: KtAnnotated): Boolean { + return true + } + } + + public object NO_NULLABILITY : KtRendererAnnotationsFilter { + context(KtAnalysisSession) + override fun filter(annotation: KtAnnotationApplication, owner: KtAnnotated): Boolean { + return annotation.classId?.asSingleFqName() !in NULLABILITY_ANNOTATIONS + } + } + + public object NO_PARAMETER_NAME : KtRendererAnnotationsFilter { + context(KtAnalysisSession) + override fun filter(annotation: KtAnnotationApplication, owner: KtAnnotated): Boolean { + return annotation.classId?.asSingleFqName() != StandardNames.FqNames.parameterName + } + } + + + public object NONE : KtRendererAnnotationsFilter { + context(KtAnalysisSession) + override fun filter(annotation: KtAnnotationApplication, owner: KtAnnotated): Boolean { + return false + } + } + + public companion object { + public operator fun invoke( + predicate: context(KtAnalysisSession) (annotation: KtAnnotationApplication, owner: KtAnnotated) -> Boolean + ): KtRendererAnnotationsFilter = object : KtRendererAnnotationsFilter { + context(KtAnalysisSession) + override fun filter(annotation: KtAnnotationApplication, owner: KtAnnotated): Boolean { + return predicate(this@KtAnalysisSession, annotation, owner) + } + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationArgumentsRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationArgumentsRenderer.kt new file mode 100644 index 00000000000..aa9546ba843 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationArgumentsRenderer.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.base.annotations.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationValueRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtAnnotationRenderer +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.renderer.render + +public interface KtAnnotationArgumentsRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + public fun renderAnnotationArguments(annotation: KtAnnotationApplication, owner: KtAnnotated, printer: PrettyPrinter) + + public object NONE : KtAnnotationArgumentsRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + override fun renderAnnotationArguments(annotation: KtAnnotationApplication, owner: KtAnnotated, printer: PrettyPrinter) { + } + } + + public object IF_ANY : KtAnnotationArgumentsRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + override fun renderAnnotationArguments( + annotation: KtAnnotationApplication, + owner: KtAnnotated, + printer: PrettyPrinter + ) { + if (annotation.arguments.isEmpty()) return + printer.printCollection(annotation.arguments, prefix = "(", postfix = ")") { argument -> + append(argument.name.render()) + append(" = ") + append(KtAnnotationValueRenderer.render(argument.expression)) + } + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationListRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationListRenderer.kt new file mode 100644 index 00000000000..eeec8292b03 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationListRenderer.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.base.annotations.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated +import org.jetbrains.kotlin.analysis.api.annotations.annotations +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtAnnotationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtAnnotationListRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + public fun renderAnnotations(owner: KtAnnotated, printer: PrettyPrinter) + + public object FOR_SOURCE : KtAnnotationListRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + override fun renderAnnotations(owner: KtAnnotated, printer: PrettyPrinter) { + val annotations = owner.annotations.filter { annotationFilter.filter(it, owner) }.ifEmpty { return } + printer.printCollection( + annotations, + separator = when (owner) { + is KtValueParameterSymbol -> " " + is KtDeclarationSymbol -> "\n" + else -> " " + } + ) { annotation -> + append('@') + annotationUseSiteTargetRenderer.renderUseSiteTarget(annotation, owner, printer) + annotationsQualifiedNameRenderer.renderQualifier(annotation, owner, printer) + annotationArgumentsRenderer.renderAnnotationArguments(annotation, owner, printer) + } + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationQualifierRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationQualifierRenderer.kt new file mode 100644 index 00000000000..e0a71d36788 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationQualifierRenderer.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.base.annotations.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtAnnotationRenderer +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.renderer.render + +public interface KtAnnotationQualifierRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + public fun renderQualifier(annotation: KtAnnotationApplication, owner: KtAnnotated, printer: PrettyPrinter) + + public object WITH_QUALIFIED_NAMES : KtAnnotationQualifierRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + override fun renderQualifier(annotation: KtAnnotationApplication, owner: KtAnnotated, printer: PrettyPrinter): Unit = printer { + val classId = annotation.classId + if (classId != null) { + append(classId.asSingleFqName().render()) + } else { + append("ERROR_ANNOTATION") + } + } + } + + public object WITH_SHORT_NAMES : KtAnnotationQualifierRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + override fun renderQualifier(annotation: KtAnnotationApplication, owner: KtAnnotated, printer: PrettyPrinter): Unit = printer { + val classId = annotation.classId + if (classId != null) { + printer.append(classId.shortClassName.render()) + } else { + printer.append("ERROR_ANNOTATION") + } + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationUseSiteTargetRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationUseSiteTargetRenderer.kt new file mode 100644 index 00000000000..8be4527f903 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/base/annotations/renderers/KtAnnotationUseSiteTargetRenderer.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.base.annotations.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtAnnotationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.* +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget + +public interface KtAnnotationUseSiteTargetRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + public fun renderUseSiteTarget(annotation: KtAnnotationApplication, owner: KtAnnotated, printer: PrettyPrinter) + + public object WITHOUT_USE_SITE : KtAnnotationUseSiteTargetRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + override fun renderUseSiteTarget(annotation: KtAnnotationApplication, owner: KtAnnotated, printer: PrettyPrinter) { + } + } + + public object WITH_USES_SITE : KtAnnotationUseSiteTargetRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + override fun renderUseSiteTarget(annotation: KtAnnotationApplication, owner: KtAnnotated, printer: PrettyPrinter) { + val useSite = annotation.useSiteTarget ?: return + printer.append(useSite.renderName) + printer.append(':') + } + } + + public object WITH_NON_DEFAULT_USE_SITE : KtAnnotationUseSiteTargetRenderer { + context(KtAnalysisSession, KtAnnotationRenderer) + override fun renderUseSiteTarget(annotation: KtAnnotationApplication, owner: KtAnnotated, printer: PrettyPrinter) { + if (owner !is KtCallableSymbol) return + val print = when (owner) { + is KtAnonymousFunctionSymbol -> true + is KtConstructorSymbol -> true + is KtFunctionSymbol -> true + is KtPropertyGetterSymbol -> annotation.useSiteTarget != AnnotationUseSiteTarget.PROPERTY_GETTER + is KtPropertySetterSymbol -> annotation.useSiteTarget != AnnotationUseSiteTarget.PROPERTY_SETTER + is KtSamConstructorSymbol -> true + is KtBackingFieldSymbol -> annotation.useSiteTarget != AnnotationUseSiteTarget.FIELD + is KtEnumEntrySymbol -> true + is KtValueParameterSymbol -> + owner.getContainingSymbol() !is KtPropertySetterSymbol || annotation.useSiteTarget != AnnotationUseSiteTarget.SETTER_PARAMETER + + is KtJavaFieldSymbol -> true + is KtLocalVariableSymbol -> true + is KtKotlinPropertySymbol -> annotation.useSiteTarget != AnnotationUseSiteTarget.PROPERTY + is KtSyntheticJavaPropertySymbol -> annotation.useSiteTarget != AnnotationUseSiteTarget.PROPERTY + } + if (print) { + WITH_USES_SITE.renderUseSiteTarget(annotation, owner, printer) + } + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtCallableReturnTypeFilter.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtCallableReturnTypeFilter.kt new file mode 100644 index 00000000000..b96f190a3e6 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtCallableReturnTypeFilter.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol +import org.jetbrains.kotlin.analysis.api.types.KtType + +public interface KtCallableReturnTypeFilter { + context (KtAnalysisSession) + public fun shouldRenderReturnType(type: KtType, symbol: KtCallableSymbol): Boolean + + public object ALWAYS : KtCallableReturnTypeFilter { + context(KtAnalysisSession) + override fun shouldRenderReturnType(type: KtType, symbol: KtCallableSymbol): Boolean { + return true + } + + } + + public object NO_UNIT_FOR_FUNCTIONS : KtCallableReturnTypeFilter { + context(KtAnalysisSession) + override fun shouldRenderReturnType(type: KtType, symbol: KtCallableSymbol): Boolean { + return when (symbol) { + is KtFunctionSymbol -> !type.isUnit + else -> true + } + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtDeclarationRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtDeclarationRenderer.kt new file mode 100644 index 00000000000..0cd1d89b379 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtDeclarationRenderer.kt @@ -0,0 +1,285 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.base.KtKeywordRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtAnnotationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.bodies.* +import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.KtDeclarationModifiersRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.* +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.callables.* +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.classifiers.KtAnonymousObjectSymbolRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.classifiers.KtNamedClassOrObjectSymbolRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.classifiers.KtSingleTypeParameterSymbolRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.classifiers.KtTypeAliasSymbolRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.superTypes.KtSuperTypeListRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.superTypes.KtSuperTypeRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.superTypes.KtSuperTypesCallArgumentsRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.superTypes.KtSuperTypesFilter +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.symbols.* +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public class KtDeclarationRenderer private constructor( + public val nameRenderer: KtDeclarationNameRenderer, + public val keywordRender: KtKeywordRenderer, + public val codeStyle: KtRendererCodeStyle, + public val typeRenderer: KtTypeRenderer, + public val annotationRenderer: KtAnnotationRenderer, + public val modifiersRenderer: KtDeclarationModifiersRenderer, + public val declarationTypeApproximator: KtRendererTypeApproximator, + public val classifierBodyRenderer: KtClassifierBodyRenderer, + + + public val superTypeRenderer: KtSuperTypeRenderer, + public val superTypeListRenderer: KtSuperTypeListRenderer, + public val superTypesFilter: KtSuperTypesFilter, + public val superTypesArgumentRenderer: KtSuperTypesCallArgumentsRenderer, + + public val bodyMemberScopeProvider: KtRendererBodyMemberScopeProvider, + public val bodyMemberScopeSorter: KtRendererBodyMemberScopeSorter, + + public val functionLikeBodyRenderer: KtFunctionLikeBodyRenderer, + public val variableInitializerRenderer: KtVariableInitializerRenderer, + public val parameterDefaultValueRenderer: KtParameterDefaultValueRenderer, + public val accessorBodyRenderer: KtPropertyAccessorBodyRenderer, + + public val returnTypeRenderer: KtCallableReturnTypeRenderer, + public val receiverTyperRenderer: KtCallableReceiverTypeRenderer, + + public val valueParametersRenderer: KtCallableParameterRenderer, + public val typeParametersRenderer: KtTypeParametersRenderer, + public val typeParametersFilter: KtTypeParameterRendererFilter, + + public val callableSignatureRenderer: KtCallableSignatureRender, + + public val anonymousFunctionRenderer: KtAnonymousFunctionSymbolRenderer, + public val backingFieldRenderer: KtBackingFieldSymbolRenderer, + public val constructorRenderer: KtConstructorSymbolRenderer, + public val enumEntryRenderer: KtEnumEntrySymbolRenderer, + public val functionSymbolRenderer: KtFunctionSymbolRenderer, + public val javaFieldRenderer: KtJavaFieldSymbolRenderer, + public val localVariableRenderer: KtLocalVariableSymbolRenderer, + public val getterRenderer: KtPropertyGetterSymbolRenderer, + public val setterRenderer: KtPropertySetterSymbolRenderer, + public val propertyRenderer: KtKotlinPropertySymbolRenderer, + public val kotlinPropertyRenderer: KtKotlinPropertySymbolRenderer, + public val syntheticJavaPropertyRenderer: KtSyntheticJavaPropertySymbolRenderer, + public val valueParameterRenderer: KtValueParameterSymbolRenderer, + public val samConstructorRenderer: KtSamConstructorSymbolRenderer, + public val propertyAccessorsRenderer: KtPropertyAccessorsRenderer, + + public val classInitializerRender: KtClassInitializerRenderer, + public val classOrObjectRenderer: KtNamedClassOrObjectSymbolRenderer, + public val typeAliasRenderer: KtTypeAliasSymbolRenderer, + public val anonymousObjectRenderer: KtAnonymousObjectSymbolRenderer, + public val singleTypeParameterRenderer: KtSingleTypeParameterSymbolRenderer, + public val returnTypeFilter: KtCallableReturnTypeFilter, +) { + + context(KtAnalysisSession) + public fun renderDeclaration(symbol: KtDeclarationSymbol, printer: PrettyPrinter) { + when (symbol) { + is KtAnonymousObjectSymbol -> anonymousObjectRenderer.renderSymbol(symbol, printer) + is KtNamedClassOrObjectSymbol -> classOrObjectRenderer.renderSymbol(symbol, printer) + is KtTypeAliasSymbol -> typeAliasRenderer.renderSymbol(symbol, printer) + is KtAnonymousFunctionSymbol -> anonymousFunctionRenderer.renderSymbol(symbol, printer) + is KtConstructorSymbol -> constructorRenderer.renderSymbol(symbol, printer) + is KtFunctionSymbol -> functionSymbolRenderer.renderSymbol(symbol, printer) + is KtPropertyGetterSymbol -> getterRenderer.renderSymbol(symbol, printer) + is KtPropertySetterSymbol -> setterRenderer.renderSymbol(symbol, printer) + is KtSamConstructorSymbol -> samConstructorRenderer.renderSymbol(symbol, printer) + is KtBackingFieldSymbol -> backingFieldRenderer.renderSymbol(symbol, printer) + is KtEnumEntrySymbol -> enumEntryRenderer.renderSymbol(symbol, printer) + is KtValueParameterSymbol -> valueParameterRenderer.renderSymbol(symbol, printer) + is KtJavaFieldSymbol -> javaFieldRenderer.renderSymbol(symbol, printer) + is KtLocalVariableSymbol -> localVariableRenderer.renderSymbol(symbol, printer) + is KtKotlinPropertySymbol -> kotlinPropertyRenderer.renderSymbol(symbol, printer) + is KtSyntheticJavaPropertySymbol -> syntheticJavaPropertyRenderer.renderSymbol(symbol, printer) + is KtTypeParameterSymbol -> singleTypeParameterRenderer.renderSymbol(symbol, printer) + is KtClassInitializerSymbol -> classInitializerRender.renderClassInitializer(symbol, printer) + } + } + + public fun with(action: Builder.() -> Unit): KtDeclarationRenderer { + val renderer = this + return KtDeclarationRenderer { + this.nameRenderer = renderer.nameRenderer + this.keywordRender = renderer.keywordRender + this.codeStyle = renderer.codeStyle + this.typeRenderer = renderer.typeRenderer + this.annotationRenderer = renderer.annotationRenderer + this.modifiersRenderer = renderer.modifiersRenderer + this.declarationTypeApproximator = renderer.declarationTypeApproximator + this.classifierBodyRenderer = renderer.classifierBodyRenderer + + this.superTypeRenderer = renderer.superTypeRenderer + this.superTypeListRenderer = renderer.superTypeListRenderer + this.superTypesFilter = renderer.superTypesFilter + this.superTypesArgumentRenderer = renderer.superTypesArgumentRenderer + + this.bodyMemberScopeProvider = renderer.bodyMemberScopeProvider + this.bodyMemberScopeSorter = renderer.bodyMemberScopeSorter + + this.functionLikeBodyRenderer = renderer.functionLikeBodyRenderer + this.variableInitializerRenderer = renderer.variableInitializerRenderer + this.parameterDefaultValueRenderer = renderer.parameterDefaultValueRenderer + this.accessorBodyRenderer = renderer.accessorBodyRenderer + + this.returnTypeRenderer = renderer.returnTypeRenderer + this.receiverTyperRenderer = renderer.receiverTyperRenderer + + this.valueParametersRenderer = renderer.valueParametersRenderer + this.typeParametersRenderer = renderer.typeParametersRenderer + this.typeParametersFilter = renderer.typeParametersFilter + + this.callableSignatureRenderer = renderer.callableSignatureRenderer + + this.anonymousFunctionRenderer = renderer.anonymousFunctionRenderer + this.backingFieldRenderer = renderer.backingFieldRenderer + this.constructorRenderer = renderer.constructorRenderer + this.enumEntryRenderer = renderer.enumEntryRenderer + this.functionSymbolRenderer = renderer.functionSymbolRenderer + this.javaFieldRenderer = renderer.javaFieldRenderer + this.localVariableRenderer = renderer.localVariableRenderer + this.getterRenderer = renderer.getterRenderer + this.setterRenderer = renderer.setterRenderer + this.propertyRenderer = renderer.propertyRenderer + this.kotlinPropertyRenderer = renderer.kotlinPropertyRenderer + this.syntheticJavaPropertyRenderer = renderer.syntheticJavaPropertyRenderer + this.valueParameterRenderer = renderer.valueParameterRenderer + this.samConstructorRenderer = renderer.samConstructorRenderer + this.propertyAccessorsRenderer = renderer.propertyAccessorsRenderer + + this.classInitializerRender = renderer.classInitializerRender + this.classOrObjectRenderer = renderer.classOrObjectRenderer + this.typeAliasRenderer = renderer.typeAliasRenderer + this.anonymousObjectRenderer = renderer.anonymousObjectRenderer + this.singleTypeParameterRenderer = renderer.singleTypeParameterRenderer + this.returnTypeFilter = renderer.returnTypeFilter + + action() + } + } + + public companion object { + public operator fun invoke(action: Builder.() -> Unit): KtDeclarationRenderer = + Builder().apply(action).build() + } + + public open class Builder { + public lateinit var returnTypeFilter: KtCallableReturnTypeFilter + public lateinit var nameRenderer: KtDeclarationNameRenderer + public lateinit var keywordRender: KtKeywordRenderer + public lateinit var codeStyle: KtRendererCodeStyle + public lateinit var typeRenderer: KtTypeRenderer + public lateinit var annotationRenderer: KtAnnotationRenderer + public lateinit var modifiersRenderer: KtDeclarationModifiersRenderer + public lateinit var declarationTypeApproximator: KtRendererTypeApproximator + public lateinit var classifierBodyRenderer: KtClassifierBodyRenderer + + public lateinit var superTypeRenderer: KtSuperTypeRenderer + public lateinit var superTypeListRenderer: KtSuperTypeListRenderer + public lateinit var superTypesFilter: KtSuperTypesFilter + public lateinit var superTypesArgumentRenderer: KtSuperTypesCallArgumentsRenderer + + public lateinit var bodyMemberScopeProvider: KtRendererBodyMemberScopeProvider + public lateinit var bodyMemberScopeSorter: KtRendererBodyMemberScopeSorter + + public lateinit var functionLikeBodyRenderer: KtFunctionLikeBodyRenderer + public lateinit var variableInitializerRenderer: KtVariableInitializerRenderer + public lateinit var parameterDefaultValueRenderer: KtParameterDefaultValueRenderer + public lateinit var accessorBodyRenderer: KtPropertyAccessorBodyRenderer + + public lateinit var returnTypeRenderer: KtCallableReturnTypeRenderer + public lateinit var receiverTyperRenderer: KtCallableReceiverTypeRenderer + + public lateinit var valueParametersRenderer: KtCallableParameterRenderer + public lateinit var typeParametersRenderer: KtTypeParametersRenderer + public lateinit var typeParametersFilter: KtTypeParameterRendererFilter + public lateinit var callableSignatureRenderer: KtCallableSignatureRender + + public lateinit var anonymousFunctionRenderer: KtAnonymousFunctionSymbolRenderer + public lateinit var backingFieldRenderer: KtBackingFieldSymbolRenderer + public lateinit var constructorRenderer: KtConstructorSymbolRenderer + public lateinit var enumEntryRenderer: KtEnumEntrySymbolRenderer + public lateinit var functionSymbolRenderer: KtFunctionSymbolRenderer + public lateinit var javaFieldRenderer: KtJavaFieldSymbolRenderer + public lateinit var localVariableRenderer: KtLocalVariableSymbolRenderer + public lateinit var getterRenderer: KtPropertyGetterSymbolRenderer + public lateinit var setterRenderer: KtPropertySetterSymbolRenderer + public lateinit var propertyRenderer: KtKotlinPropertySymbolRenderer + public lateinit var kotlinPropertyRenderer: KtKotlinPropertySymbolRenderer + public lateinit var syntheticJavaPropertyRenderer: KtSyntheticJavaPropertySymbolRenderer + public lateinit var valueParameterRenderer: KtValueParameterSymbolRenderer + public lateinit var samConstructorRenderer: KtSamConstructorSymbolRenderer + public lateinit var propertyAccessorsRenderer: KtPropertyAccessorsRenderer + + public lateinit var classInitializerRender: KtClassInitializerRenderer + public lateinit var classOrObjectRenderer: KtNamedClassOrObjectSymbolRenderer + public lateinit var typeAliasRenderer: KtTypeAliasSymbolRenderer + public lateinit var anonymousObjectRenderer: KtAnonymousObjectSymbolRenderer + public lateinit var singleTypeParameterRenderer: KtSingleTypeParameterSymbolRenderer + + + public fun build(): KtDeclarationRenderer = KtDeclarationRenderer( + nameRenderer, + keywordRender, + codeStyle, + typeRenderer, + annotationRenderer, + modifiersRenderer, + declarationTypeApproximator, + classifierBodyRenderer, + + superTypeRenderer, + superTypeListRenderer, + superTypesFilter, + superTypesArgumentRenderer, + + bodyMemberScopeProvider, + bodyMemberScopeSorter, + + functionLikeBodyRenderer, + variableInitializerRenderer, + parameterDefaultValueRenderer, + accessorBodyRenderer, + + returnTypeRenderer, + receiverTyperRenderer, + + valueParametersRenderer, + typeParametersRenderer, + typeParametersFilter, + callableSignatureRenderer, + + anonymousFunctionRenderer, + backingFieldRenderer, + constructorRenderer, + enumEntryRenderer, + functionSymbolRenderer, + javaFieldRenderer, + localVariableRenderer, + getterRenderer, + setterRenderer, + propertyRenderer, + kotlinPropertyRenderer, + syntheticJavaPropertyRenderer, + valueParameterRenderer, + samConstructorRenderer, + propertyAccessorsRenderer, + + classInitializerRender, + classOrObjectRenderer, + typeAliasRenderer, + anonymousObjectRenderer, + singleTypeParameterRenderer, + returnTypeFilter, + ) + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtRendererCodeStyle.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtRendererCodeStyle.kt new file mode 100644 index 00000000000..de50f5a6125 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtRendererCodeStyle.kt @@ -0,0 +1,71 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol +import org.jetbrains.kotlin.analysis.api.types.KtType + +public interface KtRendererCodeStyle { + context(KtAnalysisSession) + public fun getIndentSize(): Int + + context(KtAnalysisSession) + public fun getSeparatorBetweenAnnotationAndOwner(symbol: KtAnnotated): String + + context(KtAnalysisSession) + public fun getSeparatorBetweenAnnotations(symbol: KtAnnotated): String + + context(KtAnalysisSession) + public fun getSeparatorBetweenModifiers(): String + + context(KtAnalysisSession) + public fun getSeparatorBetweenMembers(first: KtDeclarationSymbol, second: KtDeclarationSymbol): String +} + +public object KtRecommendedRendererCodeStyle : KtRendererCodeStyle { + context(KtAnalysisSession) override fun getIndentSize(): Int { + return 4 + } + + context(KtAnalysisSession) + override fun getSeparatorBetweenAnnotationAndOwner(symbol: KtAnnotated): String { + return when (symbol) { + is KtType -> " " + is KtTypeParameterSymbol -> " " + is KtValueParameterSymbol -> " " + else -> "\n" + } + } + + context(KtAnalysisSession) + override fun getSeparatorBetweenAnnotations(symbol: KtAnnotated): String { + return when (symbol) { + is KtType -> " " + is KtTypeParameterSymbol -> " " + is KtValueParameterSymbol -> " " + else -> "\n" + } + } + + context(KtAnalysisSession) override fun getSeparatorBetweenModifiers(): String { + return " " + } + + context(KtAnalysisSession) + override fun getSeparatorBetweenMembers(first: KtDeclarationSymbol, second: KtDeclarationSymbol): String { + return when { + first is KtEnumEntrySymbol && second is KtEnumEntrySymbol -> ",\n" + first is KtEnumEntrySymbol && second !is KtEnumEntrySymbol -> ";\n\n" + else -> "\n\n" + } + } + +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtRendererTypeApproximator.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtRendererTypeApproximator.kt new file mode 100644 index 00000000000..5234b1d36bf --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtRendererTypeApproximator.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.types.Variance + +public interface KtRendererTypeApproximator { + context(KtAnalysisSession) + public fun approximateType(type: KtType, position: Variance): KtType + + public object TO_DENNOTABLE : KtRendererTypeApproximator { + context(KtAnalysisSession) + override fun approximateType(type: KtType, position: Variance): KtType { + return when (position) { + Variance.INVARIANT -> type + Variance.IN_VARIANCE -> type.approximateToSubPublicDenotableOrSelf(approximateLocalTypes = false) + Variance.OUT_VARIANCE -> type.approximateToSuperPublicDenotableOrSelf(approximateLocalTypes = false) + } + } + } + + public object NO_APPROXIMATION : KtRendererTypeApproximator { + context(KtAnalysisSession) + override fun approximateType(type: KtType, position: Variance): KtType { + return type + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtFunctionLikeBodyRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtFunctionLikeBodyRenderer.kt new file mode 100644 index 00000000000..0077929bbdb --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtFunctionLikeBodyRenderer.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.bodies + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtFunctionLikeBodyRenderer { + context(KtAnalysisSession) + public fun renderBody(symbol: KtFunctionLikeSymbol, printer: PrettyPrinter) + + public object NO_BODY : KtFunctionLikeBodyRenderer { + context(KtAnalysisSession) + override fun renderBody(symbol: KtFunctionLikeSymbol, printer: PrettyPrinter) { + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtParameterDefaultValueRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtParameterDefaultValueRenderer.kt new file mode 100644 index 00000000000..8a20c23c2dd --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtParameterDefaultValueRenderer.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.bodies + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtParameterDefaultValueRenderer { + context(KtAnalysisSession) + public fun renderDefaultValue(symbol: KtValueParameterSymbol, printer: PrettyPrinter) + + public object NO_DEFAULT_VALUE : KtParameterDefaultValueRenderer { + context(KtAnalysisSession) + override fun renderDefaultValue(symbol: KtValueParameterSymbol, printer: PrettyPrinter) { + } + } + + public object THREE_DOTS : KtParameterDefaultValueRenderer { + context(KtAnalysisSession) + override fun renderDefaultValue(symbol: KtValueParameterSymbol, printer: PrettyPrinter) { + if (symbol.hasDefaultValue) { + printer.append("...") + } + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtPropertyAccessorBodyRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtPropertyAccessorBodyRenderer.kt new file mode 100644 index 00000000000..3d39b0992ca --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtPropertyAccessorBodyRenderer.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.bodies + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyAccessorSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtPropertyAccessorBodyRenderer { + context(KtAnalysisSession) + public fun renderBody(symbol: KtPropertyAccessorSymbol, printer: PrettyPrinter) + + public object NO_BODY : KtPropertyAccessorBodyRenderer { + context(KtAnalysisSession) + override fun renderBody(symbol: KtPropertyAccessorSymbol, printer: PrettyPrinter) { + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtRendererBodyMemberScopeProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtRendererBodyMemberScopeProvider.kt new file mode 100644 index 00000000000..7590b42ac4f --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtRendererBodyMemberScopeProvider.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.bodies + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.* +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers + +public interface KtRendererBodyMemberScopeProvider { + context(KtAnalysisSession) + public fun getMemberScope(symbol: KtSymbolWithMembers): List + + public object ALL : KtRendererBodyMemberScopeProvider { + context(KtAnalysisSession) + override fun getMemberScope(symbol: KtSymbolWithMembers): List { + return symbol.getDeclaredMemberScope().getAllSymbols().toList() + } + } + + public object ALL_DECLARED : KtRendererBodyMemberScopeProvider { + context(KtAnalysisSession) + override fun getMemberScope(symbol: KtSymbolWithMembers): List { + return symbol.getDeclaredMemberScope().getAllSymbols() + .filter { member -> + val origin = member.origin + origin != KtSymbolOrigin.DELEGATED && + origin != KtSymbolOrigin.SOURCE_MEMBER_GENERATED && + origin != KtSymbolOrigin.SUBSTITUTION_OVERRIDE && + origin != KtSymbolOrigin.INTERSECTION_OVERRIDE + }.filter { member -> + member !is KtConstructorSymbol || symbol !is KtClassOrObjectSymbol || !symbol.classKind.isObject + }.filterNot { member -> + member is KtConstructorSymbol && symbol is KtEnumEntrySymbol + } + .toList() + } + } + + public object NONE : KtRendererBodyMemberScopeProvider { + context(KtAnalysisSession) + override fun getMemberScope(symbol: KtSymbolWithMembers): List { + return emptyList() + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtRendererBodyMemberScopeSorter.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtRendererBodyMemberScopeSorter.kt new file mode 100644 index 00000000000..b3693a1cfd5 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtRendererBodyMemberScopeSorter.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.bodies + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers + +public interface KtRendererBodyMemberScopeSorter { + context(KtAnalysisSession) + public fun sortMembers(members: List, owner: KtSymbolWithMembers): List + + public object ENUM_ENTRIES_AT_BEGINING : KtRendererBodyMemberScopeSorter { + context(KtAnalysisSession) + override fun sortMembers(members: List, owner: KtSymbolWithMembers): List { + return members.sortedBy { it !is KtEnumEntrySymbol } + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtVariableInitializerRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtVariableInitializerRenderer.kt new file mode 100644 index 00000000000..59471370dfb --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/bodies/KtVariableInitializerRenderer.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.bodies + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtVariableSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtVariableInitializerRenderer { + context(KtAnalysisSession) + public fun renderInitializer(symbol: KtVariableSymbol, printer: PrettyPrinter) + + public object NO_INITIALIZER : KtVariableInitializerRenderer { + context(KtAnalysisSession) + override fun renderInitializer(symbol: KtVariableSymbol, printer: PrettyPrinter) { + } + } + + public object ONLY_CONST_VALUE_INITIALIZERS : KtVariableInitializerRenderer { + context(KtAnalysisSession) + override fun renderInitializer(symbol: KtVariableSymbol, printer: PrettyPrinter) { + //todo add initializer to KtVariableSymbol and render for it too KT-54794/ + val initializer = (symbol as? KtPropertySymbol)?.initializer as? KtConstantInitializerValue ?: return + printer.append(" = ") + printer.append(initializer.constant.renderAsKotlinConstant()) + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/impl/KtDeclarationRendererForDebug.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/impl/KtDeclarationRendererForDebug.kt new file mode 100644 index 00000000000..158629a7f01 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/impl/KtDeclarationRendererForDebug.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.impl + +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtRendererTypeApproximator +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.callables.KtSamConstructorSymbolRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.classifiers.KtSingleTypeParameterSymbolRenderer +import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForDebug + +public object KtDeclarationRendererForDebug { + public val WITH_QUALIFIED_NAMES: KtDeclarationRenderer = KtDeclarationRendererForSource.WITH_QUALIFIED_NAMES.with { + singleTypeParameterRenderer = KtSingleTypeParameterSymbolRenderer.WITHOUT_BOUNDS + samConstructorRenderer = KtSamConstructorSymbolRenderer.AS_FUNCTION + typeRenderer = KtTypeRendererForDebug.WITH_QUALIFIED_NAMES + declarationTypeApproximator = KtRendererTypeApproximator.NO_APPROXIMATION + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/impl/KtDeclarationRendererForSource.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/impl/KtDeclarationRendererForSource.kt new file mode 100644 index 00000000000..e84dd45f8df --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/impl/KtDeclarationRendererForSource.kt @@ -0,0 +1,90 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.impl + +import org.jetbrains.kotlin.analysis.api.renderer.base.KtKeywordRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtAnnotationRendererForSource +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtCallableReturnTypeFilter +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtRecommendedRendererCodeStyle +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtRendererTypeApproximator +import org.jetbrains.kotlin.analysis.api.renderer.declarations.bodies.* +import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.impl.KtDeclarationModifiersRendererForSource +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.* +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.callables.* +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.classifiers.KtAnonymousObjectSymbolRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.classifiers.KtNamedClassOrObjectSymbolRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.classifiers.KtSingleTypeParameterSymbolRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.classifiers.KtTypeAliasSymbolRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.superTypes.KtSuperTypeListRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.superTypes.KtSuperTypeRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.superTypes.KtSuperTypesCallArgumentsRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.superTypes.KtSuperTypesFilter +import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForSource + +public object KtDeclarationRendererForSource { + public val WITH_QUALIFIED_NAMES: KtDeclarationRenderer = KtDeclarationRenderer { + nameRenderer = KtDeclarationNameRenderer.QUOTED + keywordRender = KtKeywordRenderer.AS_WORD + codeStyle = KtRecommendedRendererCodeStyle + modifiersRenderer = KtDeclarationModifiersRendererForSource.NO_IMPLICIT_MODIFIERS + classifierBodyRenderer = KtClassifierBodyRenderer.NO_BODY + bodyMemberScopeProvider = KtRendererBodyMemberScopeProvider.ALL_DECLARED + bodyMemberScopeSorter = KtRendererBodyMemberScopeSorter.ENUM_ENTRIES_AT_BEGINING + + superTypeRenderer = KtSuperTypeRenderer.WITH_OUT_APPROXIMATION + superTypeListRenderer = KtSuperTypeListRenderer.AS_LIST + superTypesFilter = KtSuperTypesFilter.NO_DEFAULT_TYPES + superTypesArgumentRenderer = KtSuperTypesCallArgumentsRenderer.EMPTY_PARENS + functionLikeBodyRenderer = KtFunctionLikeBodyRenderer.NO_BODY + valueParametersRenderer = KtCallableParameterRenderer.PARAMETERS_IN_PARENS + + typeParametersRenderer = KtTypeParametersRenderer.WITH_BOUNDS_IN_WHERE_CLAUSE + typeParametersFilter = KtTypeParameterRendererFilter.NO_FOR_CONSTURCTORS + + classInitializerRender = KtClassInitializerRenderer.INIT_BLOCK_WITH_BRACES + + anonymousFunctionRenderer = KtAnonymousFunctionSymbolRenderer.AS_SOURCE + backingFieldRenderer = KtBackingFieldSymbolRenderer.AS_FIELD_KEYWROD + constructorRenderer = KtConstructorSymbolRenderer.AS_SOURCE + enumEntryRenderer = KtEnumEntrySymbolRenderer.AS_SOURCE + functionSymbolRenderer = KtFunctionSymbolRenderer.AS_SOURCE + javaFieldRenderer = KtJavaFieldSymbolRenderer.AS_SOURCE + localVariableRenderer = KtLocalVariableSymbolRenderer.AS_SOURCE + getterRenderer = KtPropertyGetterSymbolRenderer.AS_SOURCE + setterRenderer = KtPropertySetterSymbolRenderer.AS_SOURCE + propertyRenderer = KtKotlinPropertySymbolRenderer.AS_SOURCE + kotlinPropertyRenderer = KtKotlinPropertySymbolRenderer.AS_SOURCE + syntheticJavaPropertyRenderer = KtSyntheticJavaPropertySymbolRenderer.AS_SOURCE + valueParameterRenderer = KtValueParameterSymbolRenderer.AS_SOURCE + samConstructorRenderer = KtSamConstructorSymbolRenderer.NOT_RENDER + + callableSignatureRenderer = KtCallableSignatureRender.FOR_SOURCE + accessorBodyRenderer = KtPropertyAccessorBodyRenderer.NO_BODY + parameterDefaultValueRenderer = KtParameterDefaultValueRenderer.NO_DEFAULT_VALUE + variableInitializerRenderer = KtVariableInitializerRenderer.NO_INITIALIZER + + classOrObjectRenderer = KtNamedClassOrObjectSymbolRenderer.AS_SOURCE + typeAliasRenderer = KtTypeAliasSymbolRenderer.AS_SOURCE + anonymousObjectRenderer = KtAnonymousObjectSymbolRenderer.AS_SOURCE + singleTypeParameterRenderer = KtSingleTypeParameterSymbolRenderer.WITHOUT_BOUNDS + propertyAccessorsRenderer = KtPropertyAccessorsRenderer.NO_DEFAULT + + receiverTyperRenderer = KtCallableReceiverTypeRenderer.WITH_IN_APPROXIMATION + returnTypeRenderer = KtCallableReturnTypeRenderer.WITH_OUT_APPROXIMATION + + typeRenderer = KtTypeRendererForSource.WITH_QUALIFIED_NAMES + annotationRenderer = KtAnnotationRendererForSource.WITH_QUALIFIED_NAMES + declarationTypeApproximator = KtRendererTypeApproximator.TO_DENNOTABLE + returnTypeFilter = KtCallableReturnTypeFilter.NO_UNIT_FOR_FUNCTIONS + } + + public val WITH_SHORT_NAMES: KtDeclarationRenderer = WITH_QUALIFIED_NAMES.with { + annotationRenderer = KtAnnotationRendererForSource.WITH_SHORT_NAMES + typeRenderer = KtTypeRendererForSource.WITH_SHORT_NAMES + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/ktRendererUtils.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/ktRendererUtils.kt new file mode 100644 index 00000000000..5229bab9d8f --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/ktRendererUtils.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtKeywordToken + +context(KtAnalysisSession, KtDeclarationRenderer) +public fun renderAnnotationsAndModifiers( + symbol: S, + printer: PrettyPrinter, + keyword: KtKeywordToken, +): Unit where S : KtAnnotated, S : KtDeclarationSymbol = printer { + renderAnnotationsAndModifiers(symbol, printer, listOf(keyword)) +} + +context(KtAnalysisSession, KtDeclarationRenderer) +public fun renderAnnotationsAndModifiers( + symbol: S, + printer: PrettyPrinter, + keywords: List, +): Unit where S : KtAnnotated, S : KtDeclarationSymbol = printer { + val annotationsRendered: Boolean + val modifiersRendered: Boolean + codeStyle.getSeparatorBetweenAnnotationAndOwner(symbol).separated( + { annotationsRendered = checkIfPrinted { annotationRenderer.renderAnnotations(symbol, printer) } }, + { modifiersRendered = checkIfPrinted { modifiersRenderer.renderDeclarationModifiers(symbol, printer) } } + ) + val separator = when { + annotationsRendered && !modifiersRendered -> codeStyle.getSeparatorBetweenAnnotationAndOwner(symbol) + annotationsRendered || modifiersRendered -> codeStyle.getSeparatorBetweenModifiers() + else -> "" + } + + withPrefix(separator) { + keywordRender.renderKeywords(keywords, symbol, printer) + } +} + + +context(KtAnalysisSession, KtDeclarationRenderer) +public fun renderAnnotationsAndModifiers( + symbol: S, + printer: PrettyPrinter, +): Unit where S : KtAnnotated, S : KtDeclarationSymbol = printer { + codeStyle.getSeparatorBetweenAnnotationAndOwner(symbol).separated( + { annotationRenderer.renderAnnotations(symbol, printer) }, + { modifiersRenderer.renderDeclarationModifiers(symbol, printer) } + ) +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/KtDeclarationModifiersRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/KtDeclarationModifiersRenderer.kt new file mode 100644 index 00000000000..fa737855c18 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/KtDeclarationModifiersRenderer.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.modifiers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.base.KtKeywordRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.renderers.* +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public class KtDeclarationModifiersRenderer private constructor( + public val modifierListRenderer: KtModifierListRenderer, + public val modifierFilter: KtRendererModifierFilter, + public val modifiersSorter: KtModifiersSorter, + public val modalityProvider: KtRendererModalityModifierProvider, + public val visibilityProvider: KtRendererVisibilityModifierProvider, + public val otherModifiersProvider: KtRendererOtherModifiersProvider, + public val keywordRenderer: KtKeywordRenderer, +) { + context(KtAnalysisSession) + public fun renderDeclarationModifiers(symbol: KtDeclarationSymbol, printer: PrettyPrinter) { + modifierListRenderer.renderModifiers(symbol, printer) + } + + public inline fun with(action: Builder.() -> Unit): KtDeclarationModifiersRenderer { + val renderer = this + return KtDeclarationModifiersRenderer { + this.modifierListRenderer = renderer.modifierListRenderer + this.modifierFilter = renderer.modifierFilter + this.modifiersSorter = renderer.modifiersSorter + this.modalityProvider = renderer.modalityProvider + this.visibilityProvider = renderer.visibilityProvider + this.otherModifiersProvider = renderer.otherModifiersProvider + this.keywordRenderer = renderer.keywordRenderer + action() + } + } + + public companion object { + public inline operator fun invoke(action: Builder.() -> Unit): KtDeclarationModifiersRenderer = + Builder().apply(action).build() + } + + public class Builder { + public lateinit var modifierListRenderer: KtModifierListRenderer + public lateinit var modifierFilter: KtRendererModifierFilter + public lateinit var modifiersSorter: KtModifiersSorter + public lateinit var modalityProvider: KtRendererModalityModifierProvider + public lateinit var visibilityProvider: KtRendererVisibilityModifierProvider + public lateinit var otherModifiersProvider: KtRendererOtherModifiersProvider + public lateinit var keywordRenderer: KtKeywordRenderer + + public fun build(): KtDeclarationModifiersRenderer = KtDeclarationModifiersRenderer( + modifierListRenderer, + modifierFilter, + modifiersSorter, + modalityProvider, + visibilityProvider, + otherModifiersProvider, + keywordRenderer, + ) + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/impl/KtDeclarationModifiersRendererForSource.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/impl/KtDeclarationModifiersRendererForSource.kt new file mode 100644 index 00000000000..a5a80a02f2b --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/impl/KtDeclarationModifiersRendererForSource.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.modifiers.impl + +import org.jetbrains.kotlin.analysis.api.renderer.base.KtKeywordRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.KtDeclarationModifiersRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.renderers.* + +public object KtDeclarationModifiersRendererForSource { + public val NO_IMPLICIT_MODIFIERS: KtDeclarationModifiersRenderer = KtDeclarationModifiersRenderer { + modifierListRenderer = KtModifierListRenderer.AS_LIST + modifierFilter = KtRendererModifierFilter.ALL + modifiersSorter = KtModifiersSorter.CANONICAL + modalityProvider = KtRendererModalityModifierProvider.WITHOUT_IMPLICIT_MODALITY + visibilityProvider = KtRendererVisibilityModifierProvider.NO_IMPLICIT_VISIBILITY + otherModifiersProvider = KtRendererOtherModifiersProvider.ALL + keywordRenderer = KtKeywordRenderer.AS_WORD + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtModifierListRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtModifierListRenderer.kt new file mode 100644 index 00000000000..8d83857b5d2 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtModifierListRenderer.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.modifiers.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.KtDeclarationModifiersRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtModifierKeywordToken + +public interface KtModifierListRenderer { + context(KtAnalysisSession, KtDeclarationModifiersRenderer) + public fun renderModifiers(symbol: KtDeclarationSymbol, printer: PrettyPrinter) + + public object AS_LIST : KtModifierListRenderer { + context(KtAnalysisSession, KtDeclarationModifiersRenderer) + override fun renderModifiers(symbol: KtDeclarationSymbol, printer: PrettyPrinter) { + val modifiers = getModifiers(symbol) + .distinct() + .filter { modifierFilter.filter(it, symbol) } + .let { modifiersSorter.sort(it, symbol) } + .ifEmpty { return } + keywordRenderer.renderKeywords(modifiers, symbol, printer) + } + + context(KtAnalysisSession, KtDeclarationModifiersRenderer) + private fun getModifiers(symbol: KtDeclarationSymbol): List { + return buildList { + if (symbol is KtSymbolWithVisibility) { + visibilityProvider.getVisibilityModifier(symbol)?.let(::add) + } + if (symbol is KtSymbolWithModality) { + modalityProvider.getModalityModifier(symbol)?.let(::add) + } + addAll(otherModifiersProvider.getOtherModifiers(symbol)) + } + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtModifiersFilter.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtModifiersFilter.kt new file mode 100644 index 00000000000..aedab5b1a2f --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtModifiersFilter.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.modifiers.renderers + +import com.intellij.psi.tree.TokenSet +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.lexer.KtModifierKeywordToken + +public interface KtRendererModifierFilter { + context(KtAnalysisSession) + public fun filter(modifier: KtModifierKeywordToken, symbol: KtDeclarationSymbol): Boolean + + public infix fun and(other: KtRendererModifierFilter): KtRendererModifierFilter { + val self = this + return KtRendererModifierFilter { modifier, symbol -> + self.filter(modifier, symbol) && other.filter(modifier, symbol) + } + } + + public infix fun or(other: KtRendererModifierFilter): KtRendererModifierFilter { + val self = this + return KtRendererModifierFilter { modifier, symbol -> + self.filter(modifier, symbol) || other.filter(modifier, symbol) + } + } + + public object ALL : KtRendererModifierFilter { + context(KtAnalysisSession) + override fun filter(modifier: KtModifierKeywordToken, symbol: KtDeclarationSymbol): Boolean { + return true + } + } + + public object NONE : KtRendererModifierFilter { + context(KtAnalysisSession) + override fun filter(modifier: KtModifierKeywordToken, symbol: KtDeclarationSymbol): Boolean { + return false + } + } + + public companion object { + public operator fun invoke( + predicate: context(KtAnalysisSession)(modifier: KtModifierKeywordToken, symbol: KtDeclarationSymbol) -> Boolean + ): KtRendererModifierFilter = + object : KtRendererModifierFilter { + context(KtAnalysisSession) + override fun filter(modifier: KtModifierKeywordToken, symbol: KtDeclarationSymbol): Boolean { + return predicate(this@KtAnalysisSession, modifier, symbol) + } + } + + public fun onlyWith(vararg modifiers: KtModifierKeywordToken): KtRendererModifierFilter = + KtRendererModifierFilter { modifier, _ -> modifier in modifiers } + + public fun onlyWith(modifiers: TokenSet): KtRendererModifierFilter = + KtRendererModifierFilter { modifier, _ -> modifier in modifiers } + + public fun without(vararg modifiers: KtModifierKeywordToken): KtRendererModifierFilter = + KtRendererModifierFilter { modifier, _ -> modifier !in modifiers } + + public fun without(modifiers: TokenSet): KtRendererModifierFilter = + KtRendererModifierFilter { modifier, _ -> modifier !in modifiers } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtModifiersSorter.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtModifiersSorter.kt new file mode 100644 index 00000000000..033179431d2 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtModifiersSorter.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.modifiers.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.psi.addRemoveModifier.sortModifiers + +public interface KtModifiersSorter { + context(KtAnalysisSession) + public fun sort(modifiers: List, owner: KtDeclarationSymbol): List + + public object CANONICAL : KtModifiersSorter { + context(KtAnalysisSession) + override fun sort(modifiers: List, owner: KtDeclarationSymbol): List { + return sortModifiers(modifiers) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtRendererModalityModifierProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtRendererModalityModifierProvider.kt new file mode 100644 index 00000000000..7f673cab903 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtRendererModalityModifierProvider.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.modifiers.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.* +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtRendererModalityModifierProvider { + context(KtAnalysisSession) + public fun getModalityModifier(symbol: KtSymbolWithModality): KtModifierKeywordToken? + + public fun onlyIf( + condition: context(KtAnalysisSession) (symbol: KtSymbolWithModality) -> Boolean + ): KtRendererModalityModifierProvider { + val self = this + return object : KtRendererModalityModifierProvider { + context(KtAnalysisSession) + override fun getModalityModifier(symbol: KtSymbolWithModality): KtModifierKeywordToken? = + if (condition(this@KtAnalysisSession, symbol)) self.getModalityModifier(symbol) + else null + } + } + + public object WITH_IMPLICIT_MODALITY : KtRendererModalityModifierProvider { + context(KtAnalysisSession) + override fun getModalityModifier(symbol: KtSymbolWithModality): KtModifierKeywordToken? { + if (symbol is KtPropertyAccessorSymbol) return null + return when (symbol.modality) { + Modality.SEALED -> KtTokens.SEALED_KEYWORD + Modality.OPEN -> KtTokens.OPEN_KEYWORD + Modality.ABSTRACT -> KtTokens.ABSTRACT_KEYWORD + Modality.FINAL -> KtTokens.FINAL_KEYWORD + } + } + } + + public object WITHOUT_IMPLICIT_MODALITY : KtRendererModalityModifierProvider { + context(KtAnalysisSession) override fun getModalityModifier(symbol: KtSymbolWithModality): KtModifierKeywordToken? { + when (symbol) { + is KtFunctionSymbol -> if (symbol.isOverride && symbol.modality != Modality.FINAL) return null + is KtPropertySymbol -> if (symbol.isOverride && symbol.modality != Modality.FINAL) return null + } + if ((symbol as? KtClassOrObjectSymbol)?.classKind == KtClassKind.INTERFACE) return null + if ((symbol.getContainingSymbol() as? KtClassOrObjectSymbol)?.classKind == KtClassKind.INTERFACE) return null + + return when (symbol.modality) { + Modality.FINAL -> null + else -> WITH_IMPLICIT_MODALITY.getModalityModifier(symbol) + } + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtRendererOtherModifiersProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtRendererOtherModifiersProvider.kt new file mode 100644 index 00000000000..8b57a8abff1 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtRendererOtherModifiersProvider.kt @@ -0,0 +1,87 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.modifiers.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.* +import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.types.Variance + +public interface KtRendererOtherModifiersProvider { + context(KtAnalysisSession) + public fun getOtherModifiers(symbol: KtDeclarationSymbol): List + + public infix fun and(other: KtRendererOtherModifiersProvider): KtRendererOtherModifiersProvider { + val self = this + return object : KtRendererOtherModifiersProvider { + context(KtAnalysisSession) + override fun getOtherModifiers(symbol: KtDeclarationSymbol): List { + return self.getOtherModifiers(symbol) + other.getOtherModifiers(symbol) + } + } + } + + + public fun onlyIf( + condition: context(KtAnalysisSession) (symbol: KtDeclarationSymbol) -> Boolean + ): KtRendererOtherModifiersProvider { + val self = this + return object : KtRendererOtherModifiersProvider { + context(KtAnalysisSession) + override fun getOtherModifiers(symbol: KtDeclarationSymbol): List = + if (condition(this@KtAnalysisSession, symbol)) self.getOtherModifiers(symbol) + else emptyList() + } + } + + + public object ALL : KtRendererOtherModifiersProvider { + context(KtAnalysisSession) + override fun getOtherModifiers(symbol: KtDeclarationSymbol): List = buildList { + if (symbol is KtFunctionSymbol) { + if (symbol.isExternal) add(KtTokens.EXTERNAL_KEYWORD) + if (symbol.isOverride) add(KtTokens.OVERRIDE_KEYWORD) + if (symbol.isInline) add(KtTokens.INLINE_KEYWORD) + if (symbol.isInfix) add(KtTokens.INFIX_KEYWORD) + if (symbol.isOperator) add(KtTokens.OPERATOR_KEYWORD) + if (symbol.isSuspend) add(KtTokens.SUSPEND_KEYWORD) + } + + if (symbol is KtPropertySymbol) { + if (symbol.isOverride) add(KtTokens.OVERRIDE_KEYWORD) + } + + if (symbol is KtValueParameterSymbol) { + if (symbol.isVararg) add(KtTokens.VARARG_KEYWORD) + if (symbol.isCrossinline) add(KtTokens.CROSSINLINE_KEYWORD) + if (symbol.isNoinline) add(KtTokens.NOINLINE_KEYWORD) + } + + if (symbol is KtKotlinPropertySymbol) { + if (symbol.isConst) add(KtTokens.CONST_KEYWORD) + if (symbol.isLateInit) add(KtTokens.LATEINIT_KEYWORD) + } + + if (symbol is KtNamedClassOrObjectSymbol) { + if (symbol.isExternal) add(KtTokens.EXTERNAL_KEYWORD) + if (symbol.isInline) add(KtTokens.INLINE_KEYWORD) + if (symbol.isData) add(KtTokens.DATA_KEYWORD) + if (symbol.isFun) add(KtTokens.FUN_KEYWORD) + if (symbol.isInner) add(KtTokens.INNER_KEYWORD) + } + + if (symbol is KtTypeParameterSymbol) { + if (symbol.isReified) add(KtTokens.REIFIED_KEYWORD) + when (symbol.variance) { + Variance.INVARIANT -> {} + Variance.IN_VARIANCE -> add(KtTokens.IN_KEYWORD) + Variance.OUT_VARIANCE -> add(KtTokens.OUT_KEYWORD) + } + } + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtRendererVisibilityModifierProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtRendererVisibilityModifierProvider.kt new file mode 100644 index 00000000000..ebb6f3f74b3 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/modifiers/renderers/KtRendererVisibilityModifierProvider.kt @@ -0,0 +1,67 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.modifiers.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.* +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.java.JavaVisibilities +import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtRendererVisibilityModifierProvider { + context(KtAnalysisSession) + public fun getVisibilityModifier(symbol: KtSymbolWithVisibility): KtModifierKeywordToken? + + public fun onlyIf( + condition: context(KtAnalysisSession) (symbol: KtSymbolWithVisibility) -> Boolean + ): KtRendererVisibilityModifierProvider { + val self = this + return object : KtRendererVisibilityModifierProvider { + context(KtAnalysisSession) + override fun getVisibilityModifier(symbol: KtSymbolWithVisibility): KtModifierKeywordToken? = + if (condition(this@KtAnalysisSession, symbol)) self.getVisibilityModifier(symbol) + else null + } + } + + public object NO_IMPLICIT_VISIBILITY : KtRendererVisibilityModifierProvider { + context(KtAnalysisSession) + override fun getVisibilityModifier(symbol: KtSymbolWithVisibility): KtModifierKeywordToken? { + when (symbol) { + is KtFunctionSymbol -> if (symbol.isOverride) return null + is KtPropertySymbol -> if (symbol.isOverride) return null + is KtConstructorSymbol -> { + if ((symbol.getContainingSymbol() as? KtClassOrObjectSymbol)?.classKind == KtClassKind.ENUM_CLASS) return null + } + } + + return when (symbol.visibility) { + Visibilities.Public -> null + JavaVisibilities.PackageVisibility -> null + JavaVisibilities.ProtectedStaticVisibility, JavaVisibilities.ProtectedAndPackage -> null + else -> WITH_IMPLICIT_VISIBILITY.getVisibilityModifier(symbol) + } + } + } + + public object WITH_IMPLICIT_VISIBILITY : KtRendererVisibilityModifierProvider { + context(KtAnalysisSession) + override fun getVisibilityModifier(symbol: KtSymbolWithVisibility): KtModifierKeywordToken? { + return when (symbol.visibility) { + Visibilities.Private, Visibilities.PrivateToThis -> KtTokens.PRIVATE_KEYWORD + Visibilities.Protected -> KtTokens.PROTECTED_KEYWORD + Visibilities.Internal -> KtTokens.INTERNAL_KEYWORD + Visibilities.Public -> KtTokens.PUBLIC_KEYWORD + Visibilities.Local -> null + JavaVisibilities.PackageVisibility -> KtTokens.PUBLIC_KEYWORD + JavaVisibilities.ProtectedStaticVisibility, JavaVisibilities.ProtectedAndPackage -> KtTokens.PROTECTED_KEYWORD + else -> null + } + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtCallableParameterRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtCallableParameterRenderer.kt new file mode 100644 index 00000000000..2657c994534 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtCallableParameterRenderer.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtCallableParameterRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderValueParameters(symbol: KtCallableSymbol, printer: PrettyPrinter) + + public object PARAMETERS_IN_PARENS : KtCallableParameterRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderValueParameters(symbol: KtCallableSymbol, printer: PrettyPrinter) { + val valueParameters = when (symbol) { + is KtFunctionLikeSymbol -> symbol.valueParameters + else -> return + } + printer.printCollection(valueParameters, prefix = "(", postfix = ")") { + renderDeclaration(it, printer) + } + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtClassInitializerRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtClassInitializerRenderer.kt new file mode 100644 index 00000000000..b4bc85635d0 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtClassInitializerRenderer.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtClassInitializerSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtClassInitializerRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderClassInitializer(symbol: KtClassInitializerSymbol, printer: PrettyPrinter) + + public object INIT_BLOCK_WITH_BRACES : KtClassInitializerRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderClassInitializer(symbol: KtClassInitializerSymbol, printer: PrettyPrinter): Unit = printer { + " ".separated( + { keywordRender.renderKeyword(KtTokens.INIT_KEYWORD, symbol, this) }, + { printer.withIndentInBraces {} }, + ) + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtClassifierBodyRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtClassifierBodyRenderer.kt new file mode 100644 index 00000000000..79183ff9222 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtClassifierBodyRenderer.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.analysis.utils.printer.prettyPrintWithSettingsFrom + +public interface KtClassifierBodyRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderBody(symbol: KtSymbolWithMembers, printer: PrettyPrinter) + + public object NO_BODY : KtClassifierBodyRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderBody(symbol: KtSymbolWithMembers, printer: PrettyPrinter) { + } + } + + public object EMPTY_BRACES : KtClassifierBodyRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderBody(symbol: KtSymbolWithMembers, printer: PrettyPrinter) { + printer.append("{\n}") + } + } + + public object BODY_WITH_MEMBERS : KtClassifierBodyWithMembersRenderer() { + override fun renderEmptyBodyForEmptyMemberScope(symbol: KtSymbolWithMembers): Boolean { + return false + } + } + + public object BODY_WITH_MEMBERS_OR_EMPTY_BRACES : KtClassifierBodyWithMembersRenderer() { + override fun renderEmptyBodyForEmptyMemberScope(symbol: KtSymbolWithMembers): Boolean { + return true + } + } +} + +public abstract class KtClassifierBodyWithMembersRenderer : KtClassifierBodyRenderer { + public abstract fun renderEmptyBodyForEmptyMemberScope(symbol: KtSymbolWithMembers): Boolean + + context(KtAnalysisSession, KtDeclarationRenderer) + public override fun renderBody(symbol: KtSymbolWithMembers, printer: PrettyPrinter) { + val members = bodyMemberScopeProvider.getMemberScope(symbol).filter { it !is KtConstructorSymbol || !it.isPrimary } + .let { bodyMemberScopeSorter.sortMembers(it, symbol) } + val membersToPrint = members.mapNotNull { member -> + val rendered = prettyPrintWithSettingsFrom(printer) { + renderDeclaration(member, this) + } + if (rendered.isNotEmpty()) member to rendered else null + } + if (membersToPrint.isEmpty() && !renderEmptyBodyForEmptyMemberScope(symbol)) return + + printer.withIndentInBraces { + var previous: KtDeclarationSymbol? = null + for ((member, rendered) in membersToPrint) { + if (previous != null) { + printer.append(codeStyle.getSeparatorBetweenMembers(previous, member)) + } + previous = member + printer.append(rendered) + } + } + } + +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtDeclarationNameRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtDeclarationNameRenderer.kt new file mode 100644 index 00000000000..a5f5a054970 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtDeclarationNameRenderer.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind +import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.renderer.render + +public interface KtDeclarationNameRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderName(symbol: KtNamedSymbol, printer: PrettyPrinter) + + public object QUOTED : KtDeclarationNameRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderName(symbol: KtNamedSymbol, printer: PrettyPrinter) { + if (symbol is KtClassOrObjectSymbol && symbol.classKind == KtClassKind.COMPANION_OBJECT && symbol.name == SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) + return + printer.append(symbol.name.render()) + } + } + + public object UNQUOTED : KtDeclarationNameRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderName(symbol: KtNamedSymbol, printer: PrettyPrinter) { + if (symbol is KtClassOrObjectSymbol && symbol.classKind == KtClassKind.COMPANION_OBJECT && symbol.name == SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) + return + printer.append(symbol.name.asString()) + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtTypeParameterRendererFilter.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtTypeParameterRendererFilter.kt new file mode 100644 index 00000000000..af6b5f46ab1 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtTypeParameterRendererFilter.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithTypeParameters + +public interface KtTypeParameterRendererFilter { + context(KtAnalysisSession) + public fun filter(typeParameter: KtTypeParameterSymbol, owner: KtSymbolWithTypeParameters): Boolean + + public object NO_FOR_CONSTURCTORS : KtTypeParameterRendererFilter { + context(KtAnalysisSession) + override fun filter(typeParameter: KtTypeParameterSymbol, owner: KtSymbolWithTypeParameters): Boolean { + return owner !is KtConstructorSymbol + } + } + + public companion object { + public operator fun invoke(predicate: context(KtAnalysisSession)(typeParameter: KtTypeParameterSymbol, owner: KtSymbolWithTypeParameters) -> Boolean): KtTypeParameterRendererFilter { + return object : KtTypeParameterRendererFilter { + context(KtAnalysisSession) + override fun filter(typeParameter: KtTypeParameterSymbol, owner: KtSymbolWithTypeParameters): Boolean { + return predicate(this@KtAnalysisSession, typeParameter, owner) + } + } + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtTypeParametersRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtTypeParametersRenderer.kt new file mode 100644 index 00000000000..750d7d7e372 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/KtTypeParametersRenderer.kt @@ -0,0 +1,94 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.types.Variance + +public interface KtTypeParametersRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderTypeParameters(symbol: KtDeclarationSymbol, printer: PrettyPrinter) + + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderWhereClause(symbol: KtDeclarationSymbol, printer: PrettyPrinter) + + public object NO_TYPE_PARAMETERS : KtTypeParametersRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderTypeParameters(symbol: KtDeclarationSymbol, printer: PrettyPrinter) { + } + + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderWhereClause(symbol: KtDeclarationSymbol, printer: PrettyPrinter) { + } + } + + public object WIHTOUT_BOUNDS : KtTypeParametersRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderTypeParameters(symbol: KtDeclarationSymbol, printer: PrettyPrinter) { + val typeParameters = symbol.typeParameters + .filter { typeParametersFilter.filter(it, symbol) } + .ifEmpty { return } + printer.printCollection(typeParameters, prefix = "<", postfix = ">") { typeParameter -> + codeStyle.getSeparatorBetweenAnnotationAndOwner(typeParameter).separated( + { modifiersRenderer.renderDeclarationModifiers(typeParameter, printer) }, + { nameRenderer.renderName(typeParameter, printer) }, + ) + } + } + + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderWhereClause(symbol: KtDeclarationSymbol, printer: PrettyPrinter) { + } + } + + public object WITH_BOUNDS_IN_WHERE_CLAUSE : KtTypeParametersRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderTypeParameters(symbol: KtDeclarationSymbol, printer: PrettyPrinter) { + val typeParameters = symbol.typeParameters + .filter { typeParametersFilter.filter(it, symbol) } + .ifEmpty { return } + printer.printCollection(typeParameters, prefix = "<", postfix = ">") { typeParameter -> + codeStyle.getSeparatorBetweenAnnotationAndOwner(typeParameter).separated( + { modifiersRenderer.renderDeclarationModifiers(typeParameter, printer) }, + { nameRenderer.renderName(typeParameter, printer) }, + ) + if (typeParameter.upperBounds.size == 1) { + append(" : ") + typeRenderer.renderType(typeParameter.upperBounds.single(), printer) + } + } + } + + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderWhereClause(symbol: KtDeclarationSymbol, printer: PrettyPrinter): Unit = printer { + val allBounds = symbol.typeParameters + .filter { typeParametersFilter.filter(it, symbol) } + .flatMap { typeParam -> + if (typeParam.upperBounds.size > 1) { + typeParam.upperBounds.map { bound -> typeParam to bound } + } else { + emptyList() + } + }.ifEmpty { return } + " ".separated( + { keywordRender.renderKeyword(KtTokens.WHERE_KEYWORD, symbol, printer) }, + { + printer.printCollection(allBounds) { (typeParameter, bound) -> + " : ".separated( + { nameRenderer.renderName(typeParameter, printer) }, + { typeRenderer.renderType(declarationTypeApproximator.approximateType(bound, Variance.OUT_VARIANCE), printer) }, + ) + } + }, + ) + + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtAnonymousFunctionSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtAnonymousFunctionSymbolRenderer.kt new file mode 100644 index 00000000000..6a7d9ac086b --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtAnonymousFunctionSymbolRenderer.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtAnonymousFunctionSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtAnonymousFunctionSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtAnonymousFunctionSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtAnonymousFunctionSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtAnonymousFunctionSymbol, printer: PrettyPrinter): Unit = printer { + callableSignatureRenderer.renderCallableSignature(symbol, KtTokens.FUN_KEYWORD, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtBackingFieldSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtBackingFieldSymbolRenderer.kt new file mode 100644 index 00000000000..3a01ed35b99 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtBackingFieldSymbolRenderer.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtBackingFieldSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtBackingFieldSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtBackingFieldSymbol, printer: PrettyPrinter) + + public object AS_FIELD_KEYWROD : KtBackingFieldSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtBackingFieldSymbol, printer: PrettyPrinter): Unit = printer { + keywordRender.renderKeyword(KtTokens.FIELD_KEYWORD, symbol, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtCallableReceiverTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtCallableReceiverTypeRenderer.kt new file mode 100644 index 00000000000..0b5f0567ee4 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtCallableReceiverTypeRenderer.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.types.Variance + +public interface KtCallableReceiverTypeRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderReceiverType(symbol: KtCallableSymbol, printer: PrettyPrinter) + + public object WITH_IN_APPROXIMATION : KtCallableReceiverTypeRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderReceiverType(symbol: KtCallableSymbol, printer: PrettyPrinter) { + val receiverType = symbol.receiverType?.let { declarationTypeApproximator.approximateType(it, Variance.IN_VARIANCE) } ?: return + typeRenderer.renderType(receiverType, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtCallableReturnTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtCallableReturnTypeRenderer.kt new file mode 100644 index 00000000000..42f4a36f274 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtCallableReturnTypeRenderer.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.types.Variance + +public interface KtCallableReturnTypeRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderReturnType(symbol: KtCallableSymbol, printer: PrettyPrinter) + + public object WITH_OUT_APPROXIMATION : KtCallableReturnTypeRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderReturnType(symbol: KtCallableSymbol, printer: PrettyPrinter) { + if (symbol is KtConstructorSymbol) return + val type = declarationTypeApproximator.approximateType(symbol.returnType, Variance.OUT_VARIANCE) + if (!returnTypeFilter.shouldRenderReturnType(type, symbol)) return + typeRenderer.renderType(type, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtCallableSignatureRender.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtCallableSignatureRender.kt new file mode 100644 index 00000000000..8a152ecee32 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtCallableSignatureRender.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderAnnotationsAndModifiers +import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtKeywordToken + +public interface KtCallableSignatureRender { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderCallableSignature(symbol: KtCallableSymbol, keyword: KtKeywordToken?, printer: PrettyPrinter) + + public object FOR_SOURCE : KtCallableSignatureRender { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderCallableSignature(symbol: KtCallableSymbol, keyword: KtKeywordToken?, printer: PrettyPrinter): Unit = printer { + " ".separated( + { + if (keyword != null) renderAnnotationsAndModifiers(symbol, printer, keyword) + else renderAnnotationsAndModifiers(symbol, printer) + }, + { typeParametersRenderer.renderTypeParameters(symbol, printer) }, + { + withSuffix(".") { receiverTyperRenderer.renderReceiverType(symbol, printer) } + if (symbol is KtNamedSymbol) { + nameRenderer.renderName(symbol, printer) + } + }, + ) + " ".separated( + { + valueParametersRenderer.renderValueParameters(symbol, printer) + withPrefix(": ") { returnTypeRenderer.renderReturnType(symbol, printer) } + }, + { typeParametersRenderer.renderWhereClause(symbol, printer) }, + ) + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtConstructorSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtConstructorSymbolRenderer.kt new file mode 100644 index 00000000000..e463df61a5f --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtConstructorSymbolRenderer.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtConstructorSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtConstructorSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtConstructorSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtConstructorSymbol, printer: PrettyPrinter) { + callableSignatureRenderer.renderCallableSignature(symbol, KtTokens.CONSTRUCTOR_KEYWORD, printer) + functionLikeBodyRenderer.renderBody(symbol, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtEnumEntrySymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtEnumEntrySymbolRenderer.kt new file mode 100644 index 00000000000..b08922cef40 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtEnumEntrySymbolRenderer.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderAnnotationsAndModifiers +import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtEnumEntrySymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtEnumEntrySymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtEnumEntrySymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtEnumEntrySymbol, printer: PrettyPrinter): Unit = printer { + " ".separated( + { renderAnnotationsAndModifiers(symbol, printer) }, + { nameRenderer.renderName(symbol, printer) }, + { classifierBodyRenderer.renderBody(symbol, printer) }, + ) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtFunctionSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtFunctionSymbolRenderer.kt new file mode 100644 index 00000000000..09b7179ebd6 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtFunctionSymbolRenderer.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtFunctionSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtFunctionSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtFunctionSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtFunctionSymbol, printer: PrettyPrinter) { + callableSignatureRenderer.renderCallableSignature(symbol, KtTokens.FUN_KEYWORD, printer) + functionLikeBodyRenderer.renderBody(symbol, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtJavaFieldSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtJavaFieldSymbolRenderer.kt new file mode 100644 index 00000000000..1d694e409b7 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtJavaFieldSymbolRenderer.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtJavaFieldSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtJavaFieldSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtJavaFieldSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtJavaFieldSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtJavaFieldSymbol, printer: PrettyPrinter): Unit = printer { + val mutabilityKeyword = if (symbol.isVal) KtTokens.VAL_KEYWORD else KtTokens.VAR_KEYWORD + callableSignatureRenderer.renderCallableSignature(symbol, mutabilityKeyword, printer) + variableInitializerRenderer.renderInitializer(symbol, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtKotlinPropertySymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtKotlinPropertySymbolRenderer.kt new file mode 100644 index 00000000000..17c36a57ae0 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtKotlinPropertySymbolRenderer.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtKotlinPropertySymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtKotlinPropertySymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtKotlinPropertySymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtKotlinPropertySymbol, printer: PrettyPrinter): Unit = printer { + val mutabilityKeyword = if (symbol.isVal) KtTokens.VAL_KEYWORD else KtTokens.VAR_KEYWORD + callableSignatureRenderer.renderCallableSignature(symbol, mutabilityKeyword, printer) + variableInitializerRenderer.renderInitializer(symbol, printer) + propertyAccessorsRenderer.renderAccessors(symbol, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtLocalVariableSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtLocalVariableSymbolRenderer.kt new file mode 100644 index 00000000000..8c3869595af --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtLocalVariableSymbolRenderer.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtLocalVariableSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtLocalVariableSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtLocalVariableSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtLocalVariableSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtLocalVariableSymbol, printer: PrettyPrinter) { + val mutabilityKeyword = if (symbol.isVal) KtTokens.VAL_KEYWORD else KtTokens.VAR_KEYWORD + callableSignatureRenderer.renderCallableSignature(symbol, mutabilityKeyword, printer) + variableInitializerRenderer.renderInitializer(symbol, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtPropertyAccessorsRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtPropertyAccessorsRenderer.kt new file mode 100644 index 00000000000..1e16922f2e7 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtPropertyAccessorsRenderer.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.annotations +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyGetterSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySetterSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull + +public interface KtPropertyAccessorsRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderAccessors(symbol: KtPropertySymbol, printer: PrettyPrinter) + + public object ALL : KtPropertyAccessorsRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderAccessors(symbol: KtPropertySymbol, printer: PrettyPrinter): Unit = printer { + val toRender = listOfNotNull(symbol.getter, symbol.setter).ifEmpty { return } + append("\n") + withIndent { + "\n".separated( + { toRender.firstIsInstanceOrNull()?.let { getterRenderer.renderSymbol(it, printer) } }, + { toRender.firstIsInstanceOrNull()?.let { setterRenderer.renderSymbol(it, printer) } }, + ) + } + } + } + + public object NO_DEFAULT : KtPropertyAccessorsRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderAccessors(symbol: KtPropertySymbol, printer: PrettyPrinter): Unit = printer { + val toRender = listOfNotNull(symbol.getter, symbol.setter) + .filter { !it.isDefault || it.annotations.isNotEmpty() } + .ifEmpty { return } + append("\n") + withIndent { + "\n".separated( + { toRender.firstIsInstanceOrNull()?.let { getterRenderer.renderSymbol(it, printer) } }, + { toRender.firstIsInstanceOrNull()?.let { setterRenderer.renderSymbol(it, printer) } }, + ) + } + + } + } + + + public object NONE : KtPropertyAccessorsRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderAccessors(symbol: KtPropertySymbol, printer: PrettyPrinter) { + } + } + +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtPropertyGetterSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtPropertyGetterSymbolRenderer.kt new file mode 100644 index 00000000000..4595c2739a8 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtPropertyGetterSymbolRenderer.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderAnnotationsAndModifiers +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyGetterSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtPropertyGetterSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtPropertyGetterSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtPropertyGetterSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtPropertyGetterSymbol, printer: PrettyPrinter): Unit = printer { + " ".separated( + { + renderAnnotationsAndModifiers(symbol, printer, KtTokens.GET_KEYWORD) + valueParametersRenderer.renderValueParameters(symbol, printer) + }, + { accessorBodyRenderer.renderBody(symbol, printer) }, + ) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtPropertySetterSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtPropertySetterSymbolRenderer.kt new file mode 100644 index 00000000000..08e8405c8e3 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtPropertySetterSymbolRenderer.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderAnnotationsAndModifiers +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySetterSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtPropertySetterSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtPropertySetterSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtPropertySetterSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtPropertySetterSymbol, printer: PrettyPrinter): Unit = printer { + " ".separated( + { + renderAnnotationsAndModifiers(symbol, printer, KtTokens.SET_KEYWORD) + valueParametersRenderer.renderValueParameters(symbol, printer) + }, + { accessorBodyRenderer.renderBody(symbol, printer) }, + ) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtSamConstructorSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtSamConstructorSymbolRenderer.kt new file mode 100644 index 00000000000..b0a866bcbb7 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtSamConstructorSymbolRenderer.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtSamConstructorSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtSamConstructorSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtSamConstructorSymbol, printer: PrettyPrinter) + + public object NOT_RENDER : KtSamConstructorSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtSamConstructorSymbol, printer: PrettyPrinter): Unit = printer { + } + } + + public object AS_FUNCTION : KtSamConstructorSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtSamConstructorSymbol, printer: PrettyPrinter): Unit = printer { + callableSignatureRenderer.renderCallableSignature(symbol, keyword = null, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtSyntheticJavaPropertySymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtSyntheticJavaPropertySymbolRenderer.kt new file mode 100644 index 00000000000..7005ea86668 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtSyntheticJavaPropertySymbolRenderer.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtSyntheticJavaPropertySymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtSyntheticJavaPropertySymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtSyntheticJavaPropertySymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtSyntheticJavaPropertySymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtSyntheticJavaPropertySymbol, printer: PrettyPrinter): Unit = printer { + val mutabilityKeyword = if (symbol.isVal) KtTokens.VAL_KEYWORD else KtTokens.VAR_KEYWORD + callableSignatureRenderer.renderCallableSignature(symbol, mutabilityKeyword, printer) + variableInitializerRenderer.renderInitializer(symbol, printer) + propertyAccessorsRenderer.renderAccessors(symbol, printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtValueParameterSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtValueParameterSymbolRenderer.kt new file mode 100644 index 00000000000..81027afed27 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtValueParameterSymbolRenderer.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtValueParameterSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtValueParameterSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtValueParameterSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtValueParameterSymbol, printer: PrettyPrinter): Unit = printer { + " = ".separated( + { callableSignatureRenderer.renderCallableSignature(symbol, keyword = null, printer) }, + { parameterDefaultValueRenderer.renderDefaultValue(symbol, printer) }, + ) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtAnonymousObjectSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtAnonymousObjectSymbolRenderer.kt new file mode 100644 index 00000000000..389482fb05c --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtAnonymousObjectSymbolRenderer.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.classifiers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderAnnotationsAndModifiers +import org.jetbrains.kotlin.analysis.api.symbols.KtAnonymousObjectSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtAnonymousObjectSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtAnonymousObjectSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtAnonymousObjectSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtAnonymousObjectSymbol, printer: PrettyPrinter): Unit = printer { + " ".separated( + { + " : ".separated( + { renderAnnotationsAndModifiers(symbol, printer, KtTokens.OBJECT_KEYWORD) }, + { superTypeListRenderer.renderSuperTypes(symbol, printer) } + ) + }, + { classifierBodyRenderer.renderBody(symbol, printer) }, + ) + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtNamedClassOrObjectSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtNamedClassOrObjectSymbolRenderer.kt new file mode 100644 index 00000000000..6c63da69ed7 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtNamedClassOrObjectSymbolRenderer.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.classifiers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderAnnotationsAndModifiers +import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind +import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtNamedClassOrObjectSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtNamedClassOrObjectSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtNamedClassOrObjectSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtNamedClassOrObjectSymbol, printer: PrettyPrinter): Unit = printer { + val keywords = when (symbol.classKind) { + KtClassKind.CLASS -> listOf(KtTokens.CLASS_KEYWORD) + KtClassKind.ENUM_CLASS -> listOf(KtTokens.ENUM_KEYWORD, KtTokens.CLASS_KEYWORD) + KtClassKind.ANNOTATION_CLASS -> listOf(KtTokens.ANNOTATION_KEYWORD, KtTokens.CLASS_KEYWORD) + KtClassKind.OBJECT -> listOf(KtTokens.OBJECT_KEYWORD) + KtClassKind.COMPANION_OBJECT -> listOf(KtTokens.COMPANION_KEYWORD, KtTokens.OBJECT_KEYWORD) + KtClassKind.INTERFACE -> listOf(KtTokens.INTERFACE_KEYWORD) + KtClassKind.ANONYMOUS_OBJECT -> error("KtNamedClassOrObjectSymbol cannot be KtAnonymousObjectSymbol") + } + + " ".separated( + { renderAnnotationsAndModifiers(symbol, printer, keywords) }, + { + val primaryConstructor = + bodyMemberScopeProvider.getMemberScope(symbol).filterIsInstance() + .firstOrNull { it.isPrimary } + + nameRenderer.renderName(symbol, printer) + typeParametersRenderer.renderTypeParameters(symbol, printer) + if (primaryConstructor != null) { + val annotationsPrinted = checkIfPrinted { renderAnnotationsAndModifiers(primaryConstructor, printer) } + if (annotationsPrinted) { + withPrefix(" ") { + keywordRender.renderKeyword(KtTokens.CONSTRUCTOR_KEYWORD, primaryConstructor, printer) + } + } + if (primaryConstructor.valueParameters.isNotEmpty()) { + valueParametersRenderer.renderValueParameters(primaryConstructor, printer) + } + } + }, + { typeParametersRenderer.renderWhereClause(symbol, printer) }, + { withPrefix(": ") { superTypeListRenderer.renderSuperTypes(symbol, printer) } }, + { classifierBodyRenderer.renderBody(symbol, printer) } + ) + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtSingleTypeParameterSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtSingleTypeParameterSymbolRenderer.kt new file mode 100644 index 00000000000..085618c80ea --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtSingleTypeParameterSymbolRenderer.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.classifiers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.types.Variance + +public interface KtSingleTypeParameterSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtTypeParameterSymbol, printer: PrettyPrinter) + + public object NO : KtSingleTypeParameterSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtTypeParameterSymbol, printer: PrettyPrinter) { + } + } + + + public object WITHOUT_BOUNDS : KtSingleTypeParameterSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtTypeParameterSymbol, printer: PrettyPrinter): Unit = printer { + " ".separated( + { modifiersRenderer.renderDeclarationModifiers(symbol, printer) }, + { nameRenderer.renderName(symbol, printer) }, + ) + } + } + + public object WITH_COMMA_SEPARATED_BOUNDS : KtSingleTypeParameterSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtTypeParameterSymbol, printer: PrettyPrinter): Unit = printer { + " ".separated( + { modifiersRenderer.renderDeclarationModifiers(symbol, printer) }, + { nameRenderer.renderName(symbol, printer) }, + { + if (symbol.upperBounds.isNotEmpty()) { + withPrefix(": ") { + printCollection(symbol.upperBounds) { + typeRenderer.renderType(declarationTypeApproximator.approximateType(it, Variance.OUT_VARIANCE), printer) + } + } + } + } + ) + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtTypeAliasSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtTypeAliasSymbolRenderer.kt new file mode 100644 index 00000000000..200db0eb9bc --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/classifiers/KtTypeAliasSymbolRenderer.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.renderers.classifiers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderAnnotationsAndModifiers +import org.jetbrains.kotlin.analysis.api.symbols.KtTypeAliasSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtTypeAliasSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtTypeAliasSymbol, printer: PrettyPrinter) + + public object AS_SOURCE : KtTypeAliasSymbolRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtTypeAliasSymbol, printer: PrettyPrinter): Unit = printer { + " ".separated( + { renderAnnotationsAndModifiers(symbol, printer, KtTokens.TYPE_ALIAS_KEYWORD) }, + { + " = ".separated( + { + nameRenderer.renderName(symbol, printer) + typeParametersRenderer.renderTypeParameters(symbol, printer) + }, + { typeRenderer.renderType(symbol.expandedType, printer) }) + } + ) + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypeListRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypeListRenderer.kt new file mode 100644 index 00000000000..0d2efecde12 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypeListRenderer.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.superTypes + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtSuperTypeListRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSuperTypes(symbol: KtClassOrObjectSymbol, printer: PrettyPrinter) + + public object AS_LIST : KtSuperTypeListRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSuperTypes(symbol: KtClassOrObjectSymbol, printer: PrettyPrinter): Unit = printer { + val superTypesToRender = symbol.superTypes.filter { superTypesFilter.filter(it, symbol) }.ifEmpty { return } + printCollection(superTypesToRender) { type -> + superTypeRenderer.renderSuperType(type, symbol, printer) + superTypesArgumentRenderer.renderSuperTypeArguments(type, symbol, printer) + } + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypeRenderer.kt new file mode 100644 index 00000000000..7e6bcded111 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypeRenderer.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.superTypes + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.types.Variance + +public interface KtSuperTypeRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSuperType(type: KtType, symbol: KtClassOrObjectSymbol, printer: PrettyPrinter) + + public object WITH_OUT_APPROXIMATION : KtSuperTypeRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSuperType(type: KtType, symbol: KtClassOrObjectSymbol, printer: PrettyPrinter) { + typeRenderer.renderType(declarationTypeApproximator.approximateType(type, Variance.OUT_VARIANCE), printer) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypesCallArgumentsRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypesCallArgumentsRenderer.kt new file mode 100644 index 00000000000..83eda5536cd --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypesCallArgumentsRenderer.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.superTypes + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.types.KtClassType +import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtSuperTypesCallArgumentsRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSuperTypeArguments(type: KtType, symbol: KtClassOrObjectSymbol, printer: PrettyPrinter) + + public object NO_ARGS : KtSuperTypesCallArgumentsRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSuperTypeArguments(type: KtType, symbol: KtClassOrObjectSymbol, printer: PrettyPrinter) { + } + } + + public object EMPTY_PARENS : KtSuperTypesCallArgumentsRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSuperTypeArguments(type: KtType, symbol: KtClassOrObjectSymbol, printer: PrettyPrinter) { + if ((type as? KtClassType)?.expandedClassSymbol?.classKind?.isClass != true) { + return + } + printer.append("()") + } + } + +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypesFilter.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypesFilter.kt new file mode 100644 index 00000000000..2b44edc77fe --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/superTypes/KtSuperTypesFilter.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.declarations.superTypes + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind +import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.name.StandardClassIds + +public fun interface KtSuperTypesFilter { + context(KtAnalysisSession) + public fun filter(superType: KtType, symbol: KtClassOrObjectSymbol): Boolean + + public object NO_DEFAULT_TYPES : KtSuperTypesFilter { + context(KtAnalysisSession) + override fun filter(superType: KtType, symbol: KtClassOrObjectSymbol): Boolean { + if (superType.isAny) return false + if (symbol.classKind == KtClassKind.ANNOTATION_CLASS && superType.isClassTypeWithClassId(StandardClassIds.Annotation)) return false + if (symbol.classKind == KtClassKind.ENUM_CLASS && superType.isClassTypeWithClassId(StandardClassIds.Enum)) return false + return true + } + } + + public object NO_ANY_FOR_INTERFACES : KtSuperTypesFilter { + context(KtAnalysisSession) + override fun filter(superType: KtType, symbol: KtClassOrObjectSymbol): Boolean { + return when (symbol.classKind) { + KtClassKind.INTERFACE -> !superType.isAny + else -> true + } + } + } + + public object ALL : KtSuperTypesFilter { + context(KtAnalysisSession) + override fun filter(superType: KtType, symbol: KtClassOrObjectSymbol): Boolean { + return true + } + } + + public object NONE : KtSuperTypesFilter { + context(KtAnalysisSession) + override fun filter(superType: KtType, symbol: KtClassOrObjectSymbol): Boolean { + return false + } + } + + + public companion object { + public operator fun invoke( + predicate: context(KtAnalysisSession) (type: KtType, symbol: KtClassOrObjectSymbol) -> Boolean + ): KtSuperTypesFilter = object : KtSuperTypesFilter { + context(KtAnalysisSession) override fun filter(superType: KtType, symbol: KtClassOrObjectSymbol): Boolean { + return predicate(this@KtAnalysisSession, superType, symbol) + } + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/KtTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/KtTypeRenderer.kt new file mode 100644 index 00000000000..c07514e91a5 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/KtTypeRenderer.kt @@ -0,0 +1,122 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.base.KtKeywordRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtAnnotationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtRendererTypeApproximator +import org.jetbrains.kotlin.analysis.api.renderer.types.renders.* +import org.jetbrains.kotlin.analysis.api.types.* +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public class KtTypeRenderer private constructor( + public val capturedTypeRenderer: KtCapturedTypeRenderer, + public val definitelyNotNullTypeRenderer: KtDefinitelyNotNullTypeRenderer, + public val dynamicTypeRenderer: KtDynamicTypeRenderer, + public val flexibleTypeRenderer: KtFlexibleTypeRenderer, + public val functionalTypeRenderer: KtFunctionalTypeRenderer, + public val integerLiteralTypeRenderer: KtIntegerLiteralTypeRenderer, + public val intersectionTypeRenderer: KtIntersectionTypeRenderer, + public val typeErrorTypeRenderer: KtTypeErrorTypeRenderer, + public val typeParameterTypeRenderer: KtTypeParameterTypeRenderer, + public val unresolvedClassErrorTypeRenderer: KtUnresolvedClassErrorTypeRenderer, + public val usualClassTypeRenderer: KtUsualClassTypeRenderer, + + public val classIdRenderer: KtClassTypeQualifierRenderer, + public val typeNameRenderer: KtTypeNameRenderer, + public val typeApproximator: KtRendererTypeApproximator, + public val typeProjectionRenderer: KtTypeProjectionRenderer, + public val annotationsRender: KtAnnotationRenderer, + public val keywordRenderer: KtKeywordRenderer, +) { + context(KtAnalysisSession) + public fun renderType(type: KtType, printer: PrettyPrinter) { + when (type) { + is KtCapturedType -> capturedTypeRenderer.renderType(type, printer) + is KtFunctionalType -> functionalTypeRenderer.renderType(type, printer) + is KtUsualClassType -> usualClassTypeRenderer.renderType(type, printer) + is KtDefinitelyNotNullType -> definitelyNotNullTypeRenderer.renderType(type, printer) + is KtDynamicType -> dynamicTypeRenderer.renderType(type, printer) + is KtFlexibleType -> flexibleTypeRenderer.renderType(type, printer) + is KtIntegerLiteralType -> integerLiteralTypeRenderer.renderType(type, printer) + is KtIntersectionType -> intersectionTypeRenderer.renderType(type, printer) + is KtTypeParameterType -> typeParameterTypeRenderer.renderType(type, printer) + is KtClassErrorType -> unresolvedClassErrorTypeRenderer.renderType(type, printer) + is KtTypeErrorType -> typeErrorTypeRenderer.renderType(type, printer) + } + } + + public fun with(action: Builder.() -> Unit): KtTypeRenderer { + val renderer = this + return KtTypeRenderer { + this.capturedTypeRenderer = renderer.capturedTypeRenderer + this.definitelyNotNullTypeRenderer = renderer.definitelyNotNullTypeRenderer + this.dynamicTypeRenderer = renderer.dynamicTypeRenderer + this.flexibleTypeRenderer = renderer.flexibleTypeRenderer + this.functionalTypeRenderer = renderer.functionalTypeRenderer + this.integerLiteralTypeRenderer = renderer.integerLiteralTypeRenderer + this.intersectionTypeRenderer = renderer.intersectionTypeRenderer + this.typeErrorTypeRenderer = renderer.typeErrorTypeRenderer + this.typeParameterTypeRenderer = renderer.typeParameterTypeRenderer + this.unresolvedClassErrorTypeRenderer = renderer.unresolvedClassErrorTypeRenderer + this.usualClassTypeRenderer = renderer.usualClassTypeRenderer + this.classIdRenderer = renderer.classIdRenderer + this.typeNameRenderer = renderer.typeNameRenderer + this.typeApproximator = renderer.typeApproximator + this.typeProjectionRenderer = renderer.typeProjectionRenderer + this.annotationsRender = renderer.annotationsRender + this.keywordRenderer = renderer.keywordRenderer + action() + } + } + + public companion object { + public operator fun invoke(action: Builder.() -> Unit): KtTypeRenderer = + Builder().apply(action).build() + } + + public class Builder { + public lateinit var capturedTypeRenderer: KtCapturedTypeRenderer + public lateinit var definitelyNotNullTypeRenderer: KtDefinitelyNotNullTypeRenderer + public lateinit var dynamicTypeRenderer: KtDynamicTypeRenderer + public lateinit var flexibleTypeRenderer: KtFlexibleTypeRenderer + public lateinit var functionalTypeRenderer: KtFunctionalTypeRenderer + public lateinit var integerLiteralTypeRenderer: KtIntegerLiteralTypeRenderer + public lateinit var intersectionTypeRenderer: KtIntersectionTypeRenderer + public lateinit var typeErrorTypeRenderer: KtTypeErrorTypeRenderer + public lateinit var typeParameterTypeRenderer: KtTypeParameterTypeRenderer + public lateinit var unresolvedClassErrorTypeRenderer: KtUnresolvedClassErrorTypeRenderer + public lateinit var usualClassTypeRenderer: KtUsualClassTypeRenderer + public lateinit var classIdRenderer: KtClassTypeQualifierRenderer + public lateinit var typeNameRenderer: KtTypeNameRenderer + public lateinit var typeApproximator: KtRendererTypeApproximator + public lateinit var typeProjectionRenderer: KtTypeProjectionRenderer + public lateinit var annotationsRender: KtAnnotationRenderer + public lateinit var keywordRenderer: KtKeywordRenderer + + + public fun build(): KtTypeRenderer = KtTypeRenderer( + capturedTypeRenderer, + definitelyNotNullTypeRenderer, + dynamicTypeRenderer, + flexibleTypeRenderer, + functionalTypeRenderer, + integerLiteralTypeRenderer, + intersectionTypeRenderer, + typeErrorTypeRenderer, + typeParameterTypeRenderer, + unresolvedClassErrorTypeRenderer, + usualClassTypeRenderer, + classIdRenderer, + typeNameRenderer, + typeApproximator, + typeProjectionRenderer, + annotationsRender, + keywordRenderer, + ) + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/impl/KtTypeRendererForDebug.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/impl/KtTypeRendererForDebug.kt new file mode 100644 index 00000000000..0543f462e04 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/impl/KtTypeRendererForDebug.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.impl + +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.renderer.types.renders.KtCapturedTypeRenderer +import org.jetbrains.kotlin.analysis.api.renderer.types.renders.KtFlexibleTypeRenderer +import org.jetbrains.kotlin.analysis.api.renderer.types.renders.KtTypeErrorTypeRenderer +import org.jetbrains.kotlin.analysis.api.renderer.types.renders.KtUnresolvedClassErrorTypeRenderer + +public object KtTypeRendererForDebug { + public val WITH_QUALIFIED_NAMES: KtTypeRenderer = KtTypeRendererForSource.WITH_QUALIFIED_NAMES.with { + capturedTypeRenderer = KtCapturedTypeRenderer.AS_CAPUTRED_TYPE_WITH_PROJECTION + flexibleTypeRenderer = KtFlexibleTypeRenderer.AS_SHORT + typeErrorTypeRenderer = KtTypeErrorTypeRenderer.WITH_ERROR_MESSAGE + unresolvedClassErrorTypeRenderer = KtUnresolvedClassErrorTypeRenderer.WITH_ERROR_MESSAGE + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/impl/KtTypeRendererForSource.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/impl/KtTypeRendererForSource.kt new file mode 100644 index 00000000000..d0ee54d1233 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/impl/KtTypeRendererForSource.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.impl + +import org.jetbrains.kotlin.analysis.api.renderer.base.KtKeywordRenderer +import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtAnnotationRendererForSource +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtRendererTypeApproximator +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.renderer.types.renders.* + +public object KtTypeRendererForSource { + public val WITH_QUALIFIED_NAMES: KtTypeRenderer = KtTypeRenderer { + capturedTypeRenderer = KtCapturedTypeRenderer.AS_RPOJECTION + definitelyNotNullTypeRenderer = KtDefinitelyNotNullTypeRenderer.AS_TYPE_INTERSECTION + dynamicTypeRenderer = KtDynamicTypeRenderer.AS_DYNAMIC_WORD + flexibleTypeRenderer = KtFlexibleTypeRenderer.AS_SHORT + functionalTypeRenderer = KtFunctionalTypeRenderer.AS_FUNCTIONAL_TYPE + integerLiteralTypeRenderer = KtIntegerLiteralTypeRenderer.AS_ILT_WITH_VALUE + intersectionTypeRenderer = KtIntersectionTypeRenderer.AS_INTERSECTION + typeErrorTypeRenderer = KtTypeErrorTypeRenderer.AS_CODE_IF_POSSIBLE + typeParameterTypeRenderer = KtTypeParameterTypeRenderer.AS_SOURCE + unresolvedClassErrorTypeRenderer = KtUnresolvedClassErrorTypeRenderer.UNRESOLVED_QUALIFIER + usualClassTypeRenderer = KtUsualClassTypeRenderer.AS_CLASS_TYPE_WITH_TYPE_ARGUMENTS + classIdRenderer = KtClassTypeQualifierRenderer.WITH_QUALIFIED_NAMES + typeNameRenderer = KtTypeNameRenderer.QUOTED + typeApproximator = KtRendererTypeApproximator.TO_DENNOTABLE + typeProjectionRenderer = KtTypeProjectionRenderer.WITH_VARIANCE + annotationsRender = KtAnnotationRendererForSource.WITH_QUALIFIED_NAMES + keywordRenderer = KtKeywordRenderer.AS_WORD + } + + public val WITH_SHORT_NAMES: KtTypeRenderer = WITH_QUALIFIED_NAMES.with { + classIdRenderer = KtClassTypeQualifierRenderer.WITH_SHORT_NAMES_WITH_NESTED_CLASSIFIERS + annotationsRender = KtAnnotationRendererForSource.WITH_SHORT_NAMES + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtCapturedTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtCapturedTypeRenderer.kt new file mode 100644 index 00000000000..66f21ea1343 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtCapturedTypeRenderer.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtCapturedType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + + +public interface KtCapturedTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtCapturedType, printer: PrettyPrinter) + + public object AS_RPOJECTION : KtCapturedTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtCapturedType, printer: PrettyPrinter) { + typeProjectionRenderer.renderTypeProjection(type.projection, printer) + } + } + + public object AS_CAPUTRED_TYPE_WITH_PROJECTION : KtCapturedTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtCapturedType, printer: PrettyPrinter) { + printer.append("CapturedType(") + AS_RPOJECTION.renderType(type, printer) + printer.append(")") + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtClassTypeQualifierRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtClassTypeQualifierRenderer.kt new file mode 100644 index 00000000000..9601ce459ed --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtClassTypeQualifierRenderer.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtClassType +import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.renderer.render + +public interface KtClassTypeQualifierRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderClassTypeQualifier(type: KtClassType, printer: PrettyPrinter) + + public object WITH_SHORT_NAMES : KtClassTypeQualifierRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderClassTypeQualifier(type: KtClassType, printer: PrettyPrinter) { + typeNameRenderer.renderName(type.qualifiers.last().name, type, printer) + } + } + + public object WITH_SHORT_NAMES_WITH_NESTED_CLASSIFIERS : KtClassTypeQualifierRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderClassTypeQualifier(type: KtClassType, printer: PrettyPrinter): Unit = printer { + printCollection(type.qualifiers, separator = ".") { qualifier -> + typeNameRenderer.renderName(qualifier.name, type, printer) + printCollectionIfNotEmpty(qualifier.typeArguments, prefix = "<", postfix = ">") { + typeProjectionRenderer.renderTypeProjection(it, this) + } + } + } + } + + public object WITH_QUALIFIED_NAMES : KtClassTypeQualifierRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderClassTypeQualifier(type: KtClassType, printer: PrettyPrinter): Unit = printer { + ".".separated( + { + if (type is KtNonErrorClassType) { + append(type.classId.packageFqName.render()) + } + }, + { WITH_SHORT_NAMES_WITH_NESTED_CLASSIFIERS.renderClassTypeQualifier(type, printer) }, + ) + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtDefinitelyNotNullTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtDefinitelyNotNullTypeRenderer.kt new file mode 100644 index 00000000000..95876ebe3a1 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtDefinitelyNotNullTypeRenderer.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtDefinitelyNotNullType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + + +public interface KtDefinitelyNotNullTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtDefinitelyNotNullType, printer: PrettyPrinter) + + public object AS_TYPE_INTERSECTION : KtDefinitelyNotNullTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtDefinitelyNotNullType, printer: PrettyPrinter): Unit = printer { + renderType(type.original, printer) + printer.append(" & ") + renderType(builtinTypes.ANY, printer) + } + } + +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtDynamicTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtDynamicTypeRenderer.kt new file mode 100644 index 00000000000..c4b8286be1a --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtDynamicTypeRenderer.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtDynamicType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + + +public interface KtDynamicTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtDynamicType, printer: PrettyPrinter) + + public object AS_DYNAMIC_WORD : KtDynamicTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtDynamicType, printer: PrettyPrinter) { + keywordRenderer.renderKeyword(KtTokens.DYNAMIC_KEYWORD, type, printer) + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtFlexibleTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtFlexibleTypeRenderer.kt new file mode 100644 index 00000000000..8b2baed78e9 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtFlexibleTypeRenderer.kt @@ -0,0 +1,94 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.* +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.name.StandardClassIds +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract + + +public interface KtFlexibleTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtFlexibleType, printer: PrettyPrinter) + + public object AS_RANGE : KtFlexibleTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtFlexibleType, printer: PrettyPrinter): Unit = printer { + append('(') + renderType(type.lowerBound, printer) + append("..") + renderType(type.upperBound, printer) + append(')') + } + } + + public object AS_SHORT : KtFlexibleTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtFlexibleType, printer: PrettyPrinter): Unit = printer { + val lower = type.lowerBound + val upper = type.upperBound + + when { + isNullabilityFlexibleType(lower, upper) -> { + renderType(lower, printer) + append("!") + } + + isMutabilityFlexibleType(lower, upper) -> { + " ".separated( + { annotationsRender.renderAnnotations(type, printer) }, + { append(lower.classId.asFqNameString().replace("Mutable", "(Mutable)")) }, + ) + printCollectionIfNotEmpty(lower.ownTypeArguments, prefix = "<", postfix = ">") { typeArgument -> + typeProjectionRenderer.renderTypeProjection(typeArgument, this) + } + if (lower.nullability != type.upperBound.nullability) { + append('!') + } + } + + else -> { + AS_RANGE.renderType(type, printer) + } + } + } + + private fun isNullabilityFlexibleType(lower: KtType, upper: KtType): Boolean { + val isTheSameType = lower is KtNonErrorClassType && upper is KtNonErrorClassType && lower.classId == upper.classId || + lower is KtTypeParameterType && upper is KtTypeParameterType && lower.symbol == upper.symbol + if (isTheSameType && + lower.nullability == KtTypeNullability.NON_NULLABLE + && upper.nullability == KtTypeNullability.NULLABLE + ) { + if ((lower !is KtNonErrorClassType || lower.ownTypeArguments.isEmpty()) && + (upper !is KtNonErrorClassType || upper.ownTypeArguments.isEmpty()) + ) { + return true + } + } + return false + } + + @OptIn(ExperimentalContracts::class) + private fun isMutabilityFlexibleType(lower: KtType, upper: KtType): Boolean { + contract { + returns(true) implies (lower is KtNonErrorClassType) + returns(true) implies (upper is KtNonErrorClassType) + } + if (lower !is KtNonErrorClassType || upper !is KtNonErrorClassType) return false + + if (StandardClassIds.Collections.mutableCollectionToBaseCollection[lower.classId] != upper.classId) return false + return true + } + + } + +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtFunctionalTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtFunctionalTypeRenderer.kt new file mode 100644 index 00000000000..96514850a9c --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtFunctionalTypeRenderer.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType +import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + + +public interface KtFunctionalTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtFunctionalType, printer: PrettyPrinter) + + public object AS_FUNCTIONAL_TYPE : KtFunctionalTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtFunctionalType, printer: PrettyPrinter): Unit = printer { + val annotationsRendererd = checkIfPrinted { annotationsRender.renderAnnotations(type, this) } + if (annotationsRendererd) printer.append(" ") + if (annotationsRendererd || type.nullability == KtTypeNullability.NULLABLE) append("(") + " ".separated( + { + if (type.isSuspend) { + keywordRenderer.renderKeyword(KtTokens.SUSPEND_KEYWORD, type, printer) + } + }, + { + type.receiverType?.let { renderType(it, printer); printer.append('.') } + printCollection(type.parameterTypes, prefix = "(", postfix = ")") { + renderType(it, this) + } + append(" -> ") + renderType(type.returnType, printer) + }, + ) + if (annotationsRendererd || type.nullability == KtTypeNullability.NULLABLE) append(")") + if (type.nullability == KtTypeNullability.NULLABLE) append("?") + } + } + + public object AS_CLASS_TYPE : KtFunctionalTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtFunctionalType, printer: PrettyPrinter): Unit = printer { + " ".separated( + { annotationsRender.renderAnnotations(type, printer) }, + { + classIdRenderer.renderClassTypeQualifier(type, printer) + if (type.nullability == KtTypeNullability.NULLABLE) { + append('?') + } + }, + ) + } + } + +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtIntegerLiteralTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtIntegerLiteralTypeRenderer.kt new file mode 100644 index 00000000000..a433710ac3a --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtIntegerLiteralTypeRenderer.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtIntegerLiteralType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + + +public interface KtIntegerLiteralTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtIntegerLiteralType, printer: PrettyPrinter) + + public object AS_ILT_WITH_VALUE : KtIntegerLiteralTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtIntegerLiteralType, printer: PrettyPrinter): Unit = printer { + append("ILT(") + printer.append(type.value.toString()) + append(')') + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtIntersectionTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtIntersectionTypeRenderer.kt new file mode 100644 index 00000000000..00a152c978e --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtIntersectionTypeRenderer.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtIntersectionType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + + +public interface KtIntersectionTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtIntersectionType, printer: PrettyPrinter) + + public object AS_INTERSECTION : KtIntersectionTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtIntersectionType, printer: PrettyPrinter): Unit = printer { + printCollection(type.conjuncts, separator = " & ") { + renderType(it, printer) + } + } + } + +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeErrorTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeErrorTypeRenderer.kt new file mode 100644 index 00000000000..82c23f6a152 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeErrorTypeRenderer.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtTypeErrorType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtTypeErrorTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtTypeErrorType, printer: PrettyPrinter) + + public object AS_CODE_IF_POSSIBLE : KtTypeErrorTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtTypeErrorType, printer: PrettyPrinter) { + type.tryRenderAsNonErrorType()?.let { + printer.append(it) + return + } + printer.append("ERROR") + } + } + + public object AS_ERROR_WORD : KtTypeErrorTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtTypeErrorType, printer: PrettyPrinter) { + printer.append("ERROR") + } + } + + public object WITH_ERROR_MESSAGE : KtTypeErrorTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtTypeErrorType, printer: PrettyPrinter) { + printer.append("ERROR(${type.errorMessage})") + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeNameRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeNameRenderer.kt new file mode 100644 index 00000000000..5ee85eca1e4 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeNameRenderer.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.renderer.render + +public interface KtTypeNameRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderName(name: Name, owner: KtType, printer: PrettyPrinter) + + public object QUOTED : KtTypeNameRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderName(name: Name, owner: KtType, printer: PrettyPrinter) { + printer.append(name.render()) + } + } + + public object UNQUOTED : KtTypeNameRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderName(name: Name, owner: KtType, printer: PrettyPrinter) { + printer.append(name.asString()) + } + } + +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeParameterTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeParameterTypeRenderer.kt new file mode 100644 index 00000000000..63da3ae120a --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeParameterTypeRenderer.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability +import org.jetbrains.kotlin.analysis.api.types.KtTypeParameterType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + + +public interface KtTypeParameterTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtTypeParameterType, printer: PrettyPrinter) + + public object AS_SOURCE : KtTypeParameterTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtTypeParameterType, printer: PrettyPrinter): Unit = printer { + " ".separated( + { annotationsRender.renderAnnotations(type, printer) }, + { + typeNameRenderer.renderName(type.name, type, printer) + if (type.nullability == KtTypeNullability.NULLABLE) { + printer.append('?') + } + } + ) + + } + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeProjectionRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeProjectionRenderer.kt new file mode 100644 index 00000000000..71548a6d43a --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtTypeProjectionRenderer.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection +import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance +import org.jetbrains.kotlin.analysis.api.KtTypeProjection +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtTypeProjectionRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderTypeProjection(projection: KtTypeProjection, printer: PrettyPrinter) + + public object WITH_VARIANCE : KtTypeProjectionRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderTypeProjection(projection: KtTypeProjection, printer: PrettyPrinter): Unit = printer { + when (projection) { + is KtStarTypeProjection -> printer.append('*') + is KtTypeArgumentWithVariance -> { + " ".separated( + { printer.append(projection.variance.label) }, + { renderType(projection.type, printer) }, + ) + } + } + } + } + + public object WITHOUT_VARIANCE : KtTypeProjectionRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderTypeProjection(projection: KtTypeProjection, printer: PrettyPrinter) { + when (projection) { + is KtStarTypeProjection -> printer.append('*') + is KtTypeArgumentWithVariance -> { + renderType(projection.type, printer) + } + } + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtUnresolvedClassErrorTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtUnresolvedClassErrorTypeRenderer.kt new file mode 100644 index 00000000000..eef1659b5f2 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtUnresolvedClassErrorTypeRenderer.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + +public interface KtUnresolvedClassErrorTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtClassErrorType, printer: PrettyPrinter) + + public object UNRESOLVED_QUALIFIER : KtUnresolvedClassErrorTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtClassErrorType, printer: PrettyPrinter): Unit = printer { + annotationsRender.renderAnnotations(type, printer) + classIdRenderer.renderClassTypeQualifier(type, printer) + } + } + + + public object AS_ERROR_WORD : KtUnresolvedClassErrorTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtClassErrorType, printer: PrettyPrinter) { + printer.append("ERROR_TYPE") + } + } + + public object WITH_ERROR_MESSAGE : KtUnresolvedClassErrorTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtClassErrorType, printer: PrettyPrinter) { + printer.append("ERROR_TYPE(${type.errorMessage})") + } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtUsualClassTypeRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtUsualClassTypeRenderer.kt new file mode 100644 index 00000000000..530e1134a96 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/types/renders/KtUsualClassTypeRenderer.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2022 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.analysis.api.renderer.types.renders + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer +import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability +import org.jetbrains.kotlin.analysis.api.types.KtUsualClassType +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter + + +public interface KtUsualClassTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + public fun renderType(type: KtUsualClassType, printer: PrettyPrinter) + + public object AS_CLASS_TYPE_WITH_TYPE_ARGUMENTS : KtUsualClassTypeRenderer { + context(KtAnalysisSession, KtTypeRenderer) + override fun renderType(type: KtUsualClassType, printer: PrettyPrinter): Unit = printer { + " ".separated( + { annotationsRender.renderAnnotations(type, printer) }, + { + classIdRenderer.renderClassTypeQualifier(type, printer) + if (type.nullability == KtTypeNullability.NULLABLE) { + append('?') + } + }, + ) + } + } + +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtClassLikeSymbol.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtClassLikeSymbol.kt index 0fafcb6421e..9b1b37893b4 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtClassLikeSymbol.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtClassLikeSymbol.kt @@ -98,4 +98,5 @@ public enum class KtClassKind { ANONYMOUS_OBJECT; public val isObject: Boolean get() = this == OBJECT || this == COMPANION_OBJECT || this == ANONYMOUS_OBJECT + public val isClass: Boolean get() = this == CLASS || this == ANNOTATION_CLASS || this == ENUM_CLASS } diff --git a/analysis/analysis-internal-utils/build.gradle.kts b/analysis/analysis-internal-utils/build.gradle.kts index 78f57e0120c..26d7b99e265 100644 --- a/analysis/analysis-internal-utils/build.gradle.kts +++ b/analysis/analysis-internal-utils/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { implementation(project(":compiler:psi")) + implementation(kotlinxCollectionsImmutable()) implementation(intellijCore()) } diff --git a/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/printer/PrettyPrinter.kt b/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/printer/PrettyPrinter.kt index df866ac6432..7f638f753d8 100644 --- a/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/printer/PrettyPrinter.kt +++ b/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/printer/PrettyPrinter.kt @@ -5,13 +5,27 @@ package org.jetbrains.kotlin.analysis.utils.printer -import java.lang.Appendable +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf +import org.jetbrains.kotlin.utils.addToStdlib.ifTrue +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract -public class PrettyPrinter(private val indentSize: Int = 2) : Appendable { - private val builder = StringBuilder() - public var indent: Int = 0 +@OptIn(ExperimentalContracts::class) +public class PrettyPrinter(public val indentSize: Int = 2) : Appendable { + @PublishedApi + internal val builder: StringBuilder = StringBuilder() + + @PublishedApi + internal var prefixesToPrint: PersistentList = persistentListOf() + + @PublishedApi + internal var indent: Int = 0 override fun append(seq: CharSequence): Appendable = apply { + if (seq.isEmpty()) return@apply + printPrefixes() seq.split('\n').forEachIndexed { index, line -> if (index > 0) { builder.append('\n') @@ -26,12 +40,21 @@ public class PrettyPrinter(private val indentSize: Int = 2) : Appendable { } override fun append(c: Char): Appendable = apply { + printPrefixes() if (c != '\n') { appendIndentIfNeeded() } builder.append(c) } + private fun printPrefixes() { + if (prefixesToPrint.isNotEmpty()) { + appendIndentIfNeeded() + prefixesToPrint.forEach { builder.append(it) } + prefixesToPrint = persistentListOf() + } + } + public inline fun withIndent(block: PrettyPrinter.() -> Unit) { indent += 1 block(this) @@ -99,7 +122,86 @@ public class PrettyPrinter(private val indentSize: Int = 2) : Appendable { override fun toString(): String { return builder.toString() } + + public inline fun checkIfPrinted(render: () -> Unit): Boolean { + val initialSize = builder.length + render() + return initialSize != builder.length + } + + public inline operator fun invoke(print: PrettyPrinter.() -> Unit) { + this.print() + } + + public inline fun String.separated(p1: () -> Unit, p2: () -> Unit) { + contract { + callsInPlace(p1, InvocationKind.EXACTLY_ONCE) + callsInPlace(p2, InvocationKind.EXACTLY_ONCE) + } + val firstRendered = checkIfPrinted { p1() } + if (firstRendered) { + withPrefix(this, p2) + } else { + p2() + } + } + + public inline fun String.separated(p1: () -> Unit, p2: () -> Unit, p3: () -> Unit) { + contract { + callsInPlace(p1, InvocationKind.EXACTLY_ONCE) + callsInPlace(p2, InvocationKind.EXACTLY_ONCE) + callsInPlace(p3, InvocationKind.EXACTLY_ONCE) + } + separated({ separated(p1, p2) }, p3) + } + + public inline fun String.separated(p1: () -> Unit, p2: () -> Unit, p3: () -> Unit, p4: () -> Unit) { + contract { + callsInPlace(p1, InvocationKind.EXACTLY_ONCE) + callsInPlace(p2, InvocationKind.EXACTLY_ONCE) + callsInPlace(p3, InvocationKind.EXACTLY_ONCE) + callsInPlace(p4, InvocationKind.EXACTLY_ONCE) + } + separated({ separated(p1, p2, p3) }, p4) + } + + public inline fun String.separated(p1: () -> Unit, p2: () -> Unit, p3: () -> Unit, p4: () -> Unit, p5: () -> Unit) { + contract { + callsInPlace(p1, InvocationKind.EXACTLY_ONCE) + callsInPlace(p2, InvocationKind.EXACTLY_ONCE) + callsInPlace(p3, InvocationKind.EXACTLY_ONCE) + callsInPlace(p5, InvocationKind.EXACTLY_ONCE) + } + separated({ separated(p1, p2, p3, p4) }, p5) + } + + public inline fun withPrefix(prefix: String, print: () -> Unit) { + contract { + callsInPlace(print, InvocationKind.EXACTLY_ONCE) + } + val currentPrefixes = prefixesToPrint + prefixesToPrint = prefixesToPrint.add(prefix) + try { + print() + } finally { + if (prefixesToPrint.isNotEmpty()) { + prefixesToPrint = currentPrefixes + } + } + } + + public inline fun withSuffix(suffix: String, p1: () -> Unit) { + checkIfPrinted { p1() }.ifTrue { append(suffix) } + } } public inline fun prettyPrint(body: PrettyPrinter.() -> Unit): String = - PrettyPrinter().apply(body).toString() \ No newline at end of file + PrettyPrinter().apply(body).toString() + +@OptIn(ExperimentalContracts::class) +public inline fun prettyPrintWithSettingsFrom(other: PrettyPrinter, body: PrettyPrinter.() -> Unit): String { + contract { + callsInPlace(body, InvocationKind.EXACTLY_ONCE) + } + return PrettyPrinter(other.indentSize).apply(body).toString() +} \ No newline at end of file