Commits

Jan Lahoda committed a8d6de4

Statement and block with a single statement should be considered equivalent (except for the root of the match).

  • Participants
  • Parent commits 9a2a931

Comments (0)

Files changed (5)

File api/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinder.java

 import com.sun.source.tree.ParenthesizedTree;
 import com.sun.source.tree.PrimitiveTypeTree;
 import com.sun.source.tree.ReturnTree;
+import com.sun.source.tree.StatementTree;
 import com.sun.source.tree.SynchronizedTree;
 import com.sun.source.tree.Tree;
 import com.sun.source.tree.Tree.Kind;
 import com.sun.source.tree.VariableTree;
 import com.sun.source.util.TreePath;
 import com.sun.source.util.TreePathScanner;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
         if (k1 == k2) {
             return true;
         }
-        
+
+        if (isSingleStatemenBlockAndStatement(t1, t2) || isSingleStatemenBlockAndStatement(t2, t1)) {
+            return true;
+        }
+
         if (    (k1 != Kind.MEMBER_SELECT && k1 != Kind.IDENTIFIER)
              || (k2 != Kind.MEMBER_SELECT && k2 != Kind.IDENTIFIER)) {
             return false;
 
         return Utilities.isPureMemberSelect(t1, true) && Utilities.isPureMemberSelect(t2, true);
     }
+
+    private static boolean isSingleStatemenBlockAndStatement(Tree t1, Tree t2) {
+        Kind k1 = t1.getKind();
+        Kind k2 = t2.getKind();
+        
+        if (k1 == Kind.BLOCK && ((BlockTree) t1).getStatements().size() == 1 && !((BlockTree) t1).isStatic()) {
+            return StatementTree.class.isAssignableFrom(k2.asInterface());
+        }
+
+        return false;
+    }
     
     @Override
     public Boolean scan(Tree node, TreePath p) {
 
         if (p != null && sameKind(node, p.getLeaf())) {
             //maybe equivalent:
-            boolean result = super.scan(node, p) == Boolean.TRUE;
+            boolean result = superScan(node, p) == Boolean.TRUE;
 
             if (result) {
                 if (p == searchingFor && node != searchingFor) {
             return false;
         
         if ((p != null && p.getLeaf() == searchingFor.getLeaf()) || !sameKind(node, searchingFor.getLeaf())) {
-            super.scan(node, null);
+            superScan(node, null);
             return false;
         } else {
             //maybe equivalent:
             allowGoDeeper = false;
             
-            boolean result = super.scan(node, searchingFor) == Boolean.TRUE;
+            boolean result = superScan(node, searchingFor) == Boolean.TRUE;
             
             allowGoDeeper = true;
             
                 return true;
             }
             
-            super.scan(node, null);
+            superScan(node, null);
             return false;
         }
     }
 
+    private Boolean superScan(Tree node, TreePath p) {
+        if (p == null) {
+            return super.scan(node, p);
+        }
+        
+        if (p.getLeaf().getKind() == Kind.BLOCK && node.getKind() != Kind.BLOCK /*&& p.getLeaf() != searchingFor.getLeaf()*/) {
+            BlockTree bt = (BlockTree) p.getLeaf();
+
+            assert bt.getStatements().size() == 1;
+            assert !bt.isStatic();
+            
+            p = new TreePath(p, bt.getStatements().get(0));
+        }
+
+        if (!sameKind(node, p.getLeaf())) {
+            return false;
+        }
+
+        return super.scan(node, p);
+    }
+
     private Boolean scan(Tree node, Tree p, TreePath pOrigin) {
         if (node == null || p == null)
             return node == p;
             return false;
         }
 
+        if (p.getLeaf().getKind() != Kind.BLOCK) {
+            //single-statement blocks are considered to be equivalent to statements
+            //TODO: some parents may need to be more strict, esp. synchronized and do-while
+            assert node.getStatements().size() == 1;
+            assert !node.isStatic();
+
+            if (p.getLeaf() == searchingFor.getLeaf())
+                return false;
+            
+            return checkLists(node.getStatements(), Collections.singletonList(p.getLeaf()), p.getParentPath());
+        }
+        
         BlockTree at = (BlockTree) p.getLeaf();
 
         if (node.isStatic() != at.isStatic()) {
             super.visitExpressionStatement(node, p);
             return false;
         }
-
+        
         ExpressionStatementTree et = (ExpressionStatementTree) p.getLeaf();
 
         return scan(node.getExpression(), et.getExpression(), p);

File api/src/org/netbeans/modules/jackpot30/impl/pm/TreeSerializer.java

 
 package org.netbeans.modules.jackpot30.impl.pm;
 
+import com.sun.source.tree.BlockTree;
 import com.sun.source.tree.ClassTree;
 import com.sun.source.tree.IdentifierTree;
 import com.sun.source.tree.MemberSelectTree;
             return null;
         }
 
+        if (tree.getKind() == Kind.BLOCK) {
+            BlockTree bt = (BlockTree) tree;
+
+            if (!bt.isStatic() && bt.getStatements().size() == 1) {
+                tree = bt.getStatements().get(0);
+            }
+        }
+
         append(p, "<");
         if (depth != (-1)) {
             append(p, Integer.toHexString(depth++));

File api/test/unit/src/org/netbeans/modules/jackpot30/impl/hints/HintsInvokerTest.java

                             "4:9-4:26:verifier:HINT");
     }
 
+    public void testPatternStatementAndSingleStatementBlockAreSame() throws Exception {
+        performAnalysisTest("test/Test.java",
+                            "|package test;\n" +
+                            "\n" +
+                            "public class Test {\n" +
+                            "     private int test() {\n" +
+                            "         if (true) {\n" +
+                            "             return 0;\n" +
+                            "         }\n" +
+                            "     }\n" +
+                            "}\n",
+                            "4:9-6:10:verifier:HINT");
+    }
+    
     private static final Map<String, HintDescription> test2Hint;
 
     static {
         constraints.put("$2", "java.lang.Object");
 
         test2Hint.put("testPatternAssert1", HintDescription.create(HintDescription.PatternDescription.create("assert $1 : $2;", constraints), new WorkerImpl()));
+        test2Hint.put("testPatternStatementAndSingleStatementBlockAreSame", HintDescription.create(HintDescription.PatternDescription.create("if ($1) return $2;", Collections.<String, String>emptyMap()), new WorkerImpl()));
     }
 
     @Override

File api/test/unit/src/org/netbeans/modules/jackpot30/impl/pm/BulkSearchTest.java

                     Collections.<String>emptyList());
     }
 
+    public void testStatementAndSingleBlockStatementAreSame1() throws Exception {
+        performTest("package test; public class Test { private void test() { { int y; { y = 1; } } }}",
+                    Arrays.asList("{ int $1; $1 = 1; }"),
+                    Collections.<String>emptyList());
+    }
+
+    public void testStatementAndSingleBlockStatementAreSame2() throws Exception {
+        performTest("package test; public class Test { private void test() { { int y; y = 1; } }}",
+                    Arrays.asList("{ int $1; { $1 = 1; } }"),
+                    Collections.<String>emptyList());
+    }
+
     public void XtestMeasureTime() throws Exception {
         String code = TestUtilities.copyFileToString(new File("/usr/local/home/lahvac/src/nb//outgoing/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionProvider.java"));
         List<String> patterns = new LinkedList<String>();

File api/test/unit/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinderTest.java

                              new Pair[] {new Pair<String, String>("$1", "y")});
     }
 
+    public void testStatementAndSingleBlockStatementAreSame1() throws Exception {
+        performVariablesTest("package test; public class Test {public void test1() { { int x; { x = 1; } } } }",
+                             "{ int $1; $1 = 1; }",
+                             new Pair[0],
+                             new Pair[] {new Pair<String, String>("$1", "x")});
+    }
+
+    public void testStatementAndSingleBlockStatementAreSame2() throws Exception {
+        performVariablesTest("package test; public class Test {public void test1() { { int x; x = 1; } } }",
+                             "{ int $1; { $1 = 1; } }",
+                             new Pair[0],
+                             new Pair[] {new Pair<String, String>("$1", "x")});
+    }
+
     protected void performVariablesTest(String code, String pattern, Pair<String, int[]>[] duplicatesPos, Pair<String, String>[] duplicatesNames) throws Exception {
         prepareTest(code, -1);