diff --git a/uast/uast-common/src/org/jetbrains/uast/baseElements/UIdentifier.kt b/uast/uast-common/src/org/jetbrains/uast/baseElements/UIdentifier.kt index 1c81cb09e36f..f5284479a7c5 100644 --- a/uast/uast-common/src/org/jetbrains/uast/baseElements/UIdentifier.kt +++ b/uast/uast-common/src/org/jetbrains/uast/baseElements/UIdentifier.kt @@ -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() } + } \ No newline at end of file diff --git a/uast/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt b/uast/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt index 39f8b9bdad2e..889b7991c21f 100644 --- a/uast/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt +++ b/uast/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt @@ -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 { - JavaUSimpleNameReferenceExpression(el, el.text, givenParent) - } + is PsiIdentifier -> el { JavaUSimpleNameReferenceExpression(el, el.text, givenParent) } + ?: el { LazyParentUIdentifier(el, givenParent) } is PsiNameValuePair -> el(build(::JavaUNamedExpression)) is PsiArrayInitializerMemberValue -> el(build(::JavaAnnotationArrayInitializerUCallExpression)) is PsiTypeElement -> el(build(::JavaUTypeReferenceExpression)) diff --git a/uast/uast-tests/java/Simple/Annotation.identifiers.txt b/uast/uast-tests/java/Simple/Annotation.identifiers.txt new file mode 100644 index 000000000000..20571211a823 --- /dev/null +++ b/uast/uast-tests/java/Simple/Annotation.identifiers.txt @@ -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) diff --git a/uast/uast-tests/java/Simple/Anonymous.identifiers.txt b/uast/uast-tests/java/Simple/Anonymous.identifiers.txt new file mode 100644 index 000000000000..3ad57cb44bf4 --- /dev/null +++ b/uast/uast-tests/java/Simple/Anonymous.identifiers.txt @@ -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) diff --git a/uast/uast-tests/java/Simple/TryWithResources.identifiers.txt b/uast/uast-tests/java/Simple/TryWithResources.identifiers.txt new file mode 100644 index 000000000000..6b013777fd68 --- /dev/null +++ b/uast/uast-tests/java/Simple/TryWithResources.identifiers.txt @@ -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 diff --git a/uast/uast-tests/src/org/jetbrains/uast/test/common/IdentifiersTestBase.kt b/uast/uast-tests/src/org/jetbrains/uast/test/common/IdentifiersTestBase.kt new file mode 100644 index 000000000000..d323c25237db --- /dev/null +++ b/uast/uast-tests/src/org/jetbrains/uast/test/common/IdentifiersTestBase.kt @@ -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() + 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()) + } + +} diff --git a/uast/uast-tests/test/org/jetbrains/uast/test/java/AbstractJavaIdentifiersTest.kt b/uast/uast-tests/test/org/jetbrains/uast/test/java/AbstractJavaIdentifiersTest.kt new file mode 100644 index 000000000000..b9791a71e9ad --- /dev/null +++ b/uast/uast-tests/test/org/jetbrains/uast/test/java/AbstractJavaIdentifiersTest.kt @@ -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") +} diff --git a/uast/uast-tests/test/org/jetbrains/uast/test/java/JavaIdentifiersTest.kt b/uast/uast-tests/test/org/jetbrains/uast/test/java/JavaIdentifiersTest.kt new file mode 100644 index 000000000000..3609d3f2faf0 --- /dev/null +++ b/uast/uast-tests/test/org/jetbrains/uast/test/java/JavaIdentifiersTest.kt @@ -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") + + +} \ No newline at end of file