Analysis API: add test for getReturnExpressionTargetSymbol

Also fix FIR and FE1.0 implementations.
This commit is contained in:
Tianyu Geng
2021-11-16 19:59:43 -08:00
committed by Ilya Kirillov
parent 7aef45d5cf
commit d0d1c8c4b9
16 changed files with 269 additions and 27 deletions
@@ -7,9 +7,14 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.util.Computable
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.analyse
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils.offsetToLineAndColumn
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNamedDeclaration
inline fun <T> runReadAction(crossinline runnable: () -> T): T {
return ApplicationManager.getApplication().runReadAction(Computable { runnable() })
@@ -21,4 +26,18 @@ fun <R> executeOnPooledThreadInReadAction(action: () -> R): R =
inline fun <R> analyseOnPooledThreadInReadAction(context: KtElement, crossinline action: KtAnalysisSession.() -> R): R =
executeOnPooledThreadInReadAction {
analyse(context) { action() }
}
}
fun PsiElement?.position(): String {
if (this == null) return "(unknown)"
return offsetToLineAndColumn(containingFile.viewProvider.document, textRange.startOffset).toString()
}
fun KtSymbol.getNameWithPositionString(): String {
return when (val psi = this.psi) {
is KtDeclarationWithBody -> psi.name
is KtNamedDeclaration -> psi.name
null -> "null"
else -> psi::class.simpleName
} + "@" + psi.position()
}
@@ -0,0 +1,58 @@
/*
* 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.impl.base.test.components.expressionInfoProvider
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.base.test.getNameWithPositionString
import org.jetbrains.kotlin.analysis.api.impl.base.test.test.framework.AbstractHLApiSingleFileTest
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtReturnExpression
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractReturnTargetSymbolTest(
configurator: FrontendApiTestConfiguratorService
) : AbstractHLApiSingleFileTest(configurator) {
val commentRegex = Regex("""/\* (.+@\(.+\)|null) \*/""")
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
super.doTestByFileStructure(ktFile, module, testServices)
val original = ktFile.text
val actual = buildString {
ktFile.accept(object : KtTreeVisitorVoid() {
override fun visitElement(element: PsiElement) {
if (element is LeafPsiElement) {
append(element.text)
}
super.visitElement(element)
}
override fun visitReturnExpression(expression: KtReturnExpression) {
expression.returnKeyword.accept(this)
expression.labeledExpression?.accept(this)
analyseForTest(expression) {
val target = expression.getReturnTargetSymbol()
append("/* " + target?.getNameWithPositionString() + " */")
}
expression.returnedExpression?.accept(this)
}
override fun visitComment(comment: PsiComment) {
// Skip such comments so that test become idempotent
if (comment.text.matches(commentRegex)) return
super.visitComment(comment)
}
})
}
if (actual != original) {
testServices.assertions.assertEqualsToFile(testDataPath, actual)
}
}
}