| package com.intellij.structuralsearch.impl.matcher.handlers; |
| |
| import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator; |
| import com.intellij.dupLocator.iterators.CountingNodeIterator; |
| import com.intellij.psi.*; |
| import com.intellij.structuralsearch.impl.matcher.GlobalMatchingVisitor; |
| import com.intellij.structuralsearch.impl.matcher.MatchContext; |
| import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator; |
| |
| /** |
| * Created by IntelliJ IDEA. |
| * User: maxim |
| * Date: 31.12.2004 |
| * Time: 12:01:29 |
| * To change this template use File | Settings | File Templates. |
| */ |
| public class DeclarationStatementHandler extends MatchingHandler { |
| private MatchingHandler myCommentHandler; |
| |
| public boolean match(PsiElement patternNode,PsiElement matchedNode, MatchContext context) { |
| if (patternNode instanceof PsiComment) { |
| //if (matchedNode instanceof PsiComment || matchedNode instanceof PsiClass || matchedNode instanceof PsiField) |
| return myCommentHandler.match(patternNode, matchedNode, context); |
| //return false; |
| } |
| |
| if (!super.match(patternNode,matchedNode,context)) return false; |
| boolean result; |
| PsiDeclarationStatement dcl = (PsiDeclarationStatement)patternNode; |
| |
| if (matchedNode instanceof PsiDeclarationStatement) { |
| result = GlobalMatchingVisitor.continueMatchingSequentially( |
| new SsrFilteringNodeIterator(patternNode.getFirstChild()), |
| new SsrFilteringNodeIterator(matchedNode.getFirstChild()), |
| context |
| ); |
| } else { |
| final PsiElement[] declared = dcl.getDeclaredElements(); |
| |
| // declaration statement could wrap class or dcl |
| if (declared.length >0 && |
| ( ( declared[0] instanceof PsiVariable && matchedNode instanceof PsiVariable) || |
| ( declared[0] instanceof PsiClass && matchedNode instanceof PsiClass) |
| ) && |
| !(matchedNode.getParent() instanceof PsiDeclarationStatement) // skip twice matching for child |
| ) { |
| result = GlobalMatchingVisitor.continueMatchingSequentially( |
| new ArrayBackedNodeIterator(declared), |
| new CountingNodeIterator( |
| declared.length, |
| new SsrFilteringNodeIterator(matchedNode) |
| ), |
| context |
| ); |
| |
| if (result && |
| declared[0] instanceof PsiVariable && matchedNode instanceof PsiField |
| ) { |
| // we may have comments behind to match! |
| final PsiElement[] children = dcl.getChildren(); |
| |
| final PsiElement lastChild = children[children.length - 1]; |
| if (lastChild instanceof PsiComment) { |
| final PsiElement[] fieldChildren = matchedNode.getChildren(); |
| |
| result = context.getPattern().getHandler(lastChild).match( |
| lastChild, |
| fieldChildren[fieldChildren.length-1], |
| context |
| ); |
| } |
| } |
| } else { |
| result = false; |
| } |
| } |
| |
| return result; |
| } |
| |
| public boolean shouldAdvanceTheMatchFor(PsiElement patternElement, PsiElement matchedElement) { |
| if (patternElement instanceof PsiComment && |
| ( matchedElement instanceof PsiField || |
| matchedElement instanceof PsiClass |
| ) |
| ) { |
| return false; |
| } |
| |
| return super.shouldAdvanceTheMatchFor(patternElement,matchedElement); |
| } |
| |
| public void setCommentHandler(final MatchingHandler commentHandler) { |
| myCommentHandler = commentHandler; |
| } |
| } |