Extensions PsiElement.getParentOfType with reified T

1. Renamed *ByType -> *OfType (as in PsiTreeUtil.java)
2. Introduced PsiElement.getStrictParentOfType and PsiElement.getNonStrictParentOfType
with reified TP
3. Replaced current usages of PsiTreeUtil.getParentOfType and current
extensions
4. Made reified version of PsiElement.getParentOfTypeAndBranch with
default strict value --- false (as it used)
This commit is contained in:
Denis Zharkov
2014-12-01 10:58:42 +03:00
parent 8b80daa2a1
commit b3bf8933df
53 changed files with 204 additions and 176 deletions
@@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.ImportPath
import org.jetbrains.jet.lang.psi.psiUtil.getQualifiedElement
import org.jetbrains.jet.lang.resolve.descriptorUtil.getImportableDescriptor
import org.jetbrains.jet.plugin.caches.resolve.ResolutionFacade
import org.jetbrains.jet.lang.psi.psiUtil.getStrictParentOfType
public object ShortenReferences {
public fun process(element: JetElement) {
@@ -192,7 +193,7 @@ public object ShortenReferences {
}
if (target == null) return false
val typeReference = PsiTreeUtil.getParentOfType(userType, javaClass<JetTypeReference>())!!
val typeReference = userType.getStrictParentOfType<JetTypeReference>()!!
val scope = resolutionFacade.analyze(typeReference)[BindingContext.TYPE_RESOLUTION_SCOPE, typeReference]!!
val name = target.getName()
val targetByName = scope.getClassifier(name)
@@ -19,10 +19,9 @@ package org.jetbrains.jet.plugin.findUsages
import com.intellij.psi.PsiElement
import org.jetbrains.jet.lang.psi.JetForExpression
import org.jetbrains.jet.lang.psi.JetMultiDeclaration
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
import org.jetbrains.jet.lang.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.jet.lang.psi.JetReferenceExpression
import org.jetbrains.jet.lang.psi.JetImportDirective
import org.jetbrains.jet.lang.psi.psiUtil.getParentByTypeAndBranch
import org.jetbrains.jet.lang.psi.JetCallableReferenceExpression
import org.jetbrains.jet.lang.psi.JetProperty
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
@@ -39,7 +38,7 @@ import org.jetbrains.jet.lexer.JetTokens
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression
import org.jetbrains.jet.lang.psi.JetSuperExpression
import org.jetbrains.jet.lang.psi.JetDelegatorByExpressionSpecifier
import org.jetbrains.jet.lang.psi.psiUtil.getParentByTypesAndPredicate
import org.jetbrains.jet.lang.psi.psiUtil.getParentOfTypesAndPredicate
import org.jetbrains.jet.lang.psi.JetBinaryExpression
import org.jetbrains.jet.lang.psi.JetPsiUtil
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
@@ -62,6 +61,7 @@ import com.intellij.psi.PsiPackage
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
import org.jetbrains.jet.plugin.findUsages.UsageTypeEnum.*
import org.jetbrains.jet.plugin.caches.resolve.analyze
import org.jetbrains.jet.lang.psi.psiUtil.getParentOfTypeAndBranch
public object UsageTypeUtils {
public fun getUsageType(element: PsiElement?): UsageTypeEnum? {
@@ -70,23 +70,23 @@ public object UsageTypeUtils {
is JetMultiDeclaration -> return READ
}
val refExpr = element?.getParentByType(javaClass<JetReferenceExpression>())
val refExpr = element?.getNonStrictParentOfType<JetReferenceExpression>()
if (refExpr == null) return null
val context = refExpr.analyze()
fun getCommonUsageType(): UsageTypeEnum? {
return when {
refExpr.getParentByType(javaClass<JetImportDirective>()) != null ->
refExpr.getNonStrictParentOfType<JetImportDirective>() != null ->
CLASS_IMPORT
refExpr.getParentByTypeAndBranch(javaClass<JetCallableReferenceExpression>()) { getCallableReference() } != null ->
refExpr.getParentOfTypeAndBranch<JetCallableReferenceExpression>(){ getCallableReference() } != null ->
CALLABLE_REFERENCE
else -> null
}
}
fun getClassUsageType(): UsageTypeEnum? {
val property = refExpr.getParentByType(javaClass<JetProperty>())
val property = refExpr.getNonStrictParentOfType<JetProperty>()
if (property != null) {
when {
property.getTypeReference().isAncestor(refExpr) ->
@@ -97,7 +97,7 @@ public object UsageTypeUtils {
}
}
val function = refExpr.getParentByType(javaClass<JetFunction>())
val function = refExpr.getNonStrictParentOfType<JetFunction>()
if (function != null) {
when {
function.getTypeReference().isAncestor(refExpr) ->
@@ -108,42 +108,42 @@ public object UsageTypeUtils {
}
return when {
refExpr.getParentByTypeAndBranch(javaClass<JetTypeParameter>()) { getExtendsBound() } != null
|| refExpr.getParentByTypeAndBranch(javaClass<JetTypeConstraint>()) { getBoundTypeReference() } != null ->
refExpr.getParentOfTypeAndBranch<JetTypeParameter>(){ getExtendsBound() } != null
|| refExpr.getParentOfTypeAndBranch<JetTypeConstraint>(){ getBoundTypeReference() } != null ->
TYPE_CONSTRAINT
refExpr is JetDelegationSpecifier
|| refExpr.getParentByTypeAndBranch(javaClass<JetDelegationSpecifier>()) { getTypeReference() } != null ->
|| refExpr.getParentOfTypeAndBranch<JetDelegationSpecifier>(){ getTypeReference() } != null ->
SUPER_TYPE
refExpr.getParentByTypeAndBranch(javaClass<JetTypedef>()) { getTypeReference() } != null ->
refExpr.getParentOfTypeAndBranch<JetTypedef>(){ getTypeReference() } != null ->
TYPE_DEFINITION
refExpr.getParentByType(javaClass<JetTypeProjection>()) != null ->
refExpr.getNonStrictParentOfType<JetTypeProjection>() != null ->
TYPE_PARAMETER
refExpr.getParentByTypeAndBranch(javaClass<JetParameter>()) { getTypeReference() } != null ->
refExpr.getParentOfTypeAndBranch<JetParameter>(){ getTypeReference() } != null ->
VALUE_PARAMETER_TYPE
refExpr.getParentByTypeAndBranch(javaClass<JetIsExpression>()) { getTypeReference() } != null ->
refExpr.getParentOfTypeAndBranch<JetIsExpression>(){ getTypeReference() } != null ->
IS
with(refExpr.getParentByTypeAndBranch(javaClass<JetBinaryExpressionWithTypeRHS>()) { getRight() }) {
with(refExpr.getParentOfTypeAndBranch<JetBinaryExpressionWithTypeRHS>(){ getRight() }) {
val opType = this?.getOperationReference()?.getReferencedNameElementType()
opType == JetTokens.AS_KEYWORD || opType == JetTokens.AS_SAFE
} ->
CLASS_CAST_TO
with(refExpr.getParentByType(javaClass<JetDotQualifiedExpression>())) {
with(refExpr.getNonStrictParentOfType<JetDotQualifiedExpression>()) {
if (this == null) false
else if (getReceiverExpression() == refExpr) true
else
getSelectorExpression() == refExpr
&& getParentByTypeAndBranch(javaClass<JetDotQualifiedExpression>(), true) { getReceiverExpression() } != null
&& getParentOfTypeAndBranch<JetDotQualifiedExpression>(strict = true) { getReceiverExpression() } != null
} ->
CLASS_OBJECT_ACCESS
refExpr.getParentByTypeAndBranch(javaClass<JetSuperExpression>()) { getSuperTypeQualifier() } != null ->
refExpr.getParentOfTypeAndBranch<JetSuperExpression>(){ getSuperTypeQualifier() } != null ->
SUPER_TYPE_QUALIFIER
else -> null
@@ -151,11 +151,11 @@ public object UsageTypeUtils {
}
fun getVariableUsageType(): UsageTypeEnum? {
if (refExpr.getParentByTypeAndBranch(javaClass<JetDelegatorByExpressionSpecifier>()) { getDelegateExpression() } != null) {
if (refExpr.getParentOfTypeAndBranch<JetDelegatorByExpressionSpecifier>(){ getDelegateExpression() } != null) {
return DELEGATE
}
val dotQualifiedExpression = refExpr.getParentByType(javaClass<JetDotQualifiedExpression>())
val dotQualifiedExpression = refExpr.getNonStrictParentOfType<JetDotQualifiedExpression>()
if (dotQualifiedExpression != null) {
val parent = dotQualifiedExpression.getParent()
@@ -169,11 +169,11 @@ public object UsageTypeUtils {
}
return when {
(refExpr.getParentByTypesAndPredicate(false, javaClass<JetBinaryExpression>()) { JetPsiUtil.isAssignment(it) })
(refExpr.getParentOfTypesAndPredicate(false, javaClass<JetBinaryExpression>()) { JetPsiUtil.isAssignment(it) })
?.getLeft().isAncestor(refExpr) ->
WRITE
refExpr.getParentByType(javaClass<JetSimpleNameExpression>()) != null ->
refExpr.getNonStrictParentOfType<JetSimpleNameExpression>() != null ->
READ
else -> null
@@ -194,21 +194,21 @@ public object UsageTypeUtils {
}
return when {
refExpr.getParentByTypeAndBranch(javaClass<JetDelegationSpecifier>()) { getTypeReference() } != null ->
refExpr.getParentOfTypeAndBranch<JetDelegationSpecifier>(){ getTypeReference() } != null ->
SUPER_TYPE
descriptor is ConstructorDescriptor
&& refExpr.getParentByTypeAndBranch(javaClass<JetAnnotationEntry>()) { getTypeReference() } != null ->
&& refExpr.getParentOfTypeAndBranch<JetAnnotationEntry>(){ getTypeReference() } != null ->
ANNOTATION
with(refExpr.getParentByTypeAndBranch(javaClass<JetCallExpression>()) { getCalleeExpression() }) {
with(refExpr.getParentOfTypeAndBranch<JetCallExpression>(){ getCalleeExpression() }) {
this?.getCalleeExpression() is JetSimpleNameExpression
} ->
if (descriptor is ConstructorDescriptor) CLASS_NEW_OPERATOR else FUNCTION_CALL
refExpr.getParentByTypeAndBranch(javaClass<JetBinaryExpression>()) { getOperationReference() } != null,
refExpr.getParentByTypeAndBranch(javaClass<JetUnaryExpression>()) { getOperationReference() } != null,
refExpr.getParentByTypeAndBranch(javaClass<JetWhenConditionInRange>()) { getOperationReference() } != null ->
refExpr.getParentOfTypeAndBranch<JetBinaryExpression>(){ getOperationReference() } != null,
refExpr.getParentOfTypeAndBranch<JetUnaryExpression>(){ getOperationReference() } != null,
refExpr.getParentOfTypeAndBranch<JetWhenConditionInRange>(){ getOperationReference() } != null ->
FUNCTION_CALL
else -> null
@@ -217,8 +217,8 @@ public object UsageTypeUtils {
fun getPackageUsageType(): UsageTypeEnum? {
return when {
refExpr.getParentByType(javaClass<JetPackageDirective>()) != null -> PACKAGE_DIRECTIVE
refExpr.getParentByType(javaClass<JetQualifiedExpression>()) != null -> PACKAGE_MEMBER_ACCESS
refExpr.getNonStrictParentOfType<JetPackageDirective>() != null -> PACKAGE_DIRECTIVE
refExpr.getNonStrictParentOfType<JetQualifiedExpression>() != null -> PACKAGE_MEMBER_ACCESS
else -> getClassUsageType()
}
}
@@ -25,7 +25,7 @@ import org.jetbrains.jet.plugin.quickfix.KotlinSuppressIntentionAction
import org.jetbrains.jet.lang.psi.*
import org.jetbrains.jet.plugin.quickfix.AnnotationHostKind
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.jet.lang.psi.psiUtil.getStrictParentOfType
class KotlinSuppressableWarningProblemGroup(
private val diagnosticFactory: DiagnosticFactory<*>
@@ -86,7 +86,7 @@ private object DeclarationKindDetector : JetVisitor<AnnotationHostKind?, Unit?>(
override fun visitClass(d: JetClass, _: Unit?) = detect(d, if (d.isTrait()) "trait" else "class")
override fun visitClassObject(d: JetClassObject, _: Unit?) = detect(d, "class object",
name = "of " + PsiTreeUtil.getParentOfType(d, javaClass<JetClass>())?.getName())
name = "of " + d.getStrictParentOfType<JetClass>()?.getName())
override fun visitNamedFunction(d: JetNamedFunction, _: Unit?) = detect(d, "fun")
@@ -21,7 +21,7 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import org.jetbrains.jet.lang.psi.JetElement
import org.jetbrains.jet.plugin.JetBundle
import org.jetbrains.jet.lang.psi.psiUtil.getParentByTypesAndPredicate
import org.jetbrains.jet.lang.psi.psiUtil.getParentOfTypesAndPredicate
import com.intellij.codeInsight.intention.IntentionAction
public abstract class JetSelfTargetingIntention<T: JetElement>(protected val key: String, val elementType: Class<T>) : IntentionAction {
@@ -37,7 +37,7 @@ public abstract class JetSelfTargetingIntention<T: JetElement>(protected val key
protected fun getTarget(editor: Editor, file: PsiFile): T? {
val offset = editor.getCaretModel().getOffset()
return file.findElementAt(offset)?.getParentByTypesAndPredicate(false, elementType) { element -> isApplicableTo(element, editor) }
return file.findElementAt(offset)?.getParentOfTypesAndPredicate(false, elementType) { element -> isApplicableTo(element, editor) }
}
public override fun getFamilyName(): String {
@@ -17,13 +17,13 @@
package org.jetbrains.jet.plugin.references
import com.intellij.openapi.util.TextRange
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
import org.jetbrains.jet.lang.psi.JetProperty
import org.jetbrains.jet.lang.psi.JetPropertyDelegate
import org.jetbrains.jet.lang.resolve.BindingContext
import java.util.Collections
import org.jetbrains.jet.lang.psi.psiUtil.getStrictParentOfType
public class JetPropertyDelegationMethodsReference(element: JetPropertyDelegate) : JetMultiReference<JetPropertyDelegate>(element) {
@@ -34,7 +34,7 @@ public class JetPropertyDelegationMethodsReference(element: JetPropertyDelegate)
}
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
val property = PsiTreeUtil.getParentOfType(expression, javaClass<JetProperty>())
val property = expression.getStrictParentOfType<JetProperty>()
if (property == null) {
return Collections.emptyList()
}
@@ -33,10 +33,10 @@ import org.jetbrains.jet.lexer.JetToken
import org.jetbrains.jet.plugin.intentions.OperatorToFunctionIntention
import org.jetbrains.jet.lang.resolve.BindingContext
import com.intellij.util.IncorrectOperationException
import org.jetbrains.jet.lang.psi.psiUtil.getParentByTypeAndBranch
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.dataClassUtils.isComponentLike
import org.jetbrains.jet.plugin.caches.resolve.analyze
import org.jetbrains.jet.lang.psi.psiUtil.getParentOfTypeAndBranch
public class JetSimpleNameReference(
jetSimpleNameExpression: JetSimpleNameExpression
@@ -45,7 +45,7 @@ public class JetSimpleNameReference(
override fun getRangeInElement(): TextRange = TextRange(0, getElement().getTextLength())
override fun canRename(): Boolean {
if (expression.getParentByTypeAndBranch(javaClass<JetWhenConditionInRange>()) { getOperationReference() } != null) return false
if (expression.getParentOfTypeAndBranch<JetWhenConditionInRange>(strict = true){ getOperationReference() } != null) return false
val elementType = expression.getReferencedNameElementType()
if (elementType == JetTokens.PLUSPLUS || elementType == JetTokens.MINUSMINUS) return false
@@ -21,18 +21,19 @@ import com.intellij.psi.PsiElement
import org.jetbrains.jet.asJava.unwrapped
import com.intellij.psi.PsiMethod
import org.jetbrains.jet.lang.psi.JetPropertyAccessor
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
import org.jetbrains.jet.lang.psi.JetProperty
import java.util.HashSet
import org.jetbrains.jet.lang.psi.JetExpression
import org.jetbrains.jet.plugin.intentions.OperatorToFunctionIntention
import org.jetbrains.jet.lang.psi.JetQualifiedExpression
import org.jetbrains.jet.lang.psi.JetCallExpression
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.jet.lang.psi.JetObjectDeclaration
import org.jetbrains.jet.lang.psi.JetClass
import com.intellij.psi.PsiPolyVariantReference
import org.jetbrains.jet.utils.emptyOrSingletonList
import org.jetbrains.jet.lang.psi.psiUtil.getParentOfType
import org.jetbrains.jet.lang.psi.psiUtil.getStrictParentOfType
import org.jetbrains.jet.lang.psi.psiUtil.getNonStrictParentOfType
// Navigation element of the resolved reference
// For property accessor return enclosing property
@@ -42,8 +43,8 @@ public val PsiReference.unwrappedTargets: Set<PsiElement>
fun PsiElement.adjust(): PsiElement? {
val target = unwrapped
return when {
target is JetPropertyAccessor -> target.getParentByType(javaClass<JetProperty>())
target is JetObjectDeclaration && target.isClassObject() -> target.getParentByType(javaClass<JetClass>())
target is JetPropertyAccessor -> target.getNonStrictParentOfType<JetProperty>()
target is JetObjectDeclaration && target.isClassObject() -> target.getNonStrictParentOfType<JetClass>()
else -> target
}
}
@@ -74,5 +75,5 @@ fun AbstractJetReference<out JetExpression>.renameImplicitConventionalCall(newNa
val expr = OperatorToFunctionIntention.convert(expression) as JetQualifiedExpression
val newCallee = (expr.getSelectorExpression() as JetCallExpression).getCalleeExpression()!!.getReference()!!.handleElementRename(newName)
return PsiTreeUtil.getParentOfType<JetQualifiedExpression>(newCallee, javaClass<JetQualifiedExpression>()) as JetExpression
return newCallee.getStrictParentOfType<JetQualifiedExpression>() as JetExpression
}
@@ -54,16 +54,16 @@ fun PsiReference.checkUsageVsOriginalDescriptor(
}
fun PsiReference.isImportUsage(): Boolean =
getElement()!!.getParentByType(javaClass<JetImportDirective>()) != null
getElement()!!.getNonStrictParentOfType<JetImportDirective>() != null
fun PsiReference.isConstructorUsage(jetClassOrObject: JetClassOrObject): Boolean = with (getElement()!!) {
fun getCallDescriptor(bindingContext: BindingContext): DeclarationDescriptor? {
val constructorCalleeExpression = getParentByType(javaClass<JetConstructorCalleeExpression>())
val constructorCalleeExpression = getNonStrictParentOfType<JetConstructorCalleeExpression>()
if (constructorCalleeExpression != null) {
return bindingContext.get(BindingContext.REFERENCE_TARGET, constructorCalleeExpression.getConstructorReferenceExpression())
}
val callExpression = getParentByType(javaClass<JetCallExpression>())
val callExpression = getNonStrictParentOfType<JetCallExpression>()
if (callExpression != null) {
val callee = callExpression.getCalleeExpression()
if (callee is JetReferenceExpression) {
@@ -75,7 +75,7 @@ fun PsiReference.isConstructorUsage(jetClassOrObject: JetClassOrObject): Boolean
}
fun checkJavaUsage(): Boolean {
val call = getParentByType(javaClass<PsiConstructorCall>())
val call = getNonStrictParentOfType<PsiConstructorCall>()
return call == getParent() && call?.resolveConstructor()?.getContainingClass()?.getNavigationElement() == jetClassOrObject
}
@@ -142,7 +142,7 @@ fun PsiReference.isPropertyReadOnlyUsage(): Boolean {
if (refTarget is KotlinLightMethod) {
val origin = refTarget.origin
val declaration: JetNamedDeclaration? = when (origin) {
is JetPropertyAccessor -> origin.getParentByType(javaClass<JetProperty>())
is JetPropertyAccessor -> origin.getNonStrictParentOfType<JetProperty>()
is JetProperty, is JetParameter -> origin as JetNamedDeclaration
else -> null
}