mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
getting rid of ULiteralExpression to make it possible to work in both supporting and not supporting UInjectionHost Uast-plugins
This commit is contained in:
@@ -35,6 +35,8 @@ fun injectionHostUExpression(strict: Boolean = true): UExpressionPattern<UExpres
|
||||
return@filterWithContext requestedPsi is PsiLanguageInjectionHost
|
||||
}
|
||||
|
||||
fun injectionHostOrReferenceExpression(): UExpressionPattern.Capture<UExpression> =
|
||||
uExpression().filter { it is UReferenceExpression || it.isInjectionHost() }
|
||||
|
||||
fun callExpression(): UCallExpressionPattern = UCallExpressionPattern()
|
||||
|
||||
@@ -94,12 +96,12 @@ open class UElementPattern<T : UElement, Self : UElementPattern<T, Self>>(clazz:
|
||||
|
||||
private val constructorOrMethodCall = setOf(UastCallKind.CONSTRUCTOR_CALL, UastCallKind.METHOD_CALL)
|
||||
|
||||
private fun isCallExpressionParameter(argumentExpression: UElement,
|
||||
private fun isCallExpressionParameter(argumentExpression: UExpression,
|
||||
parameterIndex: Int,
|
||||
callPattern: ElementPattern<UCallExpression>): Boolean {
|
||||
val call = argumentExpression.uastParent.getUCallExpression(searchLimit = 2) as? UCallExpressionEx ?: return false
|
||||
if (call.kind !in constructorOrMethodCall) return false
|
||||
return call.getArgumentForParameter(parameterIndex) == argumentExpression && callPattern.accepts(call)
|
||||
return call.getArgumentForParameter(parameterIndex) == unwrapPolyadic(argumentExpression) && callPattern.accepts(call)
|
||||
}
|
||||
|
||||
private val GUARD = RecursionManager.createGuard("isPropertyAssignCall")
|
||||
@@ -128,11 +130,13 @@ class UCallExpressionPattern : UElementPattern<UCallExpression, UCallExpressionP
|
||||
|
||||
fun withMethodName(methodName : String): UCallExpressionPattern = withMethodName(string().equalTo(methodName))
|
||||
|
||||
fun withAnyResolvedMethod(method: ElementPattern<out PsiMethod>): UCallExpressionPattern = filter { uCallExpression ->
|
||||
when (uCallExpression) {
|
||||
is UMultiResolvable -> uCallExpression.multiResolve().any { method.accepts(it.element) }
|
||||
else -> uCallExpression.resolve().let { method.accepts(it) }
|
||||
}
|
||||
fun withAnyResolvedMethod(method: ElementPattern<out PsiMethod>): UCallExpressionPattern = withResolvedMethod(method, true)
|
||||
|
||||
fun withResolvedMethod(method: ElementPattern<out PsiMethod>, multiResolve: Boolean): UCallExpressionPattern = filter { uCallExpression ->
|
||||
if (multiResolve && uCallExpression is UMultiResolvable)
|
||||
uCallExpression.multiResolve().any { method.accepts(it.element) }
|
||||
else
|
||||
uCallExpression.resolve().let { method.accepts(it) }
|
||||
}
|
||||
|
||||
fun withMethodName(namePattern: ElementPattern<String>): UCallExpressionPattern = filter { it.methodName?.let { namePattern.accepts(it) } ?: false }
|
||||
@@ -186,11 +190,12 @@ open class UExpressionPattern<T : UExpression, Self : UExpressionPattern<T, Self
|
||||
isCallExpressionParameter(it, 0, callExpression().withAnyResolvedMethod(methodPattern))
|
||||
}
|
||||
|
||||
override fun methodCallParameter(parameterIndex: Int, methodPattern: ElementPattern<out PsiMethod>): Self =
|
||||
callParameter(parameterIndex, callExpression().withAnyResolvedMethod(methodPattern))
|
||||
@JvmOverloads
|
||||
fun methodCallParameter(parameterIndex: Int, methodPattern: ElementPattern<out PsiMethod>, multiResolve: Boolean = true): Self =
|
||||
callParameter(parameterIndex, callExpression().withResolvedMethod(methodPattern, multiResolve))
|
||||
|
||||
override fun arrayAccessParameterOf(receiverClassPattern: ElementPattern<PsiClass>): Self = filter { self ->
|
||||
val aae: UArrayAccessExpression = self.uastParent as? UArrayAccessExpression ?: return@filter false
|
||||
val aae: UArrayAccessExpression = unwrapPolyadic(self).uastParent as? UArrayAccessExpression ?: return@filter false
|
||||
val receiverClass = (aae.receiver.getExpressionType() as? PsiClassType)?.resolve() ?: return@filter false
|
||||
receiverClassPattern.accepts(receiverClass)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ package org.jetbrains.uast
|
||||
import com.intellij.psi.PsiLanguageInjectionHost
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.uast.expressions.UInjectionHost
|
||||
|
||||
/**
|
||||
* Checks if the [UElement] is a null literal.
|
||||
@@ -54,13 +56,22 @@ fun UElement.isFalseLiteral(): Boolean = this is ULiteralExpression && this.isBo
|
||||
*
|
||||
* @return true if the receiver is a [String] literal, false otherwise.
|
||||
*/
|
||||
@Deprecated("doesn't support UInjectionHost, most probably it is not what you want", ReplaceWith("isInjectionHost()"))
|
||||
fun UElement.isStringLiteral(): Boolean = this is ULiteralExpression && this.isString
|
||||
|
||||
/**
|
||||
* Checks if the [UElement] is a [PsiLanguageInjectionHost] holder.
|
||||
*
|
||||
* NOTE: It is a transitional function until everything will migrate to [UInjectionHost]
|
||||
*/
|
||||
fun UElement?.isInjectionHost(): Boolean = this is UInjectionHost || (this is UExpression && this.sourceInjectionHost != null)
|
||||
|
||||
/**
|
||||
* Returns the [String] literal value.
|
||||
*
|
||||
* @return literal text if the receiver is a valid [String] literal, null otherwise.
|
||||
*/
|
||||
@Deprecated("doesn't support UInjectionHost, most probably it is not what you want", ReplaceWith("UExpression.evaluateString()"))
|
||||
fun UElement.getValueIfStringLiteral(): String? =
|
||||
if (isStringLiteral()) (this as ULiteralExpression).value as String else null
|
||||
|
||||
@@ -126,6 +137,17 @@ val UExpression.sourceInjectionHost: PsiLanguageInjectionHost?
|
||||
val ULiteralExpression.psiLanguageInjectionHost: PsiLanguageInjectionHost?
|
||||
get() = this.psi?.let { PsiTreeUtil.getParentOfType(it, PsiLanguageInjectionHost::class.java, false) }
|
||||
|
||||
// Workaround until everything will migrate to `UInjectionHost` from `ULiteralExpression`, see KT-27283
|
||||
@ApiStatus.Experimental
|
||||
fun unwrapPolyadic(uElement: UExpression): UExpression {
|
||||
if (uElement is ULiteralExpression) {
|
||||
val parent = uElement.uastParent
|
||||
if (parent is UPolyadicExpression)
|
||||
return parent
|
||||
}
|
||||
return uElement
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all references injected into this [ULiteralExpression]
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user