View Javadoc
1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.java.ast;
5   
6   import static org.junit.Assert.assertEquals;
7   import static org.junit.Assert.fail;
8   
9   import java.io.IOException;
10  import java.io.InputStream;
11  
12  import net.sourceforge.pmd.PMD;
13  import net.sourceforge.pmd.lang.java.ParserTst;
14  
15  import org.apache.commons.io.IOUtils;
16  import org.junit.Assert;
17  import org.junit.Test;
18  
19  public class ParserCornersTest extends ParserTst {
20  
21      /**
22       * #1107 PMD 5.0.4 couldn't parse call of parent outer java class method
23       * from inner class
24       * 
25       * @throws Exception
26       *             any error
27       */
28      @Test
29      public void testInnerOuterClass() throws Exception {
30          parseJava17("/**\n" + " * @author azagorulko\n" + " *\n" + " */\n"
31                  + "public class TestInnerClassCallsOuterParent {\n" + "\n" + "    public void test() {\n"
32                  + "        new Runnable() {\n" + "            @Override\n" + "            public void run() {\n"
33                  + "                TestInnerClassCallsOuterParent.super.toString();\n" + "            }\n"
34                  + "        };\n" + "    }\n" + "}\n");
35      }
36  
37      @Test
38      public final void testGetFirstASTNameImageNull() throws Throwable {
39          parseJava14(ABSTRACT_METHOD_LEVEL_CLASS_DECL);
40      }
41  
42      @Test
43      public final void testCastLookaheadProblem() throws Throwable {
44          parseJava14(CAST_LOOKAHEAD_PROBLEM);
45      }
46  
47      /**
48       * Tests a specific generic notation for calling methods. See:
49       * https://jira.codehaus.org/browse/MPMD-139
50       */
51      @Test
52      public void testGenericsProblem() {
53          parseJava15(GENERICS_PROBLEM);
54          parseJava17(GENERICS_PROBLEM);
55      }
56  
57      @Test
58      public void testParsersCases15() {
59          String test15 = readAsString("/net/sourceforge/pmd/ast/ParserCornerCases.java");
60          parseJava15(test15);
61      }
62  
63      @Test
64      public void testParsersCases17() {
65          String test17 = readAsString("/net/sourceforge/pmd/ast/ParserCornerCases17.java");
66          parseJava17(test17);
67      }
68  
69      @Test
70      public void testParsersCases18() throws Exception {
71          String test18 = readAsString("/net/sourceforge/pmd/ast/ParserCornerCases18.java");
72          ASTCompilationUnit cu = parseJava18(test18);
73  
74          Assert.assertEquals(13, cu.findChildNodesWithXPath("//FormalParameter").size());
75          Assert.assertEquals(4, cu.findChildNodesWithXPath("//FormalParameter[@ExplicitReceiverParameter='true']").size());
76          Assert.assertEquals(9, cu.findChildNodesWithXPath("//FormalParameter[@ExplicitReceiverParameter='false']").size());
77      }
78  
79      /**
80       * Test for https://sourceforge.net/p/pmd/bugs/1333/
81       */
82      @Test
83      public void testLambdaBug1333() {
84          parseJava18("final class Bug1333 {\n"
85                  + "    private static final Logger LOG = LoggerFactory.getLogger(Foo.class);\n" + "\n"
86                  + "    public void deleteDirectoriesByNamePattern() {\n"
87                  + "        delete(path -> deleteDirectory(path));\n" + "    }\n" + "\n"
88                  + "    private void delete(Consumer<? super String> consumer) {\n"
89                  + "        LOG.debug(consumer.toString());\n" + "    }\n" + "\n"
90                  + "    private void deleteDirectory(String path) {\n" + "        LOG.debug(path);\n" + "    }\n" + "}");
91      }
92  
93      @Test
94      public void testLambdaBug1470() throws Exception {
95          String code = IOUtils.toString(ParserCornersTest.class.getResourceAsStream("LambdaBug1470.java"), "UTF-8");
96          parseJava18(code);
97      }
98  
99      /**
100      * Test for https://sourceforge.net/p/pmd/bugs/1355/
101      */
102     @Test
103     public void emptyFileJustComment() {
104         parseJava18("// just a comment");
105     }
106 
107     @Test
108     public void testMultipleExceptionCatching() {
109         String code = "public class Foo { public void bar() { "
110                 + "try { System.out.println(); } catch (RuntimeException | IOException e) {} } }";
111         try {
112             parseJava15(code);
113             fail("Expected exception");
114         } catch (ParseException e) {
115             assertEquals(
116                     "Line 1, Column 94: Cannot catch multiple exceptions when running in JDK inferior to 1.7 mode!",
117                     e.getMessage());
118         }
119 
120         try {
121             parseJava17(code);
122             // no exception expected
123         } catch (ParseException e) {
124             fail();
125         }
126     }
127 
128     @Test
129     public void testBug1429ParseError() throws Exception {
130         String c = IOUtils.toString(this.getClass().getResourceAsStream("Bug1429.java"));
131         parseJava18(c);
132     }
133 
134     private String readAsString(String resource) {
135         InputStream in = ParserCornersTest.class.getResourceAsStream(resource);
136         try {
137             return IOUtils.toString(in);
138         } catch (IOException e) {
139             throw new RuntimeException(e);
140         } finally {
141             IOUtils.closeQuietly(in);
142         }
143     }
144 
145     private static final String GENERICS_PROBLEM = "public class Test {" + PMD.EOL + " public void test() {" + PMD.EOL
146             + "   String o = super.<String> doStuff(\"\");" + PMD.EOL + " }" + PMD.EOL + "}";
147 
148     private static final String ABSTRACT_METHOD_LEVEL_CLASS_DECL = "public class Test {" + PMD.EOL + "  void bar() {"
149             + PMD.EOL + "   abstract class X { public abstract void f(); }" + PMD.EOL
150             + "   class Y extends X { public void f() {" + PMD.EOL + "    new Y().f();" + PMD.EOL + "   }}" + PMD.EOL
151             + "  }" + PMD.EOL + "}";
152 
153     private static final String CAST_LOOKAHEAD_PROBLEM = "public class BadClass {" + PMD.EOL + "  public Class foo() {"
154             + PMD.EOL + "    return (byte[].class);" + PMD.EOL + "  }" + PMD.EOL + "}";
155 }