Uast: proper identifiers for KotlinUBinaryExpression (KT-25092)
This commit is contained in:
@@ -361,6 +361,8 @@ internal object KotlinConverter {
|
|||||||
if (element.elementType != KtTokens.OBJECT_KEYWORD || element.getParentOfType<KtObjectDeclaration>(false)?.nameIdentifier == null)
|
if (element.elementType != KtTokens.OBJECT_KEYWORD || element.getParentOfType<KtObjectDeclaration>(false)?.nameIdentifier == null)
|
||||||
el<UIdentifier>(build(::KotlinUIdentifier))
|
el<UIdentifier>(build(::KotlinUIdentifier))
|
||||||
else null
|
else null
|
||||||
|
else if (element.elementType in KtTokens.OPERATIONS && element.parent is KtOperationReferenceExpression)
|
||||||
|
el<UIdentifier>(build(::KotlinUIdentifier))
|
||||||
else if (element.elementType == KtTokens.LBRACKET && element.parent is KtCollectionLiteralExpression)
|
else if (element.elementType == KtTokens.LBRACKET && element.parent is KtCollectionLiteralExpression)
|
||||||
el<UIdentifier> {
|
el<UIdentifier> {
|
||||||
UIdentifier(
|
UIdentifier(
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ class KotlinUBinaryExpression(
|
|||||||
override val rightOperand by lz { KotlinConverter.convertOrEmpty(psi.right, this) }
|
override val rightOperand by lz { KotlinConverter.convertOrEmpty(psi.right, this) }
|
||||||
|
|
||||||
override val operatorIdentifier: UIdentifier?
|
override val operatorIdentifier: UIdentifier?
|
||||||
get() = KotlinUIdentifier(psi.operationReference, this)
|
get() = KotlinUIdentifier(psi.operationReference.getReferencedNameElement(), this)
|
||||||
|
|
||||||
override fun resolveOperator() = psi.operationReference.resolveCallToDeclaration(context = this) as? PsiMethod
|
override fun resolveOperator() = psi.operationReference.resolveCallToDeclaration(context = this) as? PsiMethod
|
||||||
|
|
||||||
|
|||||||
@@ -38,12 +38,14 @@ constructor -> UAnnotationMethod (name = AWithSecondary)
|
|||||||
i -> UParameter (name = i)
|
i -> UParameter (name = i)
|
||||||
Int -> USimpleNameReferenceExpression (identifier = Int)
|
Int -> USimpleNameReferenceExpression (identifier = Int)
|
||||||
a -> USimpleNameReferenceExpression (identifier = a)
|
a -> USimpleNameReferenceExpression (identifier = a)
|
||||||
|
= -> USimpleNameReferenceExpression (identifier = =)
|
||||||
i -> USimpleNameReferenceExpression (identifier = i)
|
i -> USimpleNameReferenceExpression (identifier = i)
|
||||||
toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||||
constructor -> UAnnotationMethod (name = AWithSecondary)
|
constructor -> UAnnotationMethod (name = AWithSecondary)
|
||||||
s -> UParameter (name = s)
|
s -> UParameter (name = s)
|
||||||
String -> USimpleNameReferenceExpression (identifier = String)
|
String -> USimpleNameReferenceExpression (identifier = String)
|
||||||
a -> USimpleNameReferenceExpression (identifier = a)
|
a -> USimpleNameReferenceExpression (identifier = a)
|
||||||
|
= -> USimpleNameReferenceExpression (identifier = =)
|
||||||
s -> USimpleNameReferenceExpression (identifier = s)
|
s -> USimpleNameReferenceExpression (identifier = s)
|
||||||
AWithSecondaryInit -> UClass (name = AWithSecondaryInit)
|
AWithSecondaryInit -> UClass (name = AWithSecondaryInit)
|
||||||
a -> UField (name = a)
|
a -> UField (name = a)
|
||||||
@@ -53,12 +55,14 @@ constructor -> UAnnotationMethod (name = AWithSecondaryInit)
|
|||||||
i -> UParameter (name = i)
|
i -> UParameter (name = i)
|
||||||
Int -> USimpleNameReferenceExpression (identifier = Int)
|
Int -> USimpleNameReferenceExpression (identifier = Int)
|
||||||
a -> USimpleNameReferenceExpression (identifier = a)
|
a -> USimpleNameReferenceExpression (identifier = a)
|
||||||
|
= -> USimpleNameReferenceExpression (identifier = =)
|
||||||
i -> USimpleNameReferenceExpression (identifier = i)
|
i -> USimpleNameReferenceExpression (identifier = i)
|
||||||
toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||||
constructor -> UAnnotationMethod (name = AWithSecondaryInit)
|
constructor -> UAnnotationMethod (name = AWithSecondaryInit)
|
||||||
s -> UParameter (name = s)
|
s -> UParameter (name = s)
|
||||||
String -> USimpleNameReferenceExpression (identifier = String)
|
String -> USimpleNameReferenceExpression (identifier = String)
|
||||||
a -> USimpleNameReferenceExpression (identifier = a)
|
a -> USimpleNameReferenceExpression (identifier = a)
|
||||||
|
= -> USimpleNameReferenceExpression (identifier = =)
|
||||||
s -> USimpleNameReferenceExpression (identifier = s)
|
s -> USimpleNameReferenceExpression (identifier = s)
|
||||||
local -> ULocalVariable (name = local)
|
local -> ULocalVariable (name = local)
|
||||||
String -> USimpleNameReferenceExpression (identifier = String)
|
String -> USimpleNameReferenceExpression (identifier = String)
|
||||||
|
|||||||
@@ -11,4 +11,5 @@ Boolean -> USimpleNameReferenceExpression (identifier = Boolean)
|
|||||||
String -> USimpleNameReferenceExpression (identifier = String)
|
String -> USimpleNameReferenceExpression (identifier = String)
|
||||||
LocalObject -> UClass (name = LocalObject)
|
LocalObject -> UClass (name = LocalObject)
|
||||||
bar -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
bar -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||||
|
== -> USimpleNameReferenceExpression (identifier = ==)
|
||||||
Local -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0))
|
Local -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0))
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.jetbrains.uast.test.env.assertEqualsToFile
|
|||||||
import org.jetbrains.uast.visitor.AbstractUastVisitor
|
import org.jetbrains.uast.visitor.AbstractUastVisitor
|
||||||
import org.junit.ComparisonFailure
|
import org.junit.ComparisonFailure
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import kotlin.test.fail
|
||||||
|
|
||||||
interface IdentifiersTestBase {
|
interface IdentifiersTestBase {
|
||||||
fun getIdentifiersFile(testName: String): File
|
fun getIdentifiersFile(testName: String): File
|
||||||
@@ -42,22 +43,28 @@ interface IdentifiersTestBase {
|
|||||||
private fun UFile.testIdentifiersParents() {
|
private fun UFile.testIdentifiersParents() {
|
||||||
accept(object : AbstractUastVisitor() {
|
accept(object : AbstractUastVisitor() {
|
||||||
override fun visitElement(node: UElement): Boolean {
|
override fun visitElement(node: UElement): Boolean {
|
||||||
if (node is UAnchorOwner) {
|
val uIdentifier = when (node) {
|
||||||
val uastAnchor = node.uastAnchor ?: return false
|
is UAnchorOwner -> node.uastAnchor ?: return false
|
||||||
assertParents(node, uastAnchor)
|
is UBinaryExpression -> node.operatorIdentifier ?: return false
|
||||||
val uastAnchorFromSource = (uastAnchor.sourcePsi ?: return false).toUElementOfType<UIdentifier>()
|
else -> return false
|
||||||
assertParents(node, uastAnchorFromSource)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assertParents(node, uIdentifier)
|
||||||
|
val identifierSourcePsi = uIdentifier.sourcePsi ?: return false
|
||||||
|
val operatorIdentifierFromSource = identifierSourcePsi.toUElementOfType<UIdentifier>()
|
||||||
|
?: fail("$identifierSourcePsi of ${identifierSourcePsi.javaClass} should be convertable to UIdentifier")
|
||||||
|
assertParents(node, operatorIdentifierFromSource)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertParents(node: UAnchorOwner, uastAnchor: UIdentifier?) {
|
fun assertParents(node: UElement, uastAnchor: UIdentifier?) {
|
||||||
//skipping such elements because they are ambiguous (properties and getters for instance)
|
//skipping such elements because they are ambiguous (properties and getters for instance)
|
||||||
if (node.sourcePsi.toUElement() != node) return
|
if (node.sourcePsi.toUElement() != node) return
|
||||||
if (uastAnchor == null)
|
if (uastAnchor == null)
|
||||||
throw AssertionError("no uast anchor for ${node.uastAnchor?.sourcePsi}(${node.uastAnchor?.sourcePsi?.javaClass}) for node = $node")
|
throw AssertionError("no uast anchor for node = $node")
|
||||||
val nodeParents = node.withContainingElements.log()
|
val nodeParents = node.withContainingElements.log()
|
||||||
val anchorParentParents = uastAnchor.uastParent?.withContainingElements?.log() ?: ""
|
val anchorParentParents = uastAnchor.uastParent?.withContainingElements?.log() ?: ""
|
||||||
// dropping node itself because we allow children to share identifiers with parents (primary constructor for instance)
|
// dropping node itself because we allow children to share identifiers with parents (primary constructor for instance)
|
||||||
|
|||||||
Reference in New Issue
Block a user