From 795f9d83e11eeb20d86b80b150ad287c2376cc2b Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Fri, 25 Jan 2019 11:13:43 +0300 Subject: [PATCH] 191: Uast: implementation of `UReferenceExpression.referenceNameElement` (KT-29025) --- ...KotlinUQualifiedReferenceExpression.kt.191 | 46 ++++ .../KotlinUSimpleReferenceExpression.kt.191 | 226 ++++++++++++++++++ .../testData/Anonymous.refNames.txt.191 | 24 ++ .../testData/ClassAnnotation.refNames.txt.191 | 6 + .../testData/Constructors.refNames.txt.191 | 44 ++++ .../LocalDeclarations.refNames.txt.191 | 7 + .../testData/SimpleAnnotated.refNames.txt.191 | 5 + .../AbstractKotlinIdentifiersTest.kt.191 | 28 +++ 8 files changed, 386 insertions(+) create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUQualifiedReferenceExpression.kt.191 create mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt.191 create mode 100644 plugins/uast-kotlin/testData/Anonymous.refNames.txt.191 create mode 100644 plugins/uast-kotlin/testData/ClassAnnotation.refNames.txt.191 create mode 100644 plugins/uast-kotlin/testData/Constructors.refNames.txt.191 create mode 100644 plugins/uast-kotlin/testData/LocalDeclarations.refNames.txt.191 create mode 100644 plugins/uast-kotlin/testData/SimpleAnnotated.refNames.txt.191 create mode 100644 plugins/uast-kotlin/tests/AbstractKotlinIdentifiersTest.kt.191 diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUQualifiedReferenceExpression.kt.191 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUQualifiedReferenceExpression.kt.191 new file mode 100644 index 00000000000..7deb38a1e68 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUQualifiedReferenceExpression.kt.191 @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.uast.kotlin + +import com.intellij.psi.PsiNamedElement +import org.jetbrains.kotlin.psi.KtDotQualifiedExpression +import org.jetbrains.uast.UCallExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UQualifiedReferenceExpression +import org.jetbrains.uast.UastQualifiedExpressionAccessType +import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve + +class KotlinUQualifiedReferenceExpression( + override val psi: KtDotQualifiedExpression, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), UQualifiedReferenceExpression, DelegatedMultiResolve, + KotlinUElementWithType, KotlinEvaluatableUElement { + override val receiver by lz { KotlinConverter.convertOrEmpty(psi.receiverExpression, this) } + override val selector by lz { KotlinConverter.convertOrEmpty(psi.selectorExpression, this) } + override val accessType = UastQualifiedExpressionAccessType.SIMPLE + + override fun resolve() = psi.selectorExpression?.resolveCallToDeclaration(this) + + override val resolvedName: String? + get() = (resolve() as? PsiNamedElement)?.name + + override val referenceNameElement: UElement? + get() = when (val selector = selector) { + is UCallExpression -> selector.methodIdentifier + else -> super.referenceNameElement + } +} diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt.191 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt.191 new file mode 100644 index 00000000000..b84f4b69aff --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt.191 @@ -0,0 +1,226 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.uast.kotlin + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiNamedElement +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.ConstructorDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor +import org.jetbrains.kotlin.utils.addToStdlib.constant +import org.jetbrains.uast.* +import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier +import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve +import org.jetbrains.uast.visitor.UastVisitor + +open class KotlinUSimpleReferenceExpression( + override val psi: KtSimpleNameExpression, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression, KotlinUElementWithType, KotlinEvaluatableUElement { + + private val resolvedDeclaration by lz { psi.resolveCallToDeclaration(this) } + + override val identifier get() = psi.getReferencedName() + + override fun resolve() = resolvedDeclaration + + override val resolvedName: String? + get() = (resolvedDeclaration as? PsiNamedElement)?.name + + override fun accept(visitor: UastVisitor) { + visitor.visitSimpleNameReferenceExpression(this) + + if (psi.parent.destructuringDeclarationInitializer != true) { + visitAccessorCalls(visitor) + } + + visitor.afterVisitSimpleNameReferenceExpression(this) + } + + override val referenceNameElement: UElement? by lz { psi.getIdentifier()?.toUElement() } + + private fun visitAccessorCalls(visitor: UastVisitor) { + // Visit Kotlin get-set synthetic Java property calls as function calls + val bindingContext = psi.analyze() + val access = psi.readWriteAccess() + val resolvedCall = psi.getResolvedCall(bindingContext) + val resultingDescriptor = resolvedCall?.resultingDescriptor as? SyntheticJavaPropertyDescriptor + if (resultingDescriptor != null) { + val setterValue = if (access.isWrite) { + findAssignment(psi, psi.parent)?.right ?: run { + visitor.afterVisitSimpleNameReferenceExpression(this) + return + } + } else { + null + } + + if (resolvedCall != null) { + if (access.isRead) { + val getDescriptor = resultingDescriptor.getMethod + KotlinAccessorCallExpression(psi, this, resolvedCall, getDescriptor, null).accept(visitor) + } + + if (access.isWrite && setterValue != null) { + val setDescriptor = resultingDescriptor.setMethod + if (setDescriptor != null) { + KotlinAccessorCallExpression(psi, this, resolvedCall, setDescriptor, setterValue).accept(visitor) + } + } + } + } + } + + private tailrec fun findAssignment(prev: PsiElement?, element: PsiElement?): KtBinaryExpression? = when (element) { + is KtBinaryExpression -> if (element.left == prev && element.operationToken == KtTokens.EQ) element else null + is KtQualifiedExpression -> findAssignment(element, element.parent) + is KtSimpleNameExpression -> findAssignment(element, element.parent) + else -> null + } + + class KotlinAccessorCallExpression( + override val psi: KtSimpleNameExpression, + override val uastParent: KotlinUSimpleReferenceExpression, + private val resolvedCall: ResolvedCall<*>, + private val accessorDescriptor: DeclarationDescriptor, + val setterValue: KtExpression? + ) : UCallExpressionEx, DelegatedMultiResolve, JvmDeclarationUElementPlaceholder { + override val methodName: String? + get() = accessorDescriptor.name.asString() + + override val receiver: UExpression? + get() { + val containingElement = uastParent.uastParent + return if (containingElement is UQualifiedReferenceExpression && containingElement.selector == this) + containingElement.receiver + else + null + } + + override val javaPsi: PsiElement? = null + override val sourcePsi: PsiElement? = psi + + override val annotations: List + get() = emptyList() + + override val receiverType by lz { + val type = (resolvedCall.dispatchReceiver ?: resolvedCall.extensionReceiver)?.type ?: return@lz null + type.toPsiType(this, psi, boxed = true) + } + + override val methodIdentifier: UIdentifier? by lazy { KotlinUIdentifier(psi.getReferencedNameElement(), this) } + + override val classReference: UReferenceExpression? + get() = null + + override val valueArgumentCount: Int + get() = if (setterValue != null) 1 else 0 + + override val valueArguments by lz { + if (setterValue != null) + listOf(KotlinConverter.convertOrEmpty(setterValue, this)) + else + emptyList() + } + + override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i) + + override val typeArgumentCount: Int + get() = resolvedCall.typeArguments.size + + override val typeArguments by lz { + resolvedCall.typeArguments.values.map { it.toPsiType(this, psi, true) } + } + + override val returnType by lz { + (accessorDescriptor as? CallableDescriptor)?.returnType?.toPsiType(this, psi, boxed = false) + } + + override val kind: UastCallKind + get() = UastCallKind.METHOD_CALL + + override fun resolve(): PsiMethod? { + val source = accessorDescriptor.toSource() + return resolveSource(psi, accessorDescriptor, source) + } + } + + enum class ReferenceAccess(val isRead: Boolean, val isWrite: Boolean) { + READ(true, false), WRITE(false, true), READ_WRITE(true, true) + } + + private fun KtExpression.readWriteAccess(): ReferenceAccess { + var expression = getQualifiedExpressionForSelectorOrThis() + loop@ while (true) { + val parent = expression.parent + when (parent) { + is KtParenthesizedExpression, is KtAnnotatedExpression, is KtLabeledExpression -> expression = parent as KtExpression + else -> break@loop + } + } + + val assignment = expression.getAssignmentByLHS() + if (assignment != null) { + return when (assignment.operationToken) { + KtTokens.EQ -> ReferenceAccess.WRITE + else -> ReferenceAccess.READ_WRITE + } + } + + return if ((expression.parent as? KtUnaryExpression)?.operationToken + in constant { setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) }) + ReferenceAccess.READ_WRITE + else + ReferenceAccess.READ + } +} + +class KotlinClassViaConstructorUSimpleReferenceExpression( + override val psi: KtCallElement, + override val identifier: String, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression, KotlinUElementWithType { + override val resolvedName: String? + get() = (psi.getResolvedCall(psi.analyze())?.resultingDescriptor as? ConstructorDescriptor) + ?.containingDeclaration?.name?.asString() + + override fun resolve(): PsiElement? { + val resolvedCall = psi.getResolvedCall(psi.analyze()) + val resultingDescriptor = resolvedCall?.resultingDescriptor as? ConstructorDescriptor ?: return null + val clazz = resultingDescriptor.containingDeclaration + return clazz.toSource()?.getMaybeLightElement(this) + } +} + +class KotlinStringUSimpleReferenceExpression( + override val identifier: String, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression { + override val psi: PsiElement? + get() = null + override fun resolve() = null + override val resolvedName: String? + get() = identifier +} \ No newline at end of file diff --git a/plugins/uast-kotlin/testData/Anonymous.refNames.txt.191 b/plugins/uast-kotlin/testData/Anonymous.refNames.txt.191 new file mode 100644 index 00000000000..62efa9fed4e --- /dev/null +++ b/plugins/uast-kotlin/testData/Anonymous.refNames.txt.191 @@ -0,0 +1,24 @@ +Closeable -> USimpleNameReferenceExpression (identifier = Closeable) from KtDotQualifiedExpression +io -> USimpleNameReferenceExpression (identifier = io) from KtDotQualifiedExpression +java -> USimpleNameReferenceExpression (identifier = java) from KtNameReferenceExpression +io -> USimpleNameReferenceExpression (identifier = io) from KtNameReferenceExpression +Closeable -> USimpleNameReferenceExpression (identifier = Closeable) from KtNameReferenceExpression +InputStream -> USimpleNameReferenceExpression (identifier = InputStream) from KtDotQualifiedExpression +io -> USimpleNameReferenceExpression (identifier = io) from KtDotQualifiedExpression +java -> USimpleNameReferenceExpression (identifier = java) from KtNameReferenceExpression +io -> USimpleNameReferenceExpression (identifier = io) from KtNameReferenceExpression +InputStream -> USimpleNameReferenceExpression (identifier = InputStream) from KtNameReferenceExpression +Runnable -> USimpleNameReferenceExpression (identifier = Runnable) from KtNameReferenceExpression +run -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression +runnable -> USimpleNameReferenceExpression (identifier = runnable) from KtNameReferenceExpression +run -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +Runnable -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) from KtNameReferenceExpression +println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +run -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression +runnable2 -> USimpleNameReferenceExpression (identifier = runnable2) from KtNameReferenceExpression +run -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +Runnable -> USimpleNameReferenceExpression (identifier = Runnable) from KtNameReferenceExpression +Closeable -> USimpleNameReferenceExpression (identifier = Closeable) from KtNameReferenceExpression +InputStream -> UObjectLiteralExpression from KtNameReferenceExpression +Runnable -> USimpleNameReferenceExpression (identifier = Runnable) from KtNameReferenceExpression +Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression diff --git a/plugins/uast-kotlin/testData/ClassAnnotation.refNames.txt.191 b/plugins/uast-kotlin/testData/ClassAnnotation.refNames.txt.191 new file mode 100644 index 00000000000..69653df4a9f --- /dev/null +++ b/plugins/uast-kotlin/testData/ClassAnnotation.refNames.txt.191 @@ -0,0 +1,6 @@ +Test -> UAnnotation (fqName = null) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +MyAnnotation -> UAnnotation (fqName = MyAnnotation) from KtNameReferenceExpression +MyAnnotation -> UAnnotation (fqName = MyAnnotation) from KtNameReferenceExpression +MyAnnotation -> UAnnotation (fqName = MyAnnotation) from KtNameReferenceExpression +MyAnnotation -> UAnnotation (fqName = MyAnnotation) from KtNameReferenceExpression diff --git a/plugins/uast-kotlin/testData/Constructors.refNames.txt.191 b/plugins/uast-kotlin/testData/Constructors.refNames.txt.191 new file mode 100644 index 00000000000..6f62d7cb1c5 --- /dev/null +++ b/plugins/uast-kotlin/testData/Constructors.refNames.txt.191 @@ -0,0 +1,44 @@ +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression +i -> USimpleNameReferenceExpression (identifier = i) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression +i -> USimpleNameReferenceExpression (identifier = i) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) from KtNameReferenceExpression +println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) from KtNameReferenceExpression +Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression +i -> USimpleNameReferenceExpression (identifier = i) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) from KtNameReferenceExpression +println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression +a -> USimpleNameReferenceExpression (identifier = a) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression +i -> USimpleNameReferenceExpression (identifier = i) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +a -> USimpleNameReferenceExpression (identifier = a) from KtNameReferenceExpression +s -> USimpleNameReferenceExpression (identifier = s) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression +a -> USimpleNameReferenceExpression (identifier = a) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression +i -> USimpleNameReferenceExpression (identifier = i) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +a -> USimpleNameReferenceExpression (identifier = a) from KtNameReferenceExpression +s -> USimpleNameReferenceExpression (identifier = s) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +s -> USimpleNameReferenceExpression (identifier = s) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression +local -> USimpleNameReferenceExpression (identifier = local) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression diff --git a/plugins/uast-kotlin/testData/LocalDeclarations.refNames.txt.191 b/plugins/uast-kotlin/testData/LocalDeclarations.refNames.txt.191 new file mode 100644 index 00000000000..877e89ede2e --- /dev/null +++ b/plugins/uast-kotlin/testData/LocalDeclarations.refNames.txt.191 @@ -0,0 +1,7 @@ +Boolean -> USimpleNameReferenceExpression (identifier = Boolean) from KtNameReferenceExpression +Local -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) from KtNameReferenceExpression +Local -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) from KtNameReferenceExpression +Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +bar -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +Local -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) from KtNameReferenceExpression diff --git a/plugins/uast-kotlin/testData/SimpleAnnotated.refNames.txt.191 b/plugins/uast-kotlin/testData/SimpleAnnotated.refNames.txt.191 new file mode 100644 index 00000000000..48be29b7c7b --- /dev/null +++ b/plugins/uast-kotlin/testData/SimpleAnnotated.refNames.txt.191 @@ -0,0 +1,5 @@ +Suppress -> UAnnotation (fqName = kotlin.Suppress) from KtNameReferenceExpression +println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) from KtNameReferenceExpression +kotlin -> USimpleNameReferenceExpression (identifier = kotlin) from KtNameReferenceExpression +SinceKotlin -> UAnnotation (fqName = kotlin.SinceKotlin) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression diff --git a/plugins/uast-kotlin/tests/AbstractKotlinIdentifiersTest.kt.191 b/plugins/uast-kotlin/tests/AbstractKotlinIdentifiersTest.kt.191 new file mode 100644 index 00000000000..f09ac4a22f4 --- /dev/null +++ b/plugins/uast-kotlin/tests/AbstractKotlinIdentifiersTest.kt.191 @@ -0,0 +1,28 @@ +package org.jetbrains.uast.test.kotlin + +import com.intellij.psi.PsiElement +import org.jetbrains.uast.UFile +import org.jetbrains.uast.UReferenceExpression +import org.jetbrains.uast.test.common.UElementToParentMap +import org.jetbrains.uast.test.common.kotlin.IdentifiersTestBase +import org.jetbrains.uast.test.env.assertEqualsToFile +import org.jetbrains.uast.toUElementOfType +import java.io.File + + +abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), IdentifiersTestBase { + + private fun getTestFile(testName: String, ext: String) = + File(File(AbstractKotlinUastTest.TEST_KOTLIN_MODEL_DIR, testName).canonicalPath + '.' + ext) + + override fun getIdentifiersFile(testName: String): File = getTestFile(testName, "identifiers.txt") + + override fun check(testName: String, file: UFile) { + super.check(testName, file) + assertEqualsToFile("refNames", getTestFile(testName, "refNames.txt"), file.asRefNames()) + } +} + +fun UFile.asRefNames() = object : UElementToParentMap({ it.toUElementOfType()?.referenceNameElement }) { + override fun renderSource(element: PsiElement): String = element.javaClass.simpleName +}.visitUFileAndGetResult(this) \ No newline at end of file