Uast: fixes for Enum identifiers (KT-35432)

This commit is contained in:
Nicolay Mitropolsky
2020-01-23 19:29:38 +03:00
parent 953b461c53
commit ac3a8eb494
13 changed files with 151 additions and 13 deletions
@@ -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 {
@@ -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)
@@ -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)
@@ -0,0 +1,6 @@
enum class Style(val value: String?) {
SYSTEM("system"),
USER("user"),
INTERNAL("internal"),
UNKNOWN(null);
}
@@ -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)
@@ -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)
@@ -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
@@ -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
}
@@ -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
}
@@ -51,6 +51,9 @@ class KotlinIDERenderLogTest : AbstractKotlinUastLightCodeInsightFixtureTest(),
@Test
fun testEnumValueMembers() = doTest("EnumValueMembers")
@Test
fun testEnumValuesConstructors() = doTest("EnumValuesConstructors")
@Test
fun testStringTemplate() = doTest("StringTemplate")
@@ -266,6 +266,34 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
}
}
@Test
fun testEnumCallIdentifier() {
doTest("EnumValuesConstructors") { _, file ->
val enumEntry = file.findElementByTextFromPsi<UElement>("(\"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<UElement>("(\"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 ->
@@ -27,4 +27,7 @@ class KotlinUastIdentifiersTest : AbstractKotlinIdentifiersTest() {
@Test
fun testSuperCalls() = doTest("SuperCalls")
@Test
fun testEnumValuesConstructors() = doTest("EnumValuesConstructors")
}
@@ -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")