From 604dec7a875c8f3409fe737384e0d54df7248e77 Mon Sep 17 00:00:00 2001 From: Pavel Kirpichenkov Date: Thu, 15 Feb 2024 17:08:38 +0200 Subject: [PATCH] [Tests] Move stub info extraction for test into a separate utility KTIJ-28668 --- .../files/AbstractAdditionalStubInfoTest.kt | 143 +---------------- .../files/AdditionalStubInfoExtraction.kt | 150 ++++++++++++++++++ 2 files changed, 151 insertions(+), 142 deletions(-) create mode 100644 analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoExtraction.kt diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt index 489aee134d1..03bd251201d 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt @@ -5,158 +5,17 @@ package org.jetbrains.kotlin.analysis.decompiler.stub.files -import com.intellij.psi.stubs.StubElement import com.intellij.util.indexing.FileContentImpl import org.jetbrains.kotlin.analysis.decompiler.stub.file.KotlinClsStubBuilder -import org.jetbrains.kotlin.contracts.description.* -import org.jetbrains.kotlin.psi.KtProjectionKind -import org.jetbrains.kotlin.psi.stubs.impl.* import org.jetbrains.kotlin.test.KotlinTestUtils import java.nio.file.Paths -import kotlin.reflect.KClass abstract class AbstractAdditionalStubInfoTest : AbstractDecompiledClassTest() { fun runTest(testDirectory: String) { val testDirectoryPath = Paths.get(testDirectory) val testData = TestData.createFromDirectory(testDirectoryPath) val stub = KotlinClsStubBuilder().buildFileStub(FileContentImpl.createByFile(getClassFileToDecompile(testData, false)))!! - val builder = StringBuilder() - extractAdditionInfo(stub, builder, 0) - KotlinTestUtils.assertEqualsToFile(testData.getExpectedFile(useK2ToCompileCode), builder.toString()) + KotlinTestUtils.assertEqualsToFile(testData.getExpectedFile(useK2ToCompileCode), extractAdditionalStubInfo(stub)) testData.checkIfIdentical(useK2ToCompileCode) } - - private fun extractAdditionInfo(stub: StubElement<*>, builder: StringBuilder, level: Int) { - builder.append(stub.toString()) - when (stub) { - is KotlinUserTypeStubImpl -> { - val upperBound = stub.upperBound - if (upperBound != null) { - builder.append(" ft: ") - appendFlexibleTypeInfo(builder, upperBound) - } - } - is KotlinFunctionStubImpl -> { - val contract = stub.contract - if (contract != null) { - for (element in contract) { - builder.append("\n" + " ".repeat(level)).append("effect:") - element.accept(KotlinContractRenderer(builder), null) - } - } - } - is KotlinPropertyStubImpl -> { - val initializer = stub.constantInitializer - if (initializer != null) { - builder.append("\n").append(" ".repeat(level)).append("initializer: ${initializer.value}") - } - } - is KotlinAnnotationEntryStubImpl -> { - val arguments = stub.valueArguments - if (arguments != null) { - builder - .append("\n") - .append(" ".repeat(level)) - .append("valueArguments: ") - .append(arguments.entries.joinToString(", ", "(", ")") { "${it.key.asString()} = ${it.value}" }) - } - } - is KotlinParameterStubImpl -> { - stub.functionTypeParameterName?.let { builder.append(" paramNameByAnnotation: ").append(it) } - } - } - for (child in stub.childrenStubs) { - builder.append("\n").append(" ".repeat(level)) - extractAdditionInfo(child, builder, level + 1) - } - } - - private fun appendFlexibleTypeInfo(builder: StringBuilder, typeBean: KotlinTypeBean) { - when (typeBean) { - is KotlinClassTypeBean -> { - builder.append(typeBean.classId.asFqNameString()) - val arguments = typeBean.arguments - if (arguments.isNotEmpty()) { - builder.append("<") - arguments.forEachIndexed { index, arg -> - if (index > 0) builder.append(", ") - if (arg.projectionKind != KtProjectionKind.NONE) { - builder.append(arg.projectionKind.name) - } - if (arg.projectionKind != KtProjectionKind.STAR) { - appendFlexibleTypeInfo(builder, arg.type!!) - } - } - builder.append(">") - } - if (typeBean.nullable) { - builder.append("?") - } - } - is KotlinTypeParameterTypeBean -> { - builder.append(typeBean.typeParameterName) - if (typeBean.nullable) { - builder.append("?") - } - if (typeBean.definitelyNotNull) { - builder.append(" & Any") - } - } - - is KotlinFlexibleTypeBean -> { - appendFlexibleTypeInfo(builder, typeBean.lowerBound) - builder.append(" .. ") - appendFlexibleTypeInfo(builder, typeBean.upperBound) - } - } - } } - -class KotlinContractRenderer(private val buffer: StringBuilder) : KtContractDescriptionVisitor() { - override fun visitConditionalEffectDeclaration(conditionalEffect: KtConditionalEffectDeclaration, data: Nothing?) { - conditionalEffect.effect.accept(this, data) - buffer.append(" -> ") - conditionalEffect.condition.accept(this, data) - } - - override fun visitReturnsEffectDeclaration(returnsEffect: KtReturnsEffectDeclaration, data: Nothing?) { - buffer.append("Returns(") - returnsEffect.value.accept(this, data) - buffer.append(")") - } - - override fun visitCallsEffectDeclaration(callsEffect: KtCallsEffectDeclaration, data: Nothing?) { - buffer.append("CallsInPlace(") - callsEffect.valueParameterReference.accept(this, data) - buffer.append(", ${callsEffect.kind})") - } - - override fun visitLogicalBinaryOperationContractExpression(binaryLogicExpression: KtBinaryLogicExpression, data: Nothing?) { - binaryLogicExpression.left.accept(this, data) - buffer.append(" ${binaryLogicExpression.kind.token} ") - binaryLogicExpression.right.accept(this, data) - } - - override fun visitLogicalNot(logicalNot: KtLogicalNot, data: Nothing?) { - logicalNot.arg.accept(this, data) - } - - override fun visitIsInstancePredicate(isInstancePredicate: KtIsInstancePredicate, data: Nothing?) { - isInstancePredicate.arg.accept(this, data) - buffer.append(" ${if (isInstancePredicate.isNegated) "!" else ""}is ${isInstancePredicate.type}") - } - - override fun visitIsNullPredicate(isNullPredicate: KtIsNullPredicate, data: Nothing?) { - isNullPredicate.arg.accept(this, data) - buffer.append(" ${if (isNullPredicate.isNegated) "!=" else "=="} null") - } - - override fun visitConstantDescriptor(constantReference: KtConstantReference, data: Nothing?) { - buffer.append(constantReference.name) - } - - override fun visitValueParameterReference(valueParameterReference: KtValueParameterReference, data: Nothing?) { - buffer.append("param(").append(valueParameterReference.parameterIndex).append(")") - } - -} \ No newline at end of file diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoExtraction.kt b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoExtraction.kt new file mode 100644 index 00000000000..4559186ee8d --- /dev/null +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoExtraction.kt @@ -0,0 +1,150 @@ +/* + * Copyright 2010-2024 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.decompiler.stub.files + +import com.intellij.psi.stubs.StubElement +import org.jetbrains.kotlin.contracts.description.* +import org.jetbrains.kotlin.psi.KtProjectionKind +import org.jetbrains.kotlin.psi.stubs.impl.* + +fun extractAdditionalStubInfo(stub: StubElement<*>): String { + val builder = StringBuilder() + extractAdditionInfo(stub, builder, 0) + return builder.toString() +} + +private fun extractAdditionInfo(stub: StubElement<*>, builder: StringBuilder, level: Int) { + builder.append(stub.toString()) + when (stub) { + is KotlinUserTypeStubImpl -> { + val upperBound = stub.upperBound + if (upperBound != null) { + builder.append(" ft: ") + appendFlexibleTypeInfo(builder, upperBound) + } + } + is KotlinFunctionStubImpl -> { + val contract = stub.contract + if (contract != null) { + for (element in contract) { + builder.append("\n" + " ".repeat(level)).append("effect:") + element.accept(KotlinContractRenderer(builder), null) + } + } + } + is KotlinPropertyStubImpl -> { + val initializer = stub.constantInitializer + if (initializer != null) { + builder.append("\n").append(" ".repeat(level)).append("initializer: ${initializer.value}") + } + } + is KotlinAnnotationEntryStubImpl -> { + val arguments = stub.valueArguments + if (arguments != null) { + builder + .append("\n") + .append(" ".repeat(level)) + .append("valueArguments: ") + .append(arguments.entries.joinToString(", ", "(", ")") { "${it.key.asString()} = ${it.value}" }) + } + } + is KotlinParameterStubImpl -> { + stub.functionTypeParameterName?.let { builder.append(" paramNameByAnnotation: ").append(it) } + } + } + for (child in stub.childrenStubs) { + builder.append("\n").append(" ".repeat(level)) + extractAdditionInfo(child, builder, level + 1) + } +} + +private fun appendFlexibleTypeInfo(builder: StringBuilder, typeBean: KotlinTypeBean) { + when (typeBean) { + is KotlinClassTypeBean -> { + builder.append(typeBean.classId.asFqNameString()) + val arguments = typeBean.arguments + if (arguments.isNotEmpty()) { + builder.append("<") + arguments.forEachIndexed { index, arg -> + if (index > 0) builder.append(", ") + if (arg.projectionKind != KtProjectionKind.NONE) { + builder.append(arg.projectionKind.name) + } + if (arg.projectionKind != KtProjectionKind.STAR) { + appendFlexibleTypeInfo(builder, arg.type!!) + } + } + builder.append(">") + } + if (typeBean.nullable) { + builder.append("?") + } + } + is KotlinTypeParameterTypeBean -> { + builder.append(typeBean.typeParameterName) + if (typeBean.nullable) { + builder.append("?") + } + if (typeBean.definitelyNotNull) { + builder.append(" & Any") + } + } + + is KotlinFlexibleTypeBean -> { + appendFlexibleTypeInfo(builder, typeBean.lowerBound) + builder.append(" .. ") + appendFlexibleTypeInfo(builder, typeBean.upperBound) + } + } +} + +class KotlinContractRenderer(private val buffer: StringBuilder) : KtContractDescriptionVisitor() { + override fun visitConditionalEffectDeclaration(conditionalEffect: KtConditionalEffectDeclaration, data: Nothing?) { + conditionalEffect.effect.accept(this, data) + buffer.append(" -> ") + conditionalEffect.condition.accept(this, data) + } + + override fun visitReturnsEffectDeclaration(returnsEffect: KtReturnsEffectDeclaration, data: Nothing?) { + buffer.append("Returns(") + returnsEffect.value.accept(this, data) + buffer.append(")") + } + + override fun visitCallsEffectDeclaration(callsEffect: KtCallsEffectDeclaration, data: Nothing?) { + buffer.append("CallsInPlace(") + callsEffect.valueParameterReference.accept(this, data) + buffer.append(", ${callsEffect.kind})") + } + + override fun visitLogicalBinaryOperationContractExpression(binaryLogicExpression: KtBinaryLogicExpression, data: Nothing?) { + binaryLogicExpression.left.accept(this, data) + buffer.append(" ${binaryLogicExpression.kind.token} ") + binaryLogicExpression.right.accept(this, data) + } + + override fun visitLogicalNot(logicalNot: KtLogicalNot, data: Nothing?) { + logicalNot.arg.accept(this, data) + } + + override fun visitIsInstancePredicate(isInstancePredicate: KtIsInstancePredicate, data: Nothing?) { + isInstancePredicate.arg.accept(this, data) + buffer.append(" ${if (isInstancePredicate.isNegated) "!" else ""}is ${isInstancePredicate.type}") + } + + override fun visitIsNullPredicate(isNullPredicate: KtIsNullPredicate, data: Nothing?) { + isNullPredicate.arg.accept(this, data) + buffer.append(" ${if (isNullPredicate.isNegated) "!=" else "=="} null") + } + + override fun visitConstantDescriptor(constantReference: KtConstantReference, data: Nothing?) { + buffer.append(constantReference.name) + } + + override fun visitValueParameterReference(valueParameterReference: KtValueParameterReference, data: Nothing?) { + buffer.append("param(").append(valueParameterReference.parameterIndex).append(")") + } +}