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.Test;
17  
18  public class ParserCornersTest extends ParserTst {
19  
20      /**
21       * #1107 PMD 5.0.4 couldn't parse call of parent outer java class method
22       * from inner class
23       * 
24       * @throws Exception
25       *             any error
26       */
27      @Test
28      public void testInnerOuterClass() throws Exception {
29          parseJava17("/**\n" + " * @author azagorulko\n" + " *\n" + " */\n"
30                  + "public class TestInnerClassCallsOuterParent {\n" + "\n" + "    public void test() {\n"
31                  + "        new Runnable() {\n" + "            @Override\n" + "            public void run() {\n"
32                  + "                TestInnerClassCallsOuterParent.super.toString();\n" + "            }\n"
33                  + "        };\n" + "    }\n" + "}\n");
34      }
35  
36      @Test
37      public final void testGetFirstASTNameImageNull() throws Throwable {
38          parseJava14(ABSTRACT_METHOD_LEVEL_CLASS_DECL);
39      }
40  
41      @Test
42      public final void testCastLookaheadProblem() throws Throwable {
43          parseJava14(CAST_LOOKAHEAD_PROBLEM);
44      }
45  
46      /**
47       * Tests a specific generic notation for calling methods. See:
48       * https://jira.codehaus.org/browse/MPMD-139
49       */
50      @Test
51      public void testGenericsProblem() {
52          parseJava15(GENERICS_PROBLEM);
53          parseJava17(GENERICS_PROBLEM);
54      }
55  
56      @Test
57      public void testParsersCases() {
58          String test15 = readAsString("/net/sourceforge/pmd/ast/ParserCornerCases.java");
59          parseJava15(test15);
60  
61          String test17 = readAsString("/net/sourceforge/pmd/ast/ParserCornerCases17.java");
62          parseJava17(test17);
63  
64          String test18 = readAsString("/net/sourceforge/pmd/ast/ParserCornerCases18.java");
65          parseJava18(test18);
66      }
67  
68      /**
69       * Test for https://sourceforge.net/p/pmd/bugs/1333/
70       */
71      @Test
72      public void testLambdaBug1333() {
73          parseJava18("final class Bug1333 {\n"
74                  + "    private static final Logger LOG = LoggerFactory.getLogger(Foo.class);\n" + "\n"
75                  + "    public void deleteDirectoriesByNamePattern() {\n"
76                  + "        delete(path -> deleteDirectory(path));\n" + "    }\n" + "\n"
77                  + "    private void delete(Consumer<? super String> consumer) {\n"
78                  + "        LOG.debug(consumer.toString());\n" + "    }\n" + "\n"
79                  + "    private void deleteDirectory(String path) {\n" + "        LOG.debug(path);\n" + "    }\n" + "}");
80      }
81  
82      /**
83       * Test for https://sourceforge.net/p/pmd/bugs/1355/
84       */
85      @Test
86      public void emptyFileJustComment() {
87          parseJava18("// just a comment");
88      }
89  
90      @Test
91      public void testMultipleExceptionCatching() {
92          String code = "public class Foo { public void bar() { "
93                  + "try { System.out.println(); } catch (RuntimeException | IOException e) {} } }";
94          try {
95              parseJava15(code);
96              fail("Expected exception");
97          } catch (ParseException e) {
98              assertEquals(
99                      "Line 1, Column 94: Cannot catch multiple exceptions when running in JDK inferior to 1.7 mode!",
100                     e.getMessage());
101         }
102 
103         try {
104             parseJava17(code);
105             // no exception expected
106         } catch (ParseException e) {
107             fail();
108         }
109     }
110 
111     private String readAsString(String resource) {
112         InputStream in = ParserCornersTest.class.getResourceAsStream(resource);
113         try {
114             return IOUtils.toString(in);
115         } catch (IOException e) {
116             throw new RuntimeException(e);
117         } finally {
118             IOUtils.closeQuietly(in);
119         }
120     }
121 
122     private static final String GENERICS_PROBLEM = "public class Test {" + PMD.EOL + " public void test() {" + PMD.EOL
123             + "   String o = super.<String> doStuff(\"\");" + PMD.EOL + " }" + PMD.EOL + "}";
124 
125     private static final String ABSTRACT_METHOD_LEVEL_CLASS_DECL = "public class Test {" + PMD.EOL + "  void bar() {"
126             + PMD.EOL + "   abstract class X { public abstract void f(); }" + PMD.EOL
127             + "   class Y extends X { public void f() {" + PMD.EOL + "    new Y().f();" + PMD.EOL + "   }}" + PMD.EOL
128             + "  }" + PMD.EOL + "}";
129 
130     private static final String CAST_LOOKAHEAD_PROBLEM = "public class BadClass {" + PMD.EOL + "  public Class foo() {"
131             + PMD.EOL + "    return (byte[].class);" + PMD.EOL + "  }" + PMD.EOL + "}";
132 }