diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java index cfb82cb0e371..fd82b2cfe75a 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java @@ -196,7 +196,7 @@ public class JavaMatchingVisitor extends JavaElementVisitor { myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(psiDocTagValue, tag2.getValueElement())); } else { - myMatchingVisitor.setResult(allowsAbsenceOfMatch(psiDocTagValue)); + myMatchingVisitor.setResult(myMatchingVisitor.allowsAbsenceOfMatch(psiDocTagValue)); } } } @@ -213,16 +213,6 @@ public class JavaMatchingVisitor extends JavaElementVisitor { } } - private boolean allowsAbsenceOfMatch(final PsiElement element) { - MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(element); - - if (handler instanceof SubstitutionHandler && - ((SubstitutionHandler)handler).getMinOccurs() == 0) { - return true; - } - return false; - } - @Override public void visitDocComment(final PsiDocComment comment) { PsiDocComment comment2; @@ -311,16 +301,7 @@ public class JavaMatchingVisitor extends JavaElementVisitor { final PsiNameValuePair elementNameValuePair = (PsiNameValuePair)myMatchingVisitor.getElement(); final PsiAnnotationMemberValue annotationInitializer = pair.getValue(); - if (annotationInitializer != null) { - final boolean isTypedInitializer = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(annotationInitializer) && - annotationInitializer instanceof PsiReferenceExpression; - - myMatchingVisitor.setResult(myMatchingVisitor.match(annotationInitializer, elementNameValuePair.getValue()) || - (isTypedInitializer && - elementNameValuePair.getValue() == null && - allowsAbsenceOfMatch(annotationInitializer) - )); - } + myMatchingVisitor.setResult(myMatchingVisitor.match(annotationInitializer, elementNameValuePair.getValue())); if (myMatchingVisitor.getResult()) { final PsiIdentifier nameIdentifier = pair.getNameIdentifier(); final PsiIdentifier otherIdentifier = elementNameValuePair.getNameIdentifier(); @@ -976,9 +957,6 @@ public class JavaMatchingVisitor extends JavaElementVisitor { final PsiIdentifier nameIdentifier = var.getNameIdentifier(); boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(nameIdentifier); - boolean isTypedInitializer = var.getInitializer() != null && - myMatchingVisitor.getMatchContext().getPattern().isTypedVar(var.getInitializer()) && - var.getInitializer() instanceof PsiReferenceExpression; final PsiVariable var2 = (PsiVariable)myMatchingVisitor.getElement(); try { @@ -998,13 +976,9 @@ public class JavaMatchingVisitor extends JavaElementVisitor { if (myMatchingVisitor.getResult()) { // Check initializer + final PsiExpression initializer = var.getInitializer(); final PsiExpression var2Initializer = var2.getInitializer(); - - myMatchingVisitor.setResult(myMatchingVisitor.match(var.getInitializer(), var2Initializer) || - (isTypedInitializer && - var2Initializer == null && - allowsAbsenceOfMatch(var.getInitializer()) - )); + myMatchingVisitor.setResult(myMatchingVisitor.match(initializer, var2Initializer)); } if (myMatchingVisitor.getResult() && var instanceof PsiParameter && var.getParent() instanceof PsiCatchSection) { diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/GlobalMatchingVisitor.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/GlobalMatchingVisitor.java index 2f53da09cd12..36e3aec89bee 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/GlobalMatchingVisitor.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/GlobalMatchingVisitor.java @@ -84,6 +84,11 @@ public class GlobalMatchingVisitor extends AbstractMatchingVisitor { return ((SubstitutionHandler)handler).handle(match, matchContext); } + public boolean allowsAbsenceOfMatch(final PsiElement element) { + final MatchingHandler handler = getMatchContext().getPattern().getHandler(element); + return handler instanceof SubstitutionHandler && ((SubstitutionHandler)handler).getMinOccurs() == 0; + } + /** * Identifies the match between given element of program tree and pattern element * @@ -92,11 +97,14 @@ public class GlobalMatchingVisitor extends AbstractMatchingVisitor { * @return true if equal and false otherwise */ public boolean match(final PsiElement el1, final PsiElement el2) { - // null if (el1 == el2) return true; - if (el2 == null || el1 == null) { - // this a bug! - return false; + if (el1 == null) { + // absence of pattern element is match + return true; + } + if (el2 == null) { + // absence of match element needs check if allowed. + return allowsAbsenceOfMatch(el1); } // copy changed data to local stack @@ -104,12 +112,6 @@ public class GlobalMatchingVisitor extends AbstractMatchingVisitor { myElement = el2; try { - /*if (el1 instanceof XmlElement) { - el1.accept(myXmlVisitor); - } - else { - el1.accept(myJavaVisitor); - }*/ PsiElementVisitor visitor = getVisitorForElement(el1); if (visitor != null) { el1.accept(visitor); @@ -298,11 +300,6 @@ public class GlobalMatchingVisitor extends AbstractMatchingVisitor { this.matchContext = matchContext; } - // Matches the sons of given elements to find equality - // @param el1 the pattern element for matching - // @param el2 the tree element for matching - // @return if they are equal and false otherwise - @Override protected boolean isLeftLooseMatching() { return matchContext.getOptions().isLooseMatching(); diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java index 32e9db6acaa7..d9089e7f4282 100644 --- a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java @@ -1577,10 +1577,12 @@ public class StructuralSearchTest extends StructuralSearchTestCase { // class pattern without extends matches pattern with extends assertEquals( "match of class without extends to class with it, ep 3", - findMatchesCount(s41,s42_2), - 2 + 4, + findMatchesCount(s41,s42_2) ); + assertEquals("match class with fields without initializers", 2, findMatchesCount(s41, "class '_ { '_T '_T2 = '_T3{0,0}; } ")); + // typed reference element assertEquals( "typed reference element", @@ -3233,4 +3235,18 @@ public class StructuralSearchTest extends StructuralSearchTestCase { String pattern6 = "try { '_St1*; } catch ('_E1 | '_E2 '_e) { '_St2*; }"; assertEquals("Find multi catch with variables", 1, findMatchesCount(source, pattern6)); } + + public void testFindAsserts() { + String source = "class A {" + + " void f(int i) {" + + " assert i > 0;" + + " assert i < 10 : \"i: \" + i;" + + " assert i == 5;" + + " }" + + "}"; + assertEquals("find assert statements", 3, findMatchesCount(source, "assert '_a;")); + assertEquals("find assert statements 2", 3, findMatchesCount(source, "assert '_a : 'b*;")); + assertEquals("find assert statement with messages", 1, findMatchesCount(source, "assert '_a : '_b;")); + assertEquals("find assert statement without messages", 2, findMatchesCount(source, "assert 'a : '_b{0,0};")); + } }