diff options
Diffstat (limited to 'java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ExprTypePredicate.java')
-rw-r--r-- | java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ExprTypePredicate.java | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ExprTypePredicate.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ExprTypePredicate.java new file mode 100644 index 000000000000..d66db76c272d --- /dev/null +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ExprTypePredicate.java @@ -0,0 +1,95 @@ +package com.intellij.structuralsearch.impl.matcher.predicates; + +import com.intellij.psi.*; +import com.intellij.structuralsearch.impl.matcher.MatchContext; +import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate; +import com.intellij.structuralsearch.impl.matcher.iterators.HierarchyNodeIterator; +import com.intellij.dupLocator.iterators.NodeIterator; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Mar 23, 2004 + * Time: 6:37:15 PM + * To change this template use File | Settings | File Templates. + */ +public class ExprTypePredicate extends MatchPredicate { + private final RegExpPredicate delegate; + private final boolean withinHierarchy; + + public ExprTypePredicate(String type, String baseName, boolean _withinHierarchy, boolean caseSensitiveMatch,boolean target) { + delegate = new RegExpPredicate(type,caseSensitiveMatch,baseName,false,target); + withinHierarchy = _withinHierarchy; + } + + public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) { + return match(patternNode, matchedNode, 0, -1, context); + } + + public boolean match(PsiElement node, PsiElement match, int start, int end, MatchContext context) { + if (match instanceof PsiIdentifier) { + // since we pickup tokens + match = match.getParent(); + } + + if (match instanceof PsiExpression) { + final PsiType type = evalType((PsiExpression)match,context); + if (type==null) return false; + + return doMatchWithTheType(type, context, match); + } else { + return false; + } + } + + protected PsiType evalType(PsiExpression match, MatchContext context) { + PsiType type = null; + + if (match instanceof PsiReferenceExpression && + match.getParent() instanceof PsiMethodCallExpression) { + PsiMethod method = ((PsiMethodCallExpression)match.getParent()).resolveMethod(); + if (method!=null) type = method.getReturnType(); + } + + if (type==null) type = match.getType(); + return type; + } + + private boolean doMatchWithTheType(final PsiType type, MatchContext context, PsiElement matchedNode) { + if (type instanceof PsiClassType) { + PsiClass clazz = ((PsiClassType)type).resolve(); + + if (clazz!=null) return checkClass(clazz, context); + } + + if (type!=null) { + final String presentableText = type.getPresentableText(); + boolean result = delegate.doMatch(presentableText,context, matchedNode); + + if (!result && type instanceof PsiArrayType && ((PsiArrayType)type).getComponentType() instanceof PsiClassType) { + PsiClass clazz = ((PsiClassType)((PsiArrayType)type).getComponentType()).resolve(); + + if (clazz!=null) { // presentable text for array is not qualified! + result = delegate.doMatch(clazz.getQualifiedName()+"[]",context, matchedNode); + } + } + return result; + } else { + return false; + } + } + + public boolean checkClass(PsiClass clazz, MatchContext context) { + if (withinHierarchy) { + final NodeIterator parents = new HierarchyNodeIterator(clazz,true,true); + + while(parents.hasNext() && !delegate.match(null,parents.current(),context)) { + parents.advance(); + } + + return parents.hasNext(); + } else { + return delegate.match(null,clazz,context); + } + } +} |