181: Uast: support for object literals

This commit is contained in:
Nicolay Mitropolsky
2018-02-06 13:28:22 +03:00
committed by Nikolay Krasko
parent 036c0fd6a4
commit 8cde41850e
11 changed files with 201 additions and 7 deletions
@@ -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<UIdentifier>(build(::KotlinUIdentifier))
if (element.elementType != KtTokens.OBJECT_KEYWORD || element.parentOfType<KtObjectDeclaration>()?.nameIdentifier == null)
el<UIdentifier>(build(::KotlinUIdentifier))
else null
else if (element.elementType == KtTokens.LBRACKET && element.parent is KtCollectionLiteralExpression)
el<UIdentifier> {
UIdentifier(
@@ -369,9 +373,7 @@ internal object KotlinConverter {
)
}
else null
} else {
null
}
} else null
}
}}
}
@@ -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<UClass> {
// filter DefaultImpls to avoid processing same methods from original interface multiple times
@@ -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)
@@ -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)
@@ -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))
+14
View File
@@ -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()
}
@@ -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 = <init>)
UDeclarationsExpression
ULocalVariable (name = baz)
ULambdaExpression
UBlockExpression
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0))
UIdentifier (Identifier (Local))
USimpleNameReferenceExpression (identifier = <init>)
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 = <init>)
@@ -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: <ErrorType> = fun () {
<init>()
}
var baz: kotlin.jvm.functions.Function0<? extends kotlin.Unit> = fun () {
<init>()
}
var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = 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() == <init>()
}
}
@@ -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: <ErrorType> = fun () {...}]
UVariable (name = bar) [var bar: <ErrorType> = fun () {...}]
ULambdaExpression [fun () {...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [<init>()] : PsiType:<ErrorType>
UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))]
USimpleNameReferenceExpression (identifier = <init>) [<init>] : PsiType:<ErrorType>
UDeclarationsExpression [var baz: kotlin.jvm.functions.Function0<? extends kotlin.Unit> = fun () {...}]
ULocalVariable (name = baz) [var baz: kotlin.jvm.functions.Function0<? extends kotlin.Unit> = fun () {...}]
ULambdaExpression [fun () {...}]
UBlockExpression [{...}] : PsiType:<ErrorType>
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [<init>()] : PsiType:<ErrorType>
UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))]
USimpleNameReferenceExpression (identifier = <init>) [<init>] : PsiType:<ErrorType>
UDeclarationsExpression [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}]
UVariable (name = someLocalFun) [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = 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() == <init>()] : PsiType:Void
UBinaryExpression (operator = ==) [bar() == <init>()] : PsiType:boolean
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [bar()] : PsiType:<ErrorType>
UIdentifier (Identifier (bar)) [UIdentifier (Identifier (bar))]
USimpleNameReferenceExpression (identifier = bar) [bar] : PsiType:<ErrorType>
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [<init>()] : PsiType:<ErrorType>
UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))]
USimpleNameReferenceExpression (identifier = <init>) [<init>] : PsiType:<ErrorType>
@@ -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: <ErrorType> = fun () {...}] = Undetermined
UVariable (name = bar) [var bar: <ErrorType> = fun () {...}]
ULambdaExpression [fun () {...}] = Undetermined
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [<init>()] = external <init>()()
UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))]
USimpleNameReferenceExpression (identifier = <init>) [<init>] = external <init>()()
UDeclarationsExpression [var baz: kotlin.jvm.functions.Function0<? extends kotlin.Unit> = fun () {...}] = Undetermined
ULocalVariable (name = baz) [var baz: kotlin.jvm.functions.Function0<? extends kotlin.Unit> = fun () {...}]
ULambdaExpression [fun () {...}] = Undetermined
UBlockExpression [{...}] = external <init>()()
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [<init>()] = external <init>()()
UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))]
USimpleNameReferenceExpression (identifier = <init>) [<init>] = external <init>()()
UDeclarationsExpression [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}] = Undetermined
UVariable (name = someLocalFun) [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = 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() == <init>()] = Nothing
UBinaryExpression (operator = ==) [bar() == <init>()] = 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)) [<init>()] = external <init>()()
UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))]
USimpleNameReferenceExpression (identifier = <init>) [<init>] = external <init>()()
@@ -18,9 +18,10 @@ class KotlinUastIdentifiersTest : AbstractKotlinIdentifiersTest() {
@Test
fun testConstructors() = doTest("Constructors")
@Test
fun testSimpleAnnotated() = doTest("SimpleAnnotated")
@Test
fun testAnonymous() = doTest("Anonymous")
}