blob: 7342e96758f0bd35fc49f2d6867acd86990765e7 [file] [log] [blame]
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;
}
}