UAST: utilize identifier test base
This commit is contained in:
committed by
Ilya Kirillov
parent
da15f0ffe8
commit
c37123603c
@@ -364,6 +364,7 @@ extra["tasksWithWarnings"] = listOf(
|
|||||||
":kotlin-stdlib-jdk7:compileTestKotlin",
|
":kotlin-stdlib-jdk7:compileTestKotlin",
|
||||||
":kotlin-stdlib-jdk8:compileTestKotlin",
|
":kotlin-stdlib-jdk8:compileTestKotlin",
|
||||||
":plugins:uast-kotlin-base:compileKotlin",
|
":plugins:uast-kotlin-base:compileKotlin",
|
||||||
|
":plugins:uast-kotlin-base:compileTestKotlin",
|
||||||
":plugins:uast-kotlin:compileKotlin",
|
":plugins:uast-kotlin:compileKotlin",
|
||||||
":plugins:uast-kotlin:compileTestKotlin",
|
":plugins:uast-kotlin:compileTestKotlin",
|
||||||
":plugins:uast-kotlin-fir:compileKotlin",
|
":plugins:uast-kotlin-fir:compileKotlin",
|
||||||
|
|||||||
@@ -11,8 +11,16 @@ dependencies {
|
|||||||
// BEWARE: UAST should not depend on IJ platform so that it can work in Android Lint CLI mode (where IDE is not available)
|
// BEWARE: UAST should not depend on IJ platform so that it can work in Android Lint CLI mode (where IDE is not available)
|
||||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "asm-all", rootProject = rootProject) }
|
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "asm-all", rootProject = rootProject) }
|
||||||
compileOnly(intellijPluginDep("java")) { includeJars("java-api", "java-impl") }
|
compileOnly(intellijPluginDep("java")) { includeJars("java-api", "java-impl") }
|
||||||
|
|
||||||
|
testImplementation(commonDep("junit:junit"))
|
||||||
|
testCompileOnly(intellijPluginDep("java")) { includeJars("java-api", "java-impl") }
|
||||||
|
testImplementation(projectTests(":compiler:tests-common"))
|
||||||
|
testCompileOnly(intellijDep("ideaIC"))
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
"main" { projectDefault() }
|
"main" { projectDefault() }
|
||||||
|
"test" { projectDefault() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testsJar ()
|
||||||
|
|||||||
+6
-7
@@ -1,12 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* 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.
|
* 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.uast.test.common.kotlin
|
package org.jetbrains.uast.test.common.kotlin
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiElementVisitor
|
import com.intellij.psi.PsiElementVisitor
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
import org.jetbrains.uast.UFile
|
import org.jetbrains.uast.UFile
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@@ -36,9 +35,9 @@ abstract class IndentedPrintingVisitor(val shouldIndent: (PsiElement) -> Boolean
|
|||||||
|
|
||||||
val result: String
|
val result: String
|
||||||
get() = builder.toString()
|
get() = builder.toString()
|
||||||
}
|
|
||||||
|
|
||||||
fun IndentedPrintingVisitor.visitUFileAndGetResult(uFile: UFile): String {
|
fun visitUFileAndGetResult(uFile: UFile): String {
|
||||||
(uFile.sourcePsi as PsiFile).accept(this)
|
uFile.sourcePsi.accept(this)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
}
|
||||||
+78
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* 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.uast.test.common.kotlin
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||||
|
import org.jetbrains.uast.*
|
||||||
|
import org.jetbrains.uast.visitor.AbstractUastVisitor
|
||||||
|
import org.jetbrains.uast.test.common.UElementToParentMap
|
||||||
|
import org.jetbrains.uast.test.common.visitUFileAndGetResult
|
||||||
|
import org.junit.ComparisonFailure
|
||||||
|
import kotlin.test.assertNotNull
|
||||||
|
import kotlin.test.fail
|
||||||
|
|
||||||
|
fun UFile.asIdentifiersWithParents() = object : IndentedPrintingVisitor(KtBlockExpression::class) {
|
||||||
|
override fun render(element: PsiElement): CharSequence? = element.toUElementOfType<UIdentifier>()?.let { uIdentifier ->
|
||||||
|
StringBuilder().apply {
|
||||||
|
append(uIdentifier.sourcePsiElement!!.text)
|
||||||
|
append(" -> ")
|
||||||
|
append(uIdentifier.uastParent?.asLogString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.visitUFileAndGetResult(this)
|
||||||
|
|
||||||
|
fun UFile.testIdentifiersParents() {
|
||||||
|
accept(object : AbstractUastVisitor() {
|
||||||
|
override fun visitElement(node: UElement): Boolean {
|
||||||
|
val uIdentifier = when (node) {
|
||||||
|
is UAnchorOwner -> node.uastAnchor ?: return false
|
||||||
|
is UBinaryExpression -> node.operatorIdentifier ?: return false
|
||||||
|
else -> return false
|
||||||
|
}
|
||||||
|
|
||||||
|
assertParents(node, uIdentifier)
|
||||||
|
val identifierSourcePsi = uIdentifier.sourcePsi ?: return false
|
||||||
|
val operatorIdentifierFromSource = identifierSourcePsi.toUElementOfType<UIdentifier>()
|
||||||
|
?: fail("$identifierSourcePsi of ${identifierSourcePsi.javaClass} should be convertible to UIdentifier")
|
||||||
|
assertParents(node, operatorIdentifierFromSource)
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Sequence<UElement>.log() = this.joinToString { it.asLogString() }
|
||||||
|
|
||||||
|
private fun assertParents(node: UElement, uastAnchor: UIdentifier?) {
|
||||||
|
// skipping such elements because they are ambiguous (properties and getters for instance)
|
||||||
|
if (node.sourcePsi.toUElement() != node) return
|
||||||
|
if (uastAnchor == null)
|
||||||
|
throw AssertionError("no uast anchor for node = $node")
|
||||||
|
val nodeParents = node.withContainingElements.log()
|
||||||
|
val anchorParentParents = uastAnchor.uastParent?.withContainingElements?.log() ?: ""
|
||||||
|
// dropping node itself because we allow children to share identifiers with parents (primary constructor for instance)
|
||||||
|
val parentsSuffix = node.withContainingElements.drop(1).log()
|
||||||
|
if (!anchorParentParents.endsWith(parentsSuffix))
|
||||||
|
throw ComparisonFailure(
|
||||||
|
"wrong parents for '${uastAnchor.sourcePsi?.text}' owner: $node[${node.sourcePsi}[${node.sourcePsi?.text}]]",
|
||||||
|
nodeParents,
|
||||||
|
anchorParentParents
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refNameRetriever(psiElement: PsiElement): UElement? =
|
||||||
|
when (val uElement = psiElement.toUElementOfExpectedTypes(UCallExpression::class.java, UReferenceExpression::class.java)) {
|
||||||
|
is UReferenceExpression -> uElement.referenceNameElement
|
||||||
|
is UCallExpression -> uElement.classReference?.referenceNameElement
|
||||||
|
else -> null
|
||||||
|
}?.also {
|
||||||
|
assertNotNull(it.sourcePsi, "referenceNameElement should have physical source, origin = $psiElement")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun UFile.asRefNames() = object : UElementToParentMap(::refNameRetriever) {
|
||||||
|
override fun renderSource(element: PsiElement): String = element.javaClass.simpleName
|
||||||
|
}.visitUFileAndGetResult(this)
|
||||||
@@ -25,15 +25,17 @@ dependencies {
|
|||||||
implementation(project(":idea:idea-frontend-api"))
|
implementation(project(":idea:idea-frontend-api"))
|
||||||
implementation(project(":idea:idea-frontend-fir"))
|
implementation(project(":idea:idea-frontend-fir"))
|
||||||
|
|
||||||
testImplementation(toolsJar())
|
|
||||||
testImplementation(commonDep("junit:junit"))
|
testImplementation(commonDep("junit:junit"))
|
||||||
testCompileOnly(intellijPluginDep("java")) { includeJars("java-api", "java-impl") }
|
testCompileOnly(intellijPluginDep("java")) { includeJars("java-api", "java-impl") }
|
||||||
testImplementation(projectTests(":compiler:tests-common"))
|
testImplementation(projectTests(":compiler:tests-common"))
|
||||||
testImplementation(projectTests(":idea:idea-test-framework"))
|
testImplementation(projectTests(":idea:idea-test-framework"))
|
||||||
testImplementation(projectTests(":idea"))
|
testImplementation(projectTests(":idea"))
|
||||||
testImplementation(projectTests(":idea:idea-fir"))
|
testImplementation(projectTests(":idea:idea-fir"))
|
||||||
|
testImplementation(projectTests(":plugins:uast-kotlin-base"))
|
||||||
// To compare various aspects (e.g., render, log, type, value, etc.) against legacy UAST Kotlin
|
// To compare various aspects (e.g., render, log, type, value, etc.) against legacy UAST Kotlin
|
||||||
testImplementation(projectTests(":plugins:uast-kotlin"))
|
testImplementation(projectTests(":plugins:uast-kotlin"))
|
||||||
|
|
||||||
|
testRuntimeOnly(toolsJar())
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.uast.common.kotlin
|
package org.jetbrains.uast.test.common.kotlin
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
+2
-2
@@ -3,13 +3,13 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.uast.common.kotlin
|
package org.jetbrains.uast.test.common.kotlin
|
||||||
|
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import org.jetbrains.uast.UComment
|
import org.jetbrains.uast.UComment
|
||||||
import org.jetbrains.uast.UFile
|
import org.jetbrains.uast.UFile
|
||||||
import org.jetbrains.uast.asRecursiveLogString
|
import org.jetbrains.uast.asRecursiveLogString
|
||||||
import org.jetbrains.uast.common.kotlin.FirUastTestSuffix.TXT
|
import org.jetbrains.uast.test.common.kotlin.FirUastTestSuffix.TXT
|
||||||
import org.jetbrains.uast.kotlin.internal.KotlinUElementWithComments
|
import org.jetbrains.uast.kotlin.internal.KotlinUElementWithComments
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.uast.common.kotlin
|
package org.jetbrains.uast.test.common.kotlin
|
||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import org.jetbrains.kotlin.test.KtAssert
|
import org.jetbrains.kotlin.test.KtAssert
|
||||||
+3
-3
@@ -3,10 +3,10 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.uast.common.kotlin
|
package org.jetbrains.uast.test.common.kotlin
|
||||||
|
|
||||||
import org.jetbrains.uast.common.kotlin.FirUastTestSuffix.FE10_SUFFIX
|
import org.jetbrains.uast.test.common.kotlin.FirUastTestSuffix.FE10_SUFFIX
|
||||||
import org.jetbrains.uast.common.kotlin.FirUastTestSuffix.FIR_SUFFIX
|
import org.jetbrains.uast.test.common.kotlin.FirUastTestSuffix.FIR_SUFFIX
|
||||||
|
|
||||||
interface FirUastPluginSelection {
|
interface FirUastPluginSelection {
|
||||||
// Whether this is FIR UAST plugin or FE 1.0 UAST plugin
|
// Whether this is FIR UAST plugin or FE 1.0 UAST plugin
|
||||||
+2
-2
@@ -3,12 +3,12 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.uast.common.kotlin
|
package org.jetbrains.uast.test.common.kotlin
|
||||||
|
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import org.jetbrains.uast.UFile
|
import org.jetbrains.uast.UFile
|
||||||
import org.jetbrains.uast.asRecursiveLogString
|
import org.jetbrains.uast.asRecursiveLogString
|
||||||
import org.jetbrains.uast.common.kotlin.FirUastTestSuffix.TXT
|
import org.jetbrains.uast.test.common.kotlin.FirUastTestSuffix.TXT
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
interface FirUastRenderLogTestBase : FirUastPluginSelection, FirUastFileComparisonTestBase {
|
interface FirUastRenderLogTestBase : FirUastPluginSelection, FirUastFileComparisonTestBase {
|
||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.uast.common.kotlin
|
package org.jetbrains.uast.test.common.kotlin
|
||||||
|
|
||||||
object FirUastTestSuffix {
|
object FirUastTestSuffix {
|
||||||
internal const val FE10_SUFFIX = ".fe10"
|
internal const val FE10_SUFFIX = ".fe10"
|
||||||
+1
-1
@@ -18,11 +18,11 @@ import org.jetbrains.kotlin.test.KotlinTestUtils
|
|||||||
import org.jetbrains.uast.UFile
|
import org.jetbrains.uast.UFile
|
||||||
import org.jetbrains.uast.UastFacade
|
import org.jetbrains.uast.UastFacade
|
||||||
import org.jetbrains.uast.UastLanguagePlugin
|
import org.jetbrains.uast.UastLanguagePlugin
|
||||||
import org.jetbrains.uast.common.kotlin.FirUastPluginSelection
|
|
||||||
import org.jetbrains.uast.kotlin.BaseKotlinUastResolveProviderService
|
import org.jetbrains.uast.kotlin.BaseKotlinUastResolveProviderService
|
||||||
import org.jetbrains.uast.kotlin.FirKotlinUastResolveProviderService
|
import org.jetbrains.uast.kotlin.FirKotlinUastResolveProviderService
|
||||||
import org.jetbrains.uast.kotlin.firKotlinUastPlugin
|
import org.jetbrains.uast.kotlin.firKotlinUastPlugin
|
||||||
import org.jetbrains.uast.kotlin.internal.FirCliKotlinUastResolveProviderService
|
import org.jetbrains.uast.kotlin.internal.FirCliKotlinUastResolveProviderService
|
||||||
|
import org.jetbrains.uast.test.common.kotlin.FirUastPluginSelection
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractFirUastTest : KotlinLightCodeInsightFixtureTestCase(), FirUastPluginSelection {
|
abstract class AbstractFirUastTest : KotlinLightCodeInsightFixtureTestCase(), FirUastPluginSelection {
|
||||||
|
|||||||
+1
-1
@@ -5,6 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.uast.test.kotlin
|
package org.jetbrains.uast.test.kotlin
|
||||||
|
|
||||||
import org.jetbrains.uast.common.kotlin.FirLegacyUastRenderLogTestBase
|
import org.jetbrains.uast.test.common.kotlin.FirLegacyUastRenderLogTestBase
|
||||||
|
|
||||||
abstract class AbstractFE1LegacyUastDeclarationTest : AbstractFE1UastDeclarationTest(), FirLegacyUastRenderLogTestBase
|
abstract class AbstractFE1LegacyUastDeclarationTest : AbstractFE1UastDeclarationTest(), FirLegacyUastRenderLogTestBase
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.uast.test.kotlin
|
package org.jetbrains.uast.test.kotlin
|
||||||
|
|
||||||
import org.jetbrains.uast.UFile
|
import org.jetbrains.uast.UFile
|
||||||
import org.jetbrains.uast.common.kotlin.FirUastCommentLogTestBase
|
import org.jetbrains.uast.test.common.kotlin.FirUastCommentLogTestBase
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractFE1UastCommentsTest : AbstractKotlinUastTest(), FirUastCommentLogTestBase {
|
abstract class AbstractFE1UastCommentsTest : AbstractKotlinUastTest(), FirUastCommentLogTestBase {
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.uast.test.kotlin
|
package org.jetbrains.uast.test.kotlin
|
||||||
|
|
||||||
import org.jetbrains.uast.UFile
|
import org.jetbrains.uast.UFile
|
||||||
import org.jetbrains.uast.common.kotlin.FirUastRenderLogTestBase
|
import org.jetbrains.uast.test.common.kotlin.FirUastRenderLogTestBase
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractFE1UastDeclarationTest : AbstractKotlinUastTest(), FirUastRenderLogTestBase {
|
abstract class AbstractFE1UastDeclarationTest : AbstractKotlinUastTest(), FirUastRenderLogTestBase {
|
||||||
|
|||||||
+1
-1
@@ -5,6 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.uast.test.kotlin
|
package org.jetbrains.uast.test.kotlin
|
||||||
|
|
||||||
import org.jetbrains.uast.common.kotlin.FirLegacyUastRenderLogTestBase
|
import org.jetbrains.uast.test.common.kotlin.FirLegacyUastRenderLogTestBase
|
||||||
|
|
||||||
abstract class AbstractFirLegacyUastDeclarationTest : AbstractFirUastDeclarationTest(), FirLegacyUastRenderLogTestBase
|
abstract class AbstractFirLegacyUastDeclarationTest : AbstractFirUastDeclarationTest(), FirLegacyUastRenderLogTestBase
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.uast.test.kotlin
|
package org.jetbrains.uast.test.kotlin
|
||||||
|
|
||||||
import org.jetbrains.uast.UFile
|
import org.jetbrains.uast.UFile
|
||||||
import org.jetbrains.uast.common.kotlin.FirUastCommentLogTestBase
|
import org.jetbrains.uast.test.common.kotlin.FirUastCommentLogTestBase
|
||||||
import org.jetbrains.uast.test.env.kotlin.AbstractFirUastTest
|
import org.jetbrains.uast.test.env.kotlin.AbstractFirUastTest
|
||||||
|
|
||||||
abstract class AbstractFirUastCommentsTest : AbstractFirUastTest(), FirUastCommentLogTestBase {
|
abstract class AbstractFirUastCommentsTest : AbstractFirUastTest(), FirUastCommentLogTestBase {
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.uast.test.kotlin
|
package org.jetbrains.uast.test.kotlin
|
||||||
|
|
||||||
import org.jetbrains.uast.UFile
|
import org.jetbrains.uast.UFile
|
||||||
import org.jetbrains.uast.common.kotlin.FirUastRenderLogTestBase
|
import org.jetbrains.uast.test.common.kotlin.FirUastRenderLogTestBase
|
||||||
import org.jetbrains.uast.test.env.kotlin.AbstractFirUastTest
|
import org.jetbrains.uast.test.env.kotlin.AbstractFirUastTest
|
||||||
|
|
||||||
abstract class AbstractFirUastDeclarationTest : AbstractFirUastTest(), FirUastRenderLogTestBase {
|
abstract class AbstractFirUastDeclarationTest : AbstractFirUastTest(), FirUastRenderLogTestBase {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ dependencies {
|
|||||||
testCompile(project(":compiler:util"))
|
testCompile(project(":compiler:util"))
|
||||||
testCompile(project(":compiler:cli"))
|
testCompile(project(":compiler:cli"))
|
||||||
testCompile(projectTests(":idea:idea-test-framework"))
|
testCompile(projectTests(":idea:idea-test-framework"))
|
||||||
|
testCompile(projectTests(":plugins:uast-kotlin-base"))
|
||||||
|
|
||||||
testCompile(project(":idea:idea-native")) { isTransitive = false }
|
testCompile(project(":idea:idea-native")) { isTransitive = false }
|
||||||
testCompile(project(":idea:idea-gradle-native")) { isTransitive = false }
|
testCompile(project(":idea:idea-gradle-native")) { isTransitive = false }
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* 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.uast.test.kotlin
|
package org.jetbrains.uast.test.kotlin
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import org.jetbrains.uast.UFile
|
||||||
import org.jetbrains.uast.*
|
|
||||||
import org.jetbrains.uast.test.common.UElementToParentMap
|
|
||||||
import org.jetbrains.uast.test.common.kotlin.IdentifiersTestBase
|
import org.jetbrains.uast.test.common.kotlin.IdentifiersTestBase
|
||||||
import org.jetbrains.uast.test.common.visitUFileAndGetResult
|
import org.jetbrains.uast.test.common.kotlin.asRefNames
|
||||||
import org.jetbrains.uast.test.env.kotlin.assertEqualsToFile
|
import org.jetbrains.uast.test.env.kotlin.assertEqualsToFile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.test.assertNotNull
|
|
||||||
|
|
||||||
|
|
||||||
abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), IdentifiersTestBase {
|
abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), IdentifiersTestBase {
|
||||||
|
|
||||||
@@ -22,16 +22,3 @@ abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), Identif
|
|||||||
assertEqualsToFile("refNames", getTestFile(testName, "refNames.txt"), file.asRefNames())
|
assertEqualsToFile("refNames", getTestFile(testName, "refNames.txt"), file.asRefNames())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun refNameRetriever(psiElement: PsiElement): UElement? =
|
|
||||||
when (val uElement = psiElement.toUElementOfExpectedTypes(UCallExpression::class.java, UReferenceExpression::class.java)) {
|
|
||||||
is UReferenceExpression -> uElement.referenceNameElement
|
|
||||||
is UCallExpression -> uElement.classReference?.referenceNameElement
|
|
||||||
else -> null
|
|
||||||
}?.also {
|
|
||||||
assertNotNull(it.sourcePsi, "referenceNameElement should have physical source, origin = $psiElement")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun UFile.asRefNames() = object : UElementToParentMap(::refNameRetriever) {
|
|
||||||
override fun renderSource(element: PsiElement): String = element.javaClass.simpleName
|
|
||||||
}.visitUFileAndGetResult(this)
|
|
||||||
|
|||||||
@@ -11,17 +11,14 @@ import org.jetbrains.kotlin.utils.addToStdlib.cast
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
import org.jetbrains.uast.test.common.kotlin.IndentedPrintingVisitor
|
import org.jetbrains.uast.test.common.kotlin.IndentedPrintingVisitor
|
||||||
import org.jetbrains.uast.test.common.kotlin.visitUFileAndGetResult
|
|
||||||
import org.jetbrains.uast.test.env.kotlin.assertEqualsToFile
|
import org.jetbrains.uast.test.env.kotlin.assertEqualsToFile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
abstract class AbstractKotlinResolveEverythingTest : AbstractKotlinUastTest() {
|
abstract class AbstractKotlinResolveEverythingTest : AbstractKotlinUastTest() {
|
||||||
|
|
||||||
private fun getTestFile(testName: String, ext: String) =
|
private fun getTestFile(testName: String, ext: String) =
|
||||||
File(File(TEST_KOTLIN_MODEL_DIR, testName).canonicalPath + '.' + ext)
|
File(File(TEST_KOTLIN_MODEL_DIR, testName).canonicalPath + '.' + ext)
|
||||||
|
|
||||||
|
|
||||||
private fun UFile.resolvableWithTargets() = object : IndentedPrintingVisitor(KtBlockExpression::class) {
|
private fun UFile.resolvableWithTargets() = object : IndentedPrintingVisitor(KtBlockExpression::class) {
|
||||||
override fun render(element: PsiElement) =
|
override fun render(element: PsiElement) =
|
||||||
UastFacade.convertToAlternatives<UExpression>(element, arrayOf(UReferenceExpression::class.java, UCallExpression::class.java))
|
UastFacade.convertToAlternatives<UExpression>(element, arrayOf(UReferenceExpression::class.java, UCallExpression::class.java))
|
||||||
@@ -57,4 +54,4 @@ abstract class AbstractKotlinResolveEverythingTest : AbstractKotlinUastTest() {
|
|||||||
override fun check(testName: String, file: UFile) {
|
override fun check(testName: String, file: UFile) {
|
||||||
assertEqualsToFile("resolved", getTestFile(testName, "resolved.txt"), file.resolvableWithTargets())
|
assertEqualsToFile("resolved", getTestFile(testName, "resolved.txt"), file.resolvableWithTargets())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-55
@@ -5,67 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.uast.test.common.kotlin
|
package org.jetbrains.uast.test.common.kotlin
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import org.jetbrains.uast.UFile
|
||||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
|
||||||
import org.jetbrains.uast.*
|
|
||||||
import org.jetbrains.uast.test.env.kotlin.assertEqualsToFile
|
import org.jetbrains.uast.test.env.kotlin.assertEqualsToFile
|
||||||
import org.jetbrains.uast.visitor.AbstractUastVisitor
|
|
||||||
import org.junit.ComparisonFailure
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.test.fail
|
|
||||||
|
|
||||||
interface IdentifiersTestBase {
|
interface IdentifiersTestBase {
|
||||||
fun getIdentifiersFile(testName: String): File
|
fun getIdentifiersFile(testName: String): File
|
||||||
|
|
||||||
private fun UFile.asIdentifiersWithParents() = object : IndentedPrintingVisitor(KtBlockExpression::class) {
|
|
||||||
override fun render(element: PsiElement): CharSequence? = element.toUElementOfType<UIdentifier>()?.let { uIdentifier ->
|
|
||||||
StringBuilder().apply {
|
|
||||||
append(uIdentifier.sourcePsiElement!!.text)
|
|
||||||
append(" -> ")
|
|
||||||
append(uIdentifier.uastParent?.asLogString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.visitUFileAndGetResult(this)
|
|
||||||
|
|
||||||
private fun UFile.testIdentifiersParents() {
|
|
||||||
accept(object : AbstractUastVisitor() {
|
|
||||||
override fun visitElement(node: UElement): Boolean {
|
|
||||||
val uIdentifier = when (node) {
|
|
||||||
is UAnchorOwner -> node.uastAnchor ?: return false
|
|
||||||
is UBinaryExpression -> node.operatorIdentifier ?: return false
|
|
||||||
else -> return false
|
|
||||||
}
|
|
||||||
|
|
||||||
assertParents(node, uIdentifier)
|
|
||||||
val identifierSourcePsi = uIdentifier.sourcePsi ?: return false
|
|
||||||
val operatorIdentifierFromSource = identifierSourcePsi.toUElementOfType<UIdentifier>()
|
|
||||||
?: fail("$identifierSourcePsi of ${identifierSourcePsi.javaClass} should be convertable to UIdentifier")
|
|
||||||
assertParents(node, operatorIdentifierFromSource)
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun assertParents(node: UElement, uastAnchor: UIdentifier?) {
|
|
||||||
//skipping such elements because they are ambiguous (properties and getters for instance)
|
|
||||||
if (node.sourcePsi.toUElement() != node) return
|
|
||||||
if (uastAnchor == null)
|
|
||||||
throw AssertionError("no uast anchor for node = $node")
|
|
||||||
val nodeParents = node.withContainingElements.log()
|
|
||||||
val anchorParentParents = uastAnchor.uastParent?.withContainingElements?.log() ?: ""
|
|
||||||
// dropping node itself because we allow children to share identifiers with parents (primary constructor for instance)
|
|
||||||
val parentsSuffix = node.withContainingElements.drop(1).log()
|
|
||||||
if (!anchorParentParents.endsWith(parentsSuffix))
|
|
||||||
throw ComparisonFailure(
|
|
||||||
"wrong parents for '${uastAnchor.sourcePsi?.text}' owner: $node[${node.sourcePsi}[${node.sourcePsi?.text}]]",
|
|
||||||
nodeParents,
|
|
||||||
anchorParentParents
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Sequence<UElement>.log() = this.joinToString { it.asLogString() }
|
|
||||||
|
|
||||||
fun check(testName: String, file: UFile) {
|
fun check(testName: String, file: UFile) {
|
||||||
val valuesFile = getIdentifiersFile(testName)
|
val valuesFile = getIdentifiersFile(testName)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user