Uast-java: support getting UIdentifiers from toUElement

This commit is contained in:
Nicolay Mitropolsky
2018-01-18 13:25:41 +03:00
parent 649f88e86b
commit a93879112b
8 changed files with 132 additions and 3 deletions
@@ -34,4 +34,10 @@ open class UIdentifier(
override val sourcePsi: PsiElement? = psi
override val javaPsi: PsiElement? = null
}
open class LazyParentUIdentifier(psi: PsiElement?, private val givenParent: UElement?) : UIdentifier(psi, givenParent) {
override val uastParent: UElement? by lazy { givenParent ?: sourcePsi?.parent?.toUElement() }
}
@@ -178,9 +178,8 @@ internal object JavaConverter {
is PsiResourceExpression -> convertExpression(el.expression, givenParent, requiredType)
is PsiExpression -> convertExpression(el, givenParent, requiredType)
is PsiStatement -> convertStatement(el, givenParent, requiredType)
is PsiIdentifier -> el<USimpleNameReferenceExpression> {
JavaUSimpleNameReferenceExpression(el, el.text, givenParent)
}
is PsiIdentifier -> el<USimpleNameReferenceExpression> { JavaUSimpleNameReferenceExpression(el, el.text, givenParent) }
?: el<UIdentifier> { LazyParentUIdentifier(el, givenParent) }
is PsiNameValuePair -> el<UNamedExpression>(build(::JavaUNamedExpression))
is PsiArrayInitializerMemberValue -> el<UCallExpression>(build(::JavaAnnotationArrayInitializerUCallExpression))
is PsiTypeElement -> el<UTypeReferenceExpression>(build(::JavaUTypeReferenceExpression))
@@ -0,0 +1,19 @@
Annotation -> UClass (name = Annotation)
Annotation -> USimpleNameReferenceExpression (identifier = Annotation)
A -> UClass (name = A)
AnnotationInner -> UClass (name = AnnotationInner)
Annotation -> USimpleNameReferenceExpression (identifier = Annotation)
value -> UAnnotationMethod (name = value)
AnnotationArray -> USimpleNameReferenceExpression (identifier = AnnotationArray)
Annotation -> USimpleNameReferenceExpression (identifier = Annotation)
B1 -> UClass (name = B1)
AnnotationArray -> USimpleNameReferenceExpression (identifier = AnnotationArray)
value -> UNamedExpression (name = value)
Annotation -> USimpleNameReferenceExpression (identifier = Annotation)
B2 -> UClass (name = B2)
AnnotationArray -> UClass (name = AnnotationArray)
Annotation -> USimpleNameReferenceExpression (identifier = Annotation)
value -> UAnnotationMethod (name = value)
AnnotationArray -> USimpleNameReferenceExpression (identifier = AnnotationArray)
Annotation -> USimpleNameReferenceExpression (identifier = Annotation)
C -> UClass (name = C)
@@ -0,0 +1,12 @@
Anonymous -> UClass (name = Anonymous)
foo -> UMethod (name = foo)
variable -> ULocalVariable (name = variable)
Runnable -> USimpleNameReferenceExpression (identifier = Runnable)
runnable -> ULocalVariable (name = runnable)
Runnable -> USimpleNameReferenceExpression (identifier = Runnable)
run -> UMethod (name = run)
variable -> ULocalVariable (name = variable)
variable -> USimpleNameReferenceExpression (identifier = variable)
runnable -> USimpleNameReferenceExpression (identifier = runnable)
run -> UQualifiedReferenceExpression
variable -> USimpleNameReferenceExpression (identifier = variable)
@@ -0,0 +1,9 @@
TryWithResources -> UClass (name = TryWithResources)
foo -> UMethod (name = foo)
BufferedReader -> USimpleNameReferenceExpression (identifier = BufferedReader)
br -> ULocalVariable (name = br)
BufferedReader -> USimpleNameReferenceExpression (identifier = BufferedReader)
FileReader -> USimpleNameReferenceExpression (identifier = FileReader)
path -> USimpleNameReferenceExpression (identifier = path)
br -> USimpleNameReferenceExpression (identifier = br)
readLine -> UQualifiedReferenceExpression
@@ -0,0 +1,47 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package org.jetbrains.uast.test.common
import com.intellij.psi.PsiCodeBlock
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiFile
import org.jetbrains.uast.UFile
import org.jetbrains.uast.UIdentifier
import org.jetbrains.uast.sourcePsiElement
import org.jetbrains.uast.test.env.assertEqualsToFile
import org.jetbrains.uast.toUElementOfType
import java.io.File
interface IdentifiersTestBase {
fun getIdentifiersFile(testName: String): File
private fun UFile.asIdentifiers(): String {
val builder = StringBuilder()
var level = 0
(this.sourcePsi as PsiFile).accept(object : PsiElementVisitor() {
override fun visitElement(element: PsiElement) {
val uIdentifier = element.toUElementOfType<UIdentifier>()
if (uIdentifier != null) {
builder.append(" ".repeat(level))
builder.append(uIdentifier.sourcePsiElement!!.text)
builder.append(" -> ")
builder.append(uIdentifier.uastParent?.asLogString())
builder.appendln()
}
if (element is PsiCodeBlock) level++
element.acceptChildren(this)
if (element is PsiCodeBlock) level--
}
})
return builder.toString()
}
fun check(testName: String, file: UFile) {
val valuesFile = getIdentifiersFile(testName)
assertEqualsToFile("Identifiers", valuesFile, file.asIdentifiers())
}
}
@@ -0,0 +1,17 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package org.jetbrains.uast.test.java
import org.jetbrains.uast.evaluation.UEvaluatorExtension
import org.jetbrains.uast.test.common.IdentifiersTestBase
import java.io.File
abstract class AbstractJavaIdentifiersTest : AbstractJavaUastTest(), IdentifiersTestBase {
protected var _evaluatorExtension: UEvaluatorExtension? = null
private fun getTestFile(testName: String, ext: String) =
File(File(TEST_JAVA_MODEL_DIR, testName).canonicalPath.substringBeforeLast('.') + '.' + ext)
override fun getIdentifiersFile(testName: String): File = getTestFile(testName, "identifiers.txt")
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package org.jetbrains.uast.test.java
import org.junit.Test
class JavaIdentifiersTest : AbstractJavaIdentifiersTest() {
@Test
fun testAnnotation() = doTest("Simple/Annotation.java")
@Test
fun testAnonymous() = doTest("Simple/Anonymous.java")
@Test
fun testTryWithResources() = doTest("Simple/TryWithResources.java")
}