use of com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler in project intellij-community by JetBrains.
the class JavaMatchingVisitor method visitTypeParameter.
@Override
public void visitTypeParameter(PsiTypeParameter psiTypeParameter) {
final PsiTypeParameter parameter = (PsiTypeParameter) myMatchingVisitor.getElement();
final PsiIdentifier identifier = psiTypeParameter.getNameIdentifier();
final PsiIdentifier identifier2 = parameter.getNameIdentifier();
final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(identifier);
if (handler instanceof SubstitutionHandler) {
myMatchingVisitor.setResult(((SubstitutionHandler) handler).handle(identifier2, myMatchingVisitor.getMatchContext()));
} else {
myMatchingVisitor.setResult(myMatchingVisitor.matchText(identifier, identifier2));
}
if (myMatchingVisitor.getResult()) {
myMatchingVisitor.setResult(matchInAnyOrder(psiTypeParameter.getExtendsList(), parameter.getExtendsList()));
}
if (myMatchingVisitor.getResult()) {
myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(psiTypeParameter.getAnnotations(), parameter.getAnnotations()));
}
}
use of com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler in project intellij-community by JetBrains.
the class JavaMatchingVisitor method compareClasses.
private boolean compareClasses(final PsiClass clazz, final PsiClass clazz2) {
final PsiClass saveClazz = this.myClazz;
final MatchContext.MatchedElementsListener oldListener = myMatchingVisitor.getMatchContext().getMatchedElementsListener();
this.myClazz = clazz2;
final CompiledPattern pattern = myMatchingVisitor.getMatchContext().getPattern();
assert pattern instanceof JavaCompiledPattern;
final JavaCompiledPattern javaPattern = (JavaCompiledPattern) pattern;
MatchContext.MatchedElementsListener listener = new MatchContext.MatchedElementsListener() {
private Set<PsiElement> myMatchedElements;
@Override
public void matchedElements(Collection<PsiElement> matchedElements) {
if (matchedElements == null)
return;
if (myMatchedElements == null) {
myMatchedElements = new HashSet<>(matchedElements);
} else {
myMatchedElements.addAll(matchedElements);
}
}
@Override
public void commitUnmatched() {
final List<PsiMember> members = PsiTreeUtil.getChildrenOfTypeAsList(clazz2, PsiMember.class);
final List<PsiMember> unmatchedElements = ContainerUtil.filter(members, a -> myMatchedElements == null || !myMatchedElements.contains(a));
MatchingHandler unmatchedSubstitutionHandler = null;
for (PsiElement element = clazz.getFirstChild(); element != null; element = element.getNextSibling()) {
if (element instanceof PsiTypeElement && element.getNextSibling() instanceof PsiErrorElement) {
unmatchedSubstitutionHandler = pattern.getHandler(element);
break;
}
}
if (unmatchedSubstitutionHandler instanceof SubstitutionHandler) {
final SubstitutionHandler handler = (SubstitutionHandler) unmatchedSubstitutionHandler;
for (PsiMember element : unmatchedElements) {
handler.handle(element, myMatchingVisitor.getMatchContext());
}
} else {
clazz2.putUserData(GlobalMatchingVisitor.UNMATCHED_ELEMENTS_KEY, unmatchedElements);
}
}
};
myMatchingVisitor.getMatchContext().setMatchedElementsListener(listener);
boolean result = false;
try {
final boolean templateIsInterface = clazz.isInterface();
if (templateIsInterface != clazz2.isInterface())
return false;
if (templateIsInterface && clazz.isAnnotationType() && !clazz2.isAnnotationType())
return false;
if (clazz.isEnum() && !clazz2.isEnum())
return false;
if (!matchInAnyOrder(clazz.getExtendsList(), clazz2.getExtendsList())) {
return false;
}
// check if implements is in extended classes implements
final PsiReferenceList implementsList = clazz.getImplementsList();
if (implementsList != null) {
if (!matchInAnyOrder(implementsList, clazz2.getImplementsList())) {
final PsiReferenceList anotherExtendsList = clazz2.getExtendsList();
final PsiJavaCodeReferenceElement[] referenceElements = implementsList.getReferenceElements();
boolean accepted = false;
if (referenceElements.length > 0 && anotherExtendsList != null) {
final HierarchyNodeIterator iterator = new HierarchyNodeIterator(clazz2, true, true, false);
accepted = myMatchingVisitor.matchInAnyOrder(new ArrayBackedNodeIterator(referenceElements), iterator);
}
if (!accepted)
return false;
}
}
final PsiField[] fields = clazz.getFields();
if (fields.length > 0) {
final PsiField[] fields2 = javaPattern.isRequestsSuperFields() ? clazz2.getAllFields() : clazz2.getFields();
if (!myMatchingVisitor.matchInAnyOrder(fields, fields2)) {
return false;
}
}
final PsiMethod[] methods = clazz.getMethods();
if (methods.length > 0) {
final PsiMethod[] methods2 = javaPattern.isRequestsSuperMethods() ? clazz2.getAllMethods() : clazz2.getMethods();
if (!myMatchingVisitor.matchInAnyOrder(methods, methods2)) {
return false;
}
}
final PsiClass[] nestedClasses = clazz.getInnerClasses();
if (nestedClasses.length > 0) {
final PsiClass[] nestedClasses2 = javaPattern.isRequestsSuperInners() ? clazz2.getAllInnerClasses() : clazz2.getInnerClasses();
if (!myMatchingVisitor.matchInAnyOrder(nestedClasses, nestedClasses2)) {
return false;
}
}
final PsiClassInitializer[] initializers = clazz.getInitializers();
if (initializers.length > 0) {
final PsiClassInitializer[] initializers2 = clazz2.getInitializers();
if (!myMatchingVisitor.matchInAnyOrder(initializers, initializers2)) {
return false;
}
}
result = true;
return true;
} finally {
if (result)
listener.commitUnmatched();
this.myClazz = saveClazz;
myMatchingVisitor.getMatchContext().setMatchedElementsListener(oldListener);
}
}
use of com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler in project intellij-community by JetBrains.
the class JavaMatchingVisitor method visitLiteralExpression.
@Override
public void visitLiteralExpression(final PsiLiteralExpression const1) {
final PsiLiteralExpression const2 = (PsiLiteralExpression) myMatchingVisitor.getElement();
final MatchingHandler handler = (MatchingHandler) const1.getUserData(CompiledPattern.HANDLER_KEY);
if (handler instanceof SubstitutionHandler) {
final PsiType type1 = const1.getType();
if (type1 != null && !type1.equals(const2.getType())) {
myMatchingVisitor.setResult(false);
} else {
int offset = 0;
int length = const2.getTextLength();
final String text = const2.getText();
if (length > 2 && text.charAt(0) == '"' && text.charAt(length - 1) == '"') {
length--;
offset++;
}
myMatchingVisitor.setResult(((SubstitutionHandler) handler).handle(const2, offset, length, myMatchingVisitor.getMatchContext()));
}
} else if (handler != null) {
myMatchingVisitor.setResult(handler.match(const1, const2, myMatchingVisitor.getMatchContext()));
} else {
myMatchingVisitor.setResult(myMatchingVisitor.matchText(const1, const2));
}
}
use of com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler in project intellij-community by JetBrains.
the class JavaMatchingVisitor method visitMethodCallExpression.
@Override
public void visitMethodCallExpression(final PsiMethodCallExpression mcall) {
final PsiElement element = myMatchingVisitor.getElement();
if (!(element instanceof PsiMethodCallExpression)) {
myMatchingVisitor.setResult(false);
return;
}
final PsiMethodCallExpression mcall2 = (PsiMethodCallExpression) element;
final PsiReferenceExpression mcallRef1 = mcall.getMethodExpression();
final PsiReferenceExpression mcallRef2 = mcall2.getMethodExpression();
final PsiElement patternMethodName = mcallRef1.getReferenceNameElement();
final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(patternMethodName);
if (!isTypedVar && !myMatchingVisitor.matchText(patternMethodName, mcallRef2.getReferenceNameElement())) {
myMatchingVisitor.setResult(false);
return;
}
final PsiExpression patternQualifier = mcallRef1.getQualifierExpression();
final PsiExpression matchedQualifier = mcallRef2.getQualifierExpression();
if (patternQualifier != null) {
if (matchedQualifier != null) {
myMatchingVisitor.setResult(myMatchingVisitor.match(patternQualifier, matchedQualifier));
if (!myMatchingVisitor.getResult())
return;
} else {
final PsiMethod method = mcall2.resolveMethod();
if (method != null) {
if (patternQualifier instanceof PsiThisExpression) {
myMatchingVisitor.setResult(!method.hasModifierProperty(PsiModifier.STATIC));
return;
}
}
final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(patternQualifier);
matchImplicitQualifier(handler, method, myMatchingVisitor.getMatchContext());
if (!myMatchingVisitor.getResult()) {
return;
}
}
} else if (matchedQualifier != null) {
myMatchingVisitor.setResult(false);
return;
}
myMatchingVisitor.setResult(myMatchingVisitor.matchSons(mcall.getArgumentList(), mcall2.getArgumentList()));
if (myMatchingVisitor.getResult()) {
myMatchingVisitor.setResult(matchTypeParameters(mcallRef1, mcallRef2));
}
if (myMatchingVisitor.getResult() && isTypedVar) {
boolean res = myMatchingVisitor.getResult();
res &= myMatchingVisitor.handleTypedElement(patternMethodName, mcallRef2.getReferenceNameElement());
myMatchingVisitor.setResult(res);
}
}
use of com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler in project intellij-community by JetBrains.
the class JavaMatchingVisitor method visitTryStatement.
@Override
public void visitTryStatement(final PsiTryStatement try1) {
final PsiTryStatement try2 = (PsiTryStatement) myMatchingVisitor.getElement();
myMatchingVisitor.setResult(myMatchingVisitor.matchSons(try1.getTryBlock(), try2.getTryBlock()));
if (!myMatchingVisitor.getResult())
return;
final PsiResourceList resourceList1 = try1.getResourceList();
final PsiCatchSection[] catches1 = try1.getCatchSections();
final PsiCodeBlock finally1 = try1.getFinallyBlock();
final PsiResourceList resourceList2 = try2.getResourceList();
final PsiCatchSection[] catches2 = try2.getCatchSections();
final PsiCodeBlock finally2 = try2.getFinallyBlock();
if (!myMatchingVisitor.getMatchContext().getOptions().isLooseMatching() && ((catches1.length == 0 && catches2.length != 0) || (finally1 == null && finally2 != null) || (resourceList1 == null && resourceList2 != null)) || catches2.length < catches1.length) {
myMatchingVisitor.setResult(false);
} else {
final List<PsiElement> unmatchedElements = new ArrayList<>();
if (resourceList1 != null) {
if (resourceList2 == null) {
myMatchingVisitor.setResult(false);
return;
}
final List<PsiResourceListElement> resources1 = PsiTreeUtil.getChildrenOfTypeAsList(resourceList1, PsiResourceListElement.class);
final List<PsiResourceListElement> resources2 = PsiTreeUtil.getChildrenOfTypeAsList(resourceList2, PsiResourceListElement.class);
myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(resources1.toArray(new PsiResourceListElement[resources1.size()]), resources2.toArray(new PsiResourceListElement[resources2.size()])));
if (!myMatchingVisitor.getResult())
return;
} else if (resourceList2 != null) {
unmatchedElements.add(resourceList2);
}
ContainerUtil.addAll(unmatchedElements, catches2);
for (PsiCatchSection catchSection : catches1) {
final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(catchSection);
final PsiElement pinnedNode = handler.getPinnedNode(null);
if (pinnedNode != null) {
myMatchingVisitor.setResult(handler.match(catchSection, pinnedNode, myMatchingVisitor.getMatchContext()));
if (!myMatchingVisitor.getResult())
return;
} else {
boolean matched = false;
for (int j = 0; j < unmatchedElements.size(); ++j) {
if (handler.match(catchSection, unmatchedElements.get(j), myMatchingVisitor.getMatchContext())) {
unmatchedElements.remove(j);
matched = true;
break;
}
}
if (!matched) {
myMatchingVisitor.setResult(false);
return;
}
}
}
if (finally1 != null) {
myMatchingVisitor.setResult(myMatchingVisitor.matchSons(finally1, finally2));
} else if (finally2 != null) {
unmatchedElements.add(finally2);
}
if (myMatchingVisitor.getResult() && unmatchedElements.size() > 0) {
try2.putUserData(GlobalMatchingVisitor.UNMATCHED_ELEMENTS_KEY, unmatchedElements);
}
}
}
Aggregations