From ac3a8eb49484a3696c9fcbc7f9a699344f341a17 Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Thu, 23 Jan 2020 19:29:38 +0300 Subject: [PATCH] Uast: fixes for Enum identifiers (KT-35432) --- .../declarations/UastLightIdentifier.kt | 4 ++- .../KotlinUFunctionCallExpression.kt | 9 +++-- .../EnumValuesConstructors.identifiers.txt | 7 ++++ .../testData/EnumValuesConstructors.kt | 6 ++++ .../EnumValuesConstructors.log-ide.txt | 24 ++++++++++++++ .../testData/EnumValuesConstructors.log.txt | 24 ++++++++++++++ .../EnumValuesConstructors.refNames.txt | 5 +++ .../EnumValuesConstructors.render-ide.txt | 9 +++++ .../EnumValuesConstructors.render.txt | 9 +++++ .../tests/KotlinIDERenderLogTest.kt | 3 ++ .../uast-kotlin/tests/KotlinUastApiTest.kt | 28 ++++++++++++++++ .../tests/KotlinUastIdentifiersTest.kt | 3 ++ .../tests/SimpleKotlinRenderLogTest.kt | 33 +++++++++++++------ 13 files changed, 151 insertions(+), 13 deletions(-) create mode 100644 plugins/uast-kotlin/testData/EnumValuesConstructors.identifiers.txt create mode 100644 plugins/uast-kotlin/testData/EnumValuesConstructors.kt create mode 100644 plugins/uast-kotlin/testData/EnumValuesConstructors.log-ide.txt create mode 100644 plugins/uast-kotlin/testData/EnumValuesConstructors.log.txt create mode 100644 plugins/uast-kotlin/testData/EnumValuesConstructors.refNames.txt create mode 100644 plugins/uast-kotlin/testData/EnumValuesConstructors.render-ide.txt create mode 100644 plugins/uast-kotlin/testData/EnumValuesConstructors.render.txt diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/UastLightIdentifier.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/UastLightIdentifier.kt index c2695d57b86..0b33ab4fed2 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/UastLightIdentifier.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/UastLightIdentifier.kt @@ -23,6 +23,7 @@ import com.intellij.psi.PsiNameIdentifierOwner import com.intellij.psi.impl.source.tree.LeafPsiElement import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments import org.jetbrains.uast.UElement import org.jetbrains.uast.UIdentifier import org.jetbrains.uast.kotlin.unwrapFakeFileForLightClass @@ -42,7 +43,8 @@ class KotlinUIdentifier private constructor( init { if (ApplicationManager.getApplication().isUnitTestMode && !acceptableSourcePsi(sourcePsi)) - throw AssertionError("sourcePsi should be physical leaf element but got $sourcePsi of (${sourcePsi?.javaClass})") + throw KotlinExceptionWithAttachments("sourcePsi should be physical leaf element but got $sourcePsi of (${sourcePsi?.javaClass})") + .withAttachment("sourcePsi.text", sourcePsi?.text) } private fun acceptableSourcePsi(sourcePsi: PsiElement?): Boolean { diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt index 974a05ab933..be0fbaf3077 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt @@ -67,8 +67,13 @@ class KotlinUFunctionCallExpression( } override val methodIdentifier by lz { - val calleeExpression = sourcePsi.calleeExpression - when (calleeExpression) { + if (sourcePsi is KtSuperTypeCallEntry) { + ((sourcePsi.parent as? KtInitializerList)?.parent as? KtEnumEntry)?.let { ktEnumEntry -> + return@lz KotlinUIdentifier(ktEnumEntry.nameIdentifier, this) + } + } + + when (val calleeExpression = sourcePsi.calleeExpression) { null -> null is KtNameReferenceExpression -> KotlinUIdentifier(calleeExpression.getReferencedNameElement(), this) diff --git a/plugins/uast-kotlin/testData/EnumValuesConstructors.identifiers.txt b/plugins/uast-kotlin/testData/EnumValuesConstructors.identifiers.txt new file mode 100644 index 00000000000..754f7e2db6d --- /dev/null +++ b/plugins/uast-kotlin/testData/EnumValuesConstructors.identifiers.txt @@ -0,0 +1,7 @@ +Style -> UClass (name = Style) +value -> UParameter (name = value) +String -> USimpleNameReferenceExpression (identifier = String) +SYSTEM -> UEnumConstant (name = SYSTEM) +USER -> UEnumConstant (name = USER) +INTERNAL -> UEnumConstant (name = INTERNAL) +UNKNOWN -> UEnumConstant (name = UNKNOWN) diff --git a/plugins/uast-kotlin/testData/EnumValuesConstructors.kt b/plugins/uast-kotlin/testData/EnumValuesConstructors.kt new file mode 100644 index 00000000000..f7198ca4082 --- /dev/null +++ b/plugins/uast-kotlin/testData/EnumValuesConstructors.kt @@ -0,0 +1,6 @@ +enum class Style(val value: String?) { + SYSTEM("system"), + USER("user"), + INTERNAL("internal"), + UNKNOWN(null); +} \ No newline at end of file diff --git a/plugins/uast-kotlin/testData/EnumValuesConstructors.log-ide.txt b/plugins/uast-kotlin/testData/EnumValuesConstructors.log-ide.txt new file mode 100644 index 00000000000..130f197f532 --- /dev/null +++ b/plugins/uast-kotlin/testData/EnumValuesConstructors.log-ide.txt @@ -0,0 +1,24 @@ +UFile (package = ) + UClass (name = Style) + UField (name = value) + UAnnotation (fqName = org.jetbrains.annotations.Nullable) + UEnumConstant (name = SYSTEM) + UAnnotation (fqName = null) + USimpleNameReferenceExpression (identifier = Style) + ULiteralExpression (value = "system") + UEnumConstant (name = USER) + UAnnotation (fqName = null) + USimpleNameReferenceExpression (identifier = Style) + ULiteralExpression (value = "user") + UEnumConstant (name = INTERNAL) + UAnnotation (fqName = null) + USimpleNameReferenceExpression (identifier = Style) + ULiteralExpression (value = "internal") + UEnumConstant (name = UNKNOWN) + UAnnotation (fqName = null) + USimpleNameReferenceExpression (identifier = Style) + ULiteralExpression (value = null) + UMethod (name = getValue) + UMethod (name = Style) + UParameter (name = value) + UAnnotation (fqName = org.jetbrains.annotations.Nullable) diff --git a/plugins/uast-kotlin/testData/EnumValuesConstructors.log.txt b/plugins/uast-kotlin/testData/EnumValuesConstructors.log.txt new file mode 100644 index 00000000000..71229cd080b --- /dev/null +++ b/plugins/uast-kotlin/testData/EnumValuesConstructors.log.txt @@ -0,0 +1,24 @@ +UFile (package = ) + UClass (name = Style) + UEnumConstant (name = SYSTEM) + UAnnotation (fqName = null) + USimpleNameReferenceExpression (identifier = Style) + ULiteralExpression (value = "system") + UEnumConstant (name = USER) + UAnnotation (fqName = null) + USimpleNameReferenceExpression (identifier = Style) + ULiteralExpression (value = "user") + UEnumConstant (name = INTERNAL) + UAnnotation (fqName = null) + USimpleNameReferenceExpression (identifier = Style) + ULiteralExpression (value = "internal") + UEnumConstant (name = UNKNOWN) + UAnnotation (fqName = null) + USimpleNameReferenceExpression (identifier = Style) + ULiteralExpression (value = null) + UField (name = value) + UAnnotation (fqName = org.jetbrains.annotations.Nullable) + UMethod (name = getValue) + UMethod (name = Style) + UParameter (name = value) + UAnnotation (fqName = org.jetbrains.annotations.Nullable) diff --git a/plugins/uast-kotlin/testData/EnumValuesConstructors.refNames.txt b/plugins/uast-kotlin/testData/EnumValuesConstructors.refNames.txt new file mode 100644 index 00000000000..c3b23a5a3cd --- /dev/null +++ b/plugins/uast-kotlin/testData/EnumValuesConstructors.refNames.txt @@ -0,0 +1,5 @@ +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +Style -> UClass (name = Style) from KtEnumEntrySuperclassReferenceExpression +Style -> UClass (name = Style) from KtEnumEntrySuperclassReferenceExpression +Style -> UClass (name = Style) from KtEnumEntrySuperclassReferenceExpression +Style -> UClass (name = Style) from KtEnumEntrySuperclassReferenceExpression diff --git a/plugins/uast-kotlin/testData/EnumValuesConstructors.render-ide.txt b/plugins/uast-kotlin/testData/EnumValuesConstructors.render-ide.txt new file mode 100644 index 00000000000..04517caf5b1 --- /dev/null +++ b/plugins/uast-kotlin/testData/EnumValuesConstructors.render-ide.txt @@ -0,0 +1,9 @@ +public enum Style { + @org.jetbrains.annotations.Nullable private final var value: java.lang.String + @null SYSTEM("system") + @null USER("user") + @null INTERNAL("internal") + @null UNKNOWN(null) + public final fun getValue() : java.lang.String = UastEmptyExpression + private fun Style(@org.jetbrains.annotations.Nullable value: java.lang.String) = UastEmptyExpression +} diff --git a/plugins/uast-kotlin/testData/EnumValuesConstructors.render.txt b/plugins/uast-kotlin/testData/EnumValuesConstructors.render.txt new file mode 100644 index 00000000000..1db9d1eb354 --- /dev/null +++ b/plugins/uast-kotlin/testData/EnumValuesConstructors.render.txt @@ -0,0 +1,9 @@ +public enum Style { + @null SYSTEM("system") + @null USER("user") + @null INTERNAL("internal") + @null UNKNOWN(null) + @org.jetbrains.annotations.Nullable private final var value: java.lang.String + public final fun getValue() : java.lang.String = UastEmptyExpression + private fun Style(@org.jetbrains.annotations.Nullable value: java.lang.String) = UastEmptyExpression +} diff --git a/plugins/uast-kotlin/tests/KotlinIDERenderLogTest.kt b/plugins/uast-kotlin/tests/KotlinIDERenderLogTest.kt index 72c85ce4c4b..c6a97379ff7 100644 --- a/plugins/uast-kotlin/tests/KotlinIDERenderLogTest.kt +++ b/plugins/uast-kotlin/tests/KotlinIDERenderLogTest.kt @@ -51,6 +51,9 @@ class KotlinIDERenderLogTest : AbstractKotlinUastLightCodeInsightFixtureTest(), @Test fun testEnumValueMembers() = doTest("EnumValueMembers") + @Test + fun testEnumValuesConstructors() = doTest("EnumValuesConstructors") + @Test fun testStringTemplate() = doTest("StringTemplate") diff --git a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt index 9bf59abc635..69190e91c57 100644 --- a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt +++ b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt @@ -266,6 +266,34 @@ class KotlinUastApiTest : AbstractKotlinUastTest() { } } + @Test + fun testEnumCallIdentifier() { + doTest("EnumValuesConstructors") { _, file -> + val enumEntry = file.findElementByTextFromPsi("(\"system\")") + enumEntry.accept(object : AbstractUastVisitor() { + override fun visitCallExpression(node: UCallExpression): Boolean { + val methodIdentifier = node.methodIdentifier + assertEquals("SYSTEM", methodIdentifier?.name) + return super.visitCallExpression(node) + } + }) + } + } + + @Test + fun testEnumCallWithBodyIdentifier() { + doTest("EnumValueMembers") { _, file -> + val enumEntry = file.findElementByTextFromPsi("(\"foo\")") + enumEntry.accept(object : AbstractUastVisitor() { + override fun visitCallExpression(node: UCallExpression): Boolean { + val methodIdentifier = node.methodIdentifier + assertEquals("SHEET", methodIdentifier?.name) + return super.visitCallExpression(node) + } + }) + } + } + @Test fun testSimpleAnnotated() { doTest("SimpleAnnotated") { _, file -> diff --git a/plugins/uast-kotlin/tests/KotlinUastIdentifiersTest.kt b/plugins/uast-kotlin/tests/KotlinUastIdentifiersTest.kt index e0879333571..c54289adc05 100644 --- a/plugins/uast-kotlin/tests/KotlinUastIdentifiersTest.kt +++ b/plugins/uast-kotlin/tests/KotlinUastIdentifiersTest.kt @@ -27,4 +27,7 @@ class KotlinUastIdentifiersTest : AbstractKotlinIdentifiersTest() { @Test fun testSuperCalls() = doTest("SuperCalls") + @Test + fun testEnumValuesConstructors() = doTest("EnumValuesConstructors") + } \ No newline at end of file diff --git a/plugins/uast-kotlin/tests/SimpleKotlinRenderLogTest.kt b/plugins/uast-kotlin/tests/SimpleKotlinRenderLogTest.kt index d6140c554ba..5432d7a8bff 100644 --- a/plugins/uast-kotlin/tests/SimpleKotlinRenderLogTest.kt +++ b/plugins/uast-kotlin/tests/SimpleKotlinRenderLogTest.kt @@ -23,30 +23,43 @@ class SimpleKotlinRenderLogTest : AbstractKotlinUastTest(), AbstractKotlinRender @Test fun testBitwise() = doTest("Bitwise") - @Test fun testElvis() = doTest("Elvis") + @Test + fun testElvis() = doTest("Elvis") - @Test fun testPropertyAccessors() = doTest("PropertyAccessors") + @Test + fun testPropertyAccessors() = doTest("PropertyAccessors") - @Test fun testPropertyInitializer() = doTest("PropertyInitializer") + @Test + fun testPropertyInitializer() = doTest("PropertyInitializer") - @Test fun testPropertyInitializerWithoutSetter() = doTest("PropertyInitializerWithoutSetter") + @Test + fun testPropertyInitializerWithoutSetter() = doTest("PropertyInitializerWithoutSetter") - @Test fun testAnnotationParameters() = doTest("AnnotationParameters") + @Test + fun testAnnotationParameters() = doTest("AnnotationParameters") - @Test fun testEnumValueMembers() = doTest("EnumValueMembers") + @Test + fun testEnumValueMembers() = doTest("EnumValueMembers") - @Test fun testStringTemplate() = doTest("StringTemplate") + @Test + fun testEnumValuesConstructors() = doTest("EnumValuesConstructors") - @Test fun testStringTemplateComplex() = doTest("StringTemplateComplex") + @Test + fun testStringTemplate() = doTest("StringTemplate") + + @Test + fun testStringTemplateComplex() = doTest("StringTemplateComplex") @Test fun testStringTemplateComplexForUInjectionHost() = withForceUInjectionHostValue { doTest("StringTemplateComplexForUInjectionHost") } - @Test fun testQualifiedConstructorCall() = doTest("QualifiedConstructorCall") + @Test + fun testQualifiedConstructorCall() = doTest("QualifiedConstructorCall") - @Test fun testPropertyDelegate() = doTest("PropertyDelegate") + @Test + fun testPropertyDelegate() = doTest("PropertyDelegate") @Test fun testLocalVariableWithAnnotation() = doTest("LocalVariableWithAnnotation")