1 /*
2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 8206986
27  * @summary Ensure CaseTree methods return expected values
28  * @modules jdk.compiler
29  */
30 
31 import java.io.IOException;
32 import java.io.StringWriter;
33 import java.net.URI;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.List;
37 import java.util.stream.Collectors;
38 
39 import javax.tools.*;
40 
41 import com.sun.source.tree.CaseTree;
42 import com.sun.source.tree.CompilationUnitTree;
43 import com.sun.source.tree.Tree;
44 import com.sun.source.util.JavacTask;
45 import com.sun.source.util.TreePathScanner;
46 
47 public class CaseTest {
48 
main(String[] args)49     public static void main(String[] args) throws Exception {
50         String sourceVersion = Integer.toString(Runtime.version().feature());
51         new CaseTest().testLabels(sourceVersion);
52         new CaseTest().testStatement(sourceVersion);
53         new CaseTest().testRule(sourceVersion);
54     }
55 
testLabels(String sourceVersion)56     void testLabels(String sourceVersion) throws Exception {
57         String code = "class Test {\n" +
58                       "    void t(int i) {\n" +
59                       "         switch(i) {\n" +
60                       "              case 0: break;\n" +
61                       "              case 1, 2: breal;\n" +
62                       "              default: breal;\n" +
63                       "         }\n" +
64                       "    }\n" +
65                       "}\n";
66         List<String> labels = new ArrayList<>();
67         new TreePathScanner<Void, Void>() {
68             @Override
69             public Void visitCase(CaseTree node, Void p) {
70                 labels.add(String.valueOf(node.getExpression()));
71                 labels.add(node.getExpressions().stream()
72                                                 .map(String::valueOf)
73                                                 .collect(Collectors.joining(",", "[", "]")));
74                 return super.visitCase(node, p);
75             }
76         }.scan(parse(code, sourceVersion), null);
77 
78         List<String> expected = Arrays.asList("0", "[0]", "1", "[1,2]", "null", "[]");
79 
80         if (!expected.equals(labels)) {
81             throw new AssertionError("Unexpected labels found: " + labels);
82         }
83     }
84 
testStatement(String sourceVersion)85     void testStatement(String sourceVersion) throws Exception {
86         String code = "class Test {\n" +
87                       "    void t(int i) {\n" +
88                       "         switch(i) {\n" +
89                       "              case 0:" +
90                       "                  System.err.println();\n" +
91                       "                  break;\n" +
92                       "         }\n" +
93                       "    }\n" +
94                       "}\n";
95         new TreePathScanner<Void, Void>() {
96             @Override
97             public Void visitCase(CaseTree node, Void p) {
98                 if (node.getStatements().size() != 2) {
99                     throw new AssertionError("Unexpected statements: " + node.getStatements());
100                 }
101                 if (node.getBody() != null) {
102                     throw new AssertionError("Unexpected body: " + node.getBody());
103                 }
104                 return super.visitCase(node, p);
105             }
106         }.scan(parse(code, sourceVersion), null);
107     }
108 
testRule(String sourceVersion)109     void testRule(String sourceVersion) throws Exception {
110         String code = "class Test {\n" +
111                       "    void t(int i) {\n" +
112                       "         switch(i) {\n" +
113                       "              case 0 -> {" +
114                       "                  System.err.println();\n" +
115                       "              };\n" +
116                       "         }\n" +
117                       "    }\n" +
118                       "}\n";
119         new TreePathScanner<Void, Void>() {
120             @Override
121             public Void visitCase(CaseTree node, Void p) {
122                 if (node.getStatements() != null) {
123                     throw new AssertionError("Unexpected statements: " + node.getStatements());
124                 }
125                 if (node.getBody().getKind() != Tree.Kind.BLOCK) {
126                     throw new AssertionError("Unexpected body: " + node.getBody());
127                 }
128                 return super.visitCase(node, p);
129             }
130         }.scan(parse(code, sourceVersion), null);
131     }
132 
parse(String code, String sourceVersion)133     private CompilationUnitTree parse(String code, String sourceVersion) throws IOException {
134         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
135         assert tool != null;
136         DiagnosticListener<JavaFileObject> noErrors = d -> {};
137 
138         StringWriter out = new StringWriter();
139         JavacTask ct = (JavacTask) tool.getTask(out, null, noErrors,
140             List.of("-XDdev"), null,
141             Arrays.asList(new MyFileObject(code)));
142         return ct.parse().iterator().next();
143     }
144 
145     static class MyFileObject extends SimpleJavaFileObject {
146         private String text;
147 
MyFileObject(String text)148         public MyFileObject(String text) {
149             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
150             this.text = text;
151         }
152 
153         @Override
getCharContent(boolean ignoreEncodingErrors)154         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
155             return text;
156         }
157     }
158 }
159