From 8cde41850ef89b21894c0625ae85359c99ad5a06 Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Tue, 6 Feb 2018 13:28:22 +0300 Subject: [PATCH] 181: Uast: support for object literals --- .../kotlin/KotlinUastLanguagePlugin.kt.181 | 12 +++--- .../kotlin/declarations/KotlinUClass.kt.181 | 8 +++- .../testData/Anonymous.identifiers.txt.181 | 31 +++++++++++++++ .../ClassAnnotation.identifiers.txt.181 | 1 + .../LocalDeclarations.identifiers.txt.181 | 1 + .../testData/LocalDeclarations.kt.181 | 14 +++++++ .../testData/LocalDeclarations.log.txt.181 | 39 +++++++++++++++++++ .../testData/LocalDeclarations.render.txt.181 | 21 ++++++++++ .../testData/LocalDeclarations.types.txt.181 | 39 +++++++++++++++++++ .../testData/LocalDeclarations.values.txt.181 | 39 +++++++++++++++++++ .../tests/KotlinUastIdentifiersTest.kt.181 | 3 +- 11 files changed, 201 insertions(+), 7 deletions(-) create mode 100644 plugins/uast-kotlin/testData/Anonymous.identifiers.txt.181 create mode 100644 plugins/uast-kotlin/testData/LocalDeclarations.kt.181 create mode 100644 plugins/uast-kotlin/testData/LocalDeclarations.log.txt.181 create mode 100644 plugins/uast-kotlin/testData/LocalDeclarations.render.txt.181 create mode 100644 plugins/uast-kotlin/testData/LocalDeclarations.types.txt.181 create mode 100644 plugins/uast-kotlin/testData/LocalDeclarations.values.txt.181 diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.181 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.181 index 33fc721e6ec..abda9de222d 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.181 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.181 @@ -21,6 +21,7 @@ import com.intellij.openapi.util.Key import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.impl.source.tree.LeafPsiElement +import com.intellij.psi.util.parentOfType import org.jetbrains.kotlin.asJava.LightClassUtil import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade @@ -297,7 +298,8 @@ internal object KotlinConverter { else -> element } - private val identifiersTokens = setOf(KtTokens.IDENTIFIER, KtTokens.CONSTRUCTOR_KEYWORD, KtTokens.THIS_KEYWORD, KtTokens.SUPER_KEYWORD) + private val identifiersTokens = + setOf(KtTokens.IDENTIFIER, KtTokens.CONSTRUCTOR_KEYWORD, KtTokens.THIS_KEYWORD, KtTokens.SUPER_KEYWORD, KtTokens.OBJECT_KEYWORD) internal fun convertPsiElement(element: PsiElement?, givenParent: UElement?, @@ -357,7 +359,9 @@ internal object KotlinConverter { else -> { if (element is LeafPsiElement) { if (element.elementType in identifiersTokens) - el(build(::KotlinUIdentifier)) + if (element.elementType != KtTokens.OBJECT_KEYWORD || element.parentOfType()?.nameIdentifier == null) + el(build(::KotlinUIdentifier)) + else null else if (element.elementType == KtTokens.LBRACKET && element.parent is KtCollectionLiteralExpression) el { UIdentifier( @@ -369,9 +373,7 @@ internal object KotlinConverter { ) } else null - } else { - null - } + } else null } }} } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt.181 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt.181 index 68190da9821..886373290bd 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt.181 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt.181 @@ -80,7 +80,13 @@ open class KotlinUClass private constructor( override fun getContainingFile(): PsiFile? = unwrapFakeFileForLightClass(psi.containingFile) - override val uastAnchor by lazy { KotlinUIdentifier(nameIdentifier, ktClass?.nameIdentifier, this) } + override val uastAnchor by lazy { getIdentifierSourcePsi()?.let { KotlinUIdentifier(nameIdentifier, it, this) } } + + private fun getIdentifierSourcePsi(): PsiElement? { + ktClass?.nameIdentifier?.let { return it } + (ktClass as? KtObjectDeclaration)?.getObjectKeyword()?.let { return it } + return null + } override fun getInnerClasses(): Array { // filter DefaultImpls to avoid processing same methods from original interface multiple times diff --git a/plugins/uast-kotlin/testData/Anonymous.identifiers.txt.181 b/plugins/uast-kotlin/testData/Anonymous.identifiers.txt.181 new file mode 100644 index 00000000000..40cc421ef48 --- /dev/null +++ b/plugins/uast-kotlin/testData/Anonymous.identifiers.txt.181 @@ -0,0 +1,31 @@ +java -> USimpleNameReferenceExpression (identifier = java) +io -> USimpleNameReferenceExpression (identifier = io) +Closeable -> USimpleNameReferenceExpression (identifier = Closeable) +java -> USimpleNameReferenceExpression (identifier = java) +io -> USimpleNameReferenceExpression (identifier = io) +InputStream -> USimpleNameReferenceExpression (identifier = InputStream) +foo -> UAnnotationMethod (name = foo) + runnable -> ULocalVariable (name = runnable) + object -> UClass (name = null) + Runnable -> USimpleNameReferenceExpression (identifier = Runnable) + run -> UAnnotationMethod (name = run) + runnable -> USimpleNameReferenceExpression (identifier = runnable) + run -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + runnable2 -> ULocalVariable (name = runnable2) + Runnable -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + runnable2 -> USimpleNameReferenceExpression (identifier = runnable2) + run -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + closeableRunnable -> ULocalVariable (name = closeableRunnable) + object -> UClass (name = null) + Runnable -> USimpleNameReferenceExpression (identifier = Runnable) + Closeable -> USimpleNameReferenceExpression (identifier = Closeable) + close -> UAnnotationMethod (name = close) + run -> UAnnotationMethod (name = run) + runnableIs -> ULocalVariable (name = runnableIs) + object -> UClass (name = null) + InputStream -> UObjectLiteralExpression + Runnable -> USimpleNameReferenceExpression (identifier = Runnable) + read -> UAnnotationMethod (name = read) + Int -> USimpleNameReferenceExpression (identifier = Int) + run -> UAnnotationMethod (name = run) diff --git a/plugins/uast-kotlin/testData/ClassAnnotation.identifiers.txt.181 b/plugins/uast-kotlin/testData/ClassAnnotation.identifiers.txt.181 index 70c4e02d27d..b26c4c639f6 100644 --- a/plugins/uast-kotlin/testData/ClassAnnotation.identifiers.txt.181 +++ b/plugins/uast-kotlin/testData/ClassAnnotation.identifiers.txt.181 @@ -8,5 +8,6 @@ B -> UClass (name = B) MyAnnotation -> UAnnotation (fqName = MyAnnotation) InB -> UClass (name = InB) MyAnnotation -> UAnnotation (fqName = MyAnnotation) +object -> UClass (name = Companion) MyAnnotation -> UAnnotation (fqName = MyAnnotation) Obj -> UClass (name = Obj) diff --git a/plugins/uast-kotlin/testData/LocalDeclarations.identifiers.txt.181 b/plugins/uast-kotlin/testData/LocalDeclarations.identifiers.txt.181 index 21cdea0b552..0e28e7b947b 100644 --- a/plugins/uast-kotlin/testData/LocalDeclarations.identifiers.txt.181 +++ b/plugins/uast-kotlin/testData/LocalDeclarations.identifiers.txt.181 @@ -9,5 +9,6 @@ Boolean -> USimpleNameReferenceExpression (identifier = Boolean) someLocalFun -> ULambdaExpression text -> [!] UnknownKotlinExpression (VALUE_PARAMETER) String -> USimpleNameReferenceExpression (identifier = String) + LocalObject -> UClass (name = LocalObject) bar -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) Local -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) diff --git a/plugins/uast-kotlin/testData/LocalDeclarations.kt.181 b/plugins/uast-kotlin/testData/LocalDeclarations.kt.181 new file mode 100644 index 00000000000..26a267e7d8d --- /dev/null +++ b/plugins/uast-kotlin/testData/LocalDeclarations.kt.181 @@ -0,0 +1,14 @@ +fun foo(): Boolean { + class Local + fun bar() = Local() + + val baz = fun() { + Local() + } + + fun Int.someLocalFun(text: String) = 42 + + object LocalObject + + return bar() == Local() +} \ No newline at end of file diff --git a/plugins/uast-kotlin/testData/LocalDeclarations.log.txt.181 b/plugins/uast-kotlin/testData/LocalDeclarations.log.txt.181 new file mode 100644 index 00000000000..bd4c47ba808 --- /dev/null +++ b/plugins/uast-kotlin/testData/LocalDeclarations.log.txt.181 @@ -0,0 +1,39 @@ +UFile (package = ) + UClass (name = LocalDeclarationsKt) + UAnnotationMethod (name = foo) + UBlockExpression + UDeclarationsExpression + UClass (name = Local) + UAnnotationMethod (name = LocalDeclarationsKt$foo$Local) + UDeclarationsExpression + UVariable (name = bar) + ULambdaExpression + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) + UIdentifier (Identifier (Local)) + USimpleNameReferenceExpression (identifier = ) + UDeclarationsExpression + ULocalVariable (name = baz) + ULambdaExpression + UBlockExpression + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) + UIdentifier (Identifier (Local)) + USimpleNameReferenceExpression (identifier = ) + UDeclarationsExpression + UVariable (name = someLocalFun) + ULambdaExpression + UParameter (name = text) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + ULiteralExpression (value = 42) + UDeclarationsExpression + UClass (name = LocalObject) + UField (name = INSTANCE) + UAnnotation (fqName = null) + UAnnotationMethod (name = LocalDeclarationsKt$foo$LocalObject) + UReturnExpression + UBinaryExpression (operator = ==) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (bar)) + USimpleNameReferenceExpression (identifier = bar) + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) + UIdentifier (Identifier (Local)) + USimpleNameReferenceExpression (identifier = ) diff --git a/plugins/uast-kotlin/testData/LocalDeclarations.render.txt.181 b/plugins/uast-kotlin/testData/LocalDeclarations.render.txt.181 new file mode 100644 index 00000000000..b4a41c7ddb2 --- /dev/null +++ b/plugins/uast-kotlin/testData/LocalDeclarations.render.txt.181 @@ -0,0 +1,21 @@ +public final class LocalDeclarationsKt { + public static final fun foo() : boolean { + public static final class Local { + public fun LocalDeclarationsKt$foo$Local() = UastEmptyExpression + } + var bar: = fun () { + () + } + var baz: kotlin.jvm.functions.Function0 = fun () { + () + } + var someLocalFun: kotlin.jvm.functions.Function2 = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) { + 42 + } + public static final class LocalObject { + @null public static final var INSTANCE: LocalDeclarationsKt.foo.LocalObject + private fun LocalDeclarationsKt$foo$LocalObject() = UastEmptyExpression + } + return bar() == () + } +} diff --git a/plugins/uast-kotlin/testData/LocalDeclarations.types.txt.181 b/plugins/uast-kotlin/testData/LocalDeclarations.types.txt.181 new file mode 100644 index 00000000000..7c1a696b7c6 --- /dev/null +++ b/plugins/uast-kotlin/testData/LocalDeclarations.types.txt.181 @@ -0,0 +1,39 @@ +UFile (package = ) [public final class LocalDeclarationsKt {...] + UClass (name = LocalDeclarationsKt) [public final class LocalDeclarationsKt {...}] + UAnnotationMethod (name = foo) [public static final fun foo() : boolean {...}] + UBlockExpression [{...}] : PsiType:Void + UDeclarationsExpression [public static final class Local {...}] + UClass (name = Local) [public static final class Local {...}] + UAnnotationMethod (name = LocalDeclarationsKt$foo$Local) [public fun LocalDeclarationsKt$foo$Local() = UastEmptyExpression] + UDeclarationsExpression [var bar: = fun () {...}] + UVariable (name = bar) [var bar: = fun () {...}] + ULambdaExpression [fun () {...}] + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [()] : PsiType: + UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))] + USimpleNameReferenceExpression (identifier = ) [] : PsiType: + UDeclarationsExpression [var baz: kotlin.jvm.functions.Function0 = fun () {...}] + ULocalVariable (name = baz) [var baz: kotlin.jvm.functions.Function0 = fun () {...}] + ULambdaExpression [fun () {...}] + UBlockExpression [{...}] : PsiType: + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [()] : PsiType: + UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))] + USimpleNameReferenceExpression (identifier = ) [] : PsiType: + UDeclarationsExpression [var someLocalFun: kotlin.jvm.functions.Function2 = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}] + UVariable (name = someLocalFun) [var someLocalFun: kotlin.jvm.functions.Function2 = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}] + ULambdaExpression [fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}] + UParameter (name = text) [@org.jetbrains.annotations.NotNull var text: java.lang.String] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + ULiteralExpression (value = 42) [42] : PsiType:int + UDeclarationsExpression [public static final class LocalObject {...}] + UClass (name = LocalObject) [public static final class LocalObject {...}] + UField (name = INSTANCE) [@null public static final var INSTANCE: LocalDeclarationsKt.foo.LocalObject] + UAnnotation (fqName = null) [@null] + UAnnotationMethod (name = LocalDeclarationsKt$foo$LocalObject) [private fun LocalDeclarationsKt$foo$LocalObject() = UastEmptyExpression] + UReturnExpression [return bar() == ()] : PsiType:Void + UBinaryExpression (operator = ==) [bar() == ()] : PsiType:boolean + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [bar()] : PsiType: + UIdentifier (Identifier (bar)) [UIdentifier (Identifier (bar))] + USimpleNameReferenceExpression (identifier = bar) [bar] : PsiType: + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [()] : PsiType: + UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))] + USimpleNameReferenceExpression (identifier = ) [] : PsiType: diff --git a/plugins/uast-kotlin/testData/LocalDeclarations.values.txt.181 b/plugins/uast-kotlin/testData/LocalDeclarations.values.txt.181 new file mode 100644 index 00000000000..abbcb97f975 --- /dev/null +++ b/plugins/uast-kotlin/testData/LocalDeclarations.values.txt.181 @@ -0,0 +1,39 @@ +UFile (package = ) [public final class LocalDeclarationsKt {...] + UClass (name = LocalDeclarationsKt) [public final class LocalDeclarationsKt {...}] + UAnnotationMethod (name = foo) [public static final fun foo() : boolean {...}] + UBlockExpression [{...}] = Nothing + UDeclarationsExpression [public static final class Local {...}] = Undetermined + UClass (name = Local) [public static final class Local {...}] + UAnnotationMethod (name = LocalDeclarationsKt$foo$Local) [public fun LocalDeclarationsKt$foo$Local() = UastEmptyExpression] + UDeclarationsExpression [var bar: = fun () {...}] = Undetermined + UVariable (name = bar) [var bar: = fun () {...}] + ULambdaExpression [fun () {...}] = Undetermined + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [()] = external ()() + UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))] + USimpleNameReferenceExpression (identifier = ) [] = external ()() + UDeclarationsExpression [var baz: kotlin.jvm.functions.Function0 = fun () {...}] = Undetermined + ULocalVariable (name = baz) [var baz: kotlin.jvm.functions.Function0 = fun () {...}] + ULambdaExpression [fun () {...}] = Undetermined + UBlockExpression [{...}] = external ()() + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [()] = external ()() + UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))] + USimpleNameReferenceExpression (identifier = ) [] = external ()() + UDeclarationsExpression [var someLocalFun: kotlin.jvm.functions.Function2 = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}] = Undetermined + UVariable (name = someLocalFun) [var someLocalFun: kotlin.jvm.functions.Function2 = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}] + ULambdaExpression [fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}] = Undetermined + UParameter (name = text) [@org.jetbrains.annotations.NotNull var text: java.lang.String] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + ULiteralExpression (value = 42) [42] = 42 + UDeclarationsExpression [public static final class LocalObject {...}] = Undetermined + UClass (name = LocalObject) [public static final class LocalObject {...}] + UField (name = INSTANCE) [@null public static final var INSTANCE: LocalDeclarationsKt.foo.LocalObject] + UAnnotation (fqName = null) [@null] + UAnnotationMethod (name = LocalDeclarationsKt$foo$LocalObject) [private fun LocalDeclarationsKt$foo$LocalObject() = UastEmptyExpression] + UReturnExpression [return bar() == ()] = Nothing + UBinaryExpression (operator = ==) [bar() == ()] = Undetermined + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [bar()] = external bar()() + UIdentifier (Identifier (bar)) [UIdentifier (Identifier (bar))] + USimpleNameReferenceExpression (identifier = bar) [bar] = external bar()() + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [()] = external ()() + UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))] + USimpleNameReferenceExpression (identifier = ) [] = external ()() diff --git a/plugins/uast-kotlin/tests/KotlinUastIdentifiersTest.kt.181 b/plugins/uast-kotlin/tests/KotlinUastIdentifiersTest.kt.181 index 5906787d5fc..d45325d1da4 100644 --- a/plugins/uast-kotlin/tests/KotlinUastIdentifiersTest.kt.181 +++ b/plugins/uast-kotlin/tests/KotlinUastIdentifiersTest.kt.181 @@ -18,9 +18,10 @@ class KotlinUastIdentifiersTest : AbstractKotlinIdentifiersTest() { @Test fun testConstructors() = doTest("Constructors") - @Test fun testSimpleAnnotated() = doTest("SimpleAnnotated") + @Test + fun testAnonymous() = doTest("Anonymous") } \ No newline at end of file