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-jdk8:compileTestKotlin",
|
||||
":plugins:uast-kotlin-base:compileKotlin",
|
||||
":plugins:uast-kotlin-base:compileTestKotlin",
|
||||
":plugins:uast-kotlin:compileKotlin",
|
||||
":plugins:uast-kotlin:compileTestKotlin",
|
||||
":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)
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "asm-all", rootProject = rootProject) }
|
||||
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 {
|
||||
"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.
|
||||
*/
|
||||
package org.jetbrains.uast.test.common.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.uast.UFile
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@@ -36,9 +35,9 @@ abstract class IndentedPrintingVisitor(val shouldIndent: (PsiElement) -> Boolean
|
||||
|
||||
val result: String
|
||||
get() = builder.toString()
|
||||
}
|
||||
|
||||
fun IndentedPrintingVisitor.visitUFileAndGetResult(uFile: UFile): String {
|
||||
(uFile.sourcePsi as PsiFile).accept(this)
|
||||
return result
|
||||
}
|
||||
fun visitUFileAndGetResult(uFile: UFile): String {
|
||||
uFile.sourcePsi.accept(this)
|
||||
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-fir"))
|
||||
|
||||
testImplementation(toolsJar())
|
||||
testImplementation(commonDep("junit:junit"))
|
||||
testCompileOnly(intellijPluginDep("java")) { includeJars("java-api", "java-impl") }
|
||||
testImplementation(projectTests(":compiler:tests-common"))
|
||||
testImplementation(projectTests(":idea:idea-test-framework"))
|
||||
testImplementation(projectTests(":idea"))
|
||||
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
|
||||
testImplementation(projectTests(":plugins:uast-kotlin"))
|
||||
|
||||
testRuntimeOnly(toolsJar())
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.common.kotlin
|
||||
package org.jetbrains.uast.test.common.kotlin
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.common.kotlin
|
||||
package org.jetbrains.uast.test.common.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.uast.UComment
|
||||
import org.jetbrains.uast.UFile
|
||||
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 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.common.kotlin
|
||||
package org.jetbrains.uast.test.common.kotlin
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
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.
|
||||
*/
|
||||
|
||||
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.common.kotlin.FirUastTestSuffix.FIR_SUFFIX
|
||||
import org.jetbrains.uast.test.common.kotlin.FirUastTestSuffix.FE10_SUFFIX
|
||||
import org.jetbrains.uast.test.common.kotlin.FirUastTestSuffix.FIR_SUFFIX
|
||||
|
||||
interface FirUastPluginSelection {
|
||||
// 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.common.kotlin
|
||||
package org.jetbrains.uast.test.common.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.uast.UFile
|
||||
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
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.common.kotlin
|
||||
package org.jetbrains.uast.test.common.kotlin
|
||||
|
||||
object FirUastTestSuffix {
|
||||
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.UastFacade
|
||||
import org.jetbrains.uast.UastLanguagePlugin
|
||||
import org.jetbrains.uast.common.kotlin.FirUastPluginSelection
|
||||
import org.jetbrains.uast.kotlin.BaseKotlinUastResolveProviderService
|
||||
import org.jetbrains.uast.kotlin.FirKotlinUastResolveProviderService
|
||||
import org.jetbrains.uast.kotlin.firKotlinUastPlugin
|
||||
import org.jetbrains.uast.kotlin.internal.FirCliKotlinUastResolveProviderService
|
||||
import org.jetbrains.uast.test.common.kotlin.FirUastPluginSelection
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractFirUastTest : KotlinLightCodeInsightFixtureTestCase(), FirUastPluginSelection {
|
||||
|
||||
+1
-1
@@ -5,6 +5,6 @@
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import org.jetbrains.uast.UFile
|
||||
import org.jetbrains.uast.common.kotlin.FirUastCommentLogTestBase
|
||||
import org.jetbrains.uast.test.common.kotlin.FirUastCommentLogTestBase
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractFE1UastCommentsTest : AbstractKotlinUastTest(), FirUastCommentLogTestBase {
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import org.jetbrains.uast.UFile
|
||||
import org.jetbrains.uast.common.kotlin.FirUastRenderLogTestBase
|
||||
import org.jetbrains.uast.test.common.kotlin.FirUastRenderLogTestBase
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractFE1UastDeclarationTest : AbstractKotlinUastTest(), FirUastRenderLogTestBase {
|
||||
|
||||
+1
-1
@@ -5,6 +5,6 @@
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
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
|
||||
|
||||
abstract class AbstractFirUastCommentsTest : AbstractFirUastTest(), FirUastCommentLogTestBase {
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
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
|
||||
|
||||
abstract class AbstractFirUastDeclarationTest : AbstractFirUastTest(), FirUastRenderLogTestBase {
|
||||
|
||||
@@ -44,6 +44,7 @@ dependencies {
|
||||
testCompile(project(":compiler:util"))
|
||||
testCompile(project(":compiler:cli"))
|
||||
testCompile(projectTests(":idea:idea-test-framework"))
|
||||
testCompile(projectTests(":plugins:uast-kotlin-base"))
|
||||
|
||||
testCompile(project(":idea:idea-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
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.test.common.UElementToParentMap
|
||||
import org.jetbrains.uast.UFile
|
||||
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 java.io.File
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
|
||||
abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), IdentifiersTestBase {
|
||||
|
||||
@@ -22,16 +22,3 @@ abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), Identif
|
||||
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.uast.*
|
||||
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 java.io.File
|
||||
|
||||
|
||||
abstract class AbstractKotlinResolveEverythingTest : AbstractKotlinUastTest() {
|
||||
|
||||
private fun getTestFile(testName: String, ext: String) =
|
||||
File(File(TEST_KOTLIN_MODEL_DIR, testName).canonicalPath + '.' + ext)
|
||||
|
||||
|
||||
private fun UFile.resolvableWithTargets() = object : IndentedPrintingVisitor(KtBlockExpression::class) {
|
||||
override fun render(element: PsiElement) =
|
||||
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) {
|
||||
assertEqualsToFile("resolved", getTestFile(testName, "resolved.txt"), file.resolvableWithTargets())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-55
@@ -5,67 +5,13 @@
|
||||
|
||||
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.UFile
|
||||
import org.jetbrains.uast.test.env.kotlin.assertEqualsToFile
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor
|
||||
import org.junit.ComparisonFailure
|
||||
import java.io.File
|
||||
import kotlin.test.fail
|
||||
|
||||
interface IdentifiersTestBase {
|
||||
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) {
|
||||
val valuesFile = getIdentifiersFile(testName)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user