1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/tools/javac/processing/model/type/TestUnionType.java Wed Apr 27 01:34:52 2016 +0800 1.3 @@ -0,0 +1,207 @@ 1.4 +/* 1.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + */ 1.26 + 1.27 +/* 1.28 + * @test 1.29 + * @bug 7029150 7025809 1.30 + * @summary Test support for union types 1.31 + * @library /tools/javac/lib 1.32 + */ 1.33 + 1.34 +import java.net.URI; 1.35 +import java.util.*; 1.36 +import javax.annotation.processing.*; 1.37 +import javax.lang.model.element.*; 1.38 +import javax.lang.model.type.*; 1.39 +import javax.lang.model.util.*; 1.40 +import javax.tools.*; 1.41 + 1.42 +import com.sun.source.tree.*; 1.43 +import com.sun.source.util.*; 1.44 + 1.45 +public class TestUnionType extends JavacTestingAbstractProcessor { 1.46 + enum TestKind { 1.47 + SingleType("E1", "E1", 1.48 + "VariableTree: E1 e", 1.49 + "VariableTree: elem EXCEPTION_PARAMETER e", 1.50 + "VariableTree: elem.type DECLARED", 1.51 + "VariableTree: elem.type.elem CLASS E1", 1.52 + "VariableTree: type DECLARED", 1.53 + "VariableTree: type.elem CLASS E1", 1.54 + "VariableTree: type.elem.type DECLARED"), 1.55 + 1.56 + ValidTypes("E1, E2", "E1 | E2", 1.57 + "VariableTree: E1 | E2 e", 1.58 + "VariableTree: elem EXCEPTION_PARAMETER e", 1.59 + "VariableTree: elem.type UNION Test.E1,Test.E2", 1.60 + "VariableTree: elem.type.elem null", 1.61 + "VariableTree: type UNION Test.E1,Test.E2", 1.62 + "VariableTree: type.elem null"), 1.63 + 1.64 + InvalidTypes("E1, E2", "E1 | EMissing", 1.65 + "VariableTree: E1 | EMissing e", 1.66 + "VariableTree: elem EXCEPTION_PARAMETER e", 1.67 + "VariableTree: elem.type UNION Test.E1,EMissing", 1.68 + "VariableTree: elem.type.elem null", 1.69 + "VariableTree: type UNION Test.E1,EMissing", 1.70 + "VariableTree: type.elem null"), 1.71 + 1.72 + Uncaught("E1", "E1 | E2", 1.73 + "VariableTree: E1 | E2 e", 1.74 + "VariableTree: elem EXCEPTION_PARAMETER e", 1.75 + "VariableTree: elem.type UNION Test.E1,Test.E2", 1.76 + "VariableTree: elem.type.elem null", 1.77 + "VariableTree: type UNION Test.E1,Test.E2", 1.78 + "VariableTree: type.elem null"); 1.79 + 1.80 + TestKind(String throwsTypes, String catchTypes, String... gold) { 1.81 + this.throwsTypes = throwsTypes; 1.82 + this.catchTypes = catchTypes; 1.83 + this.gold = Arrays.asList(gold); 1.84 + } 1.85 + 1.86 + final String throwsTypes; 1.87 + final String catchTypes; 1.88 + final List<String> gold; 1.89 + } 1.90 + 1.91 + static class TestFileObject extends SimpleJavaFileObject { 1.92 + public static final String template = 1.93 + "class Test {\n" 1.94 + + " class E1 extends Exception { }\n" 1.95 + + " class E2 extends Exception { }\n" 1.96 + + " void doSomething() throws #T { }\n" 1.97 + + " void test() {\n" 1.98 + + " try {\n" 1.99 + + " doSomething();\n" 1.100 + + " } catch (#C e) {\n" 1.101 + + " }\n" 1.102 + + " }\n" 1.103 + + "}\n"; 1.104 + 1.105 + public TestFileObject(TestKind tk) { 1.106 + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 1.107 + this.tk = tk; 1.108 + } 1.109 + 1.110 + @Override 1.111 + public CharSequence getCharContent(boolean ignoreEncodingErrors) { 1.112 + return template 1.113 + .replace("#T", tk.throwsTypes) 1.114 + .replace("#C", tk.catchTypes); 1.115 + } 1.116 + final TestKind tk; 1.117 + } 1.118 + 1.119 + public static void main(String... args) throws Exception { 1.120 + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); 1.121 + List<String> options = Arrays.asList("-proc:only"); 1.122 + for (TestKind tk: TestKind.values()) { 1.123 + System.err.println("Test: " + tk); 1.124 + TestUnionType p = new TestUnionType(); 1.125 + JavaFileObject fo = new TestFileObject(tk); 1.126 + JavaCompiler.CompilationTask task = comp.getTask(null, null, null, options, null, Arrays.asList(fo)); 1.127 + task.setProcessors(Arrays.asList(p)); 1.128 + boolean ok = task.call(); 1.129 + System.err.println("compilation " + (ok ? "passed" : "failed")); 1.130 + if (!ok) 1.131 + throw new Exception("compilation failed unexpectedly"); 1.132 + if (!p.log.equals(tk.gold)) { 1.133 + System.err.println("Expected output:"); 1.134 + for (String g: tk.gold) 1.135 + System.err.println(g); 1.136 + throw new Exception("unexpected output from test"); 1.137 + } 1.138 + System.err.println(); 1.139 + } 1.140 + } 1.141 + 1.142 + Trees trees; 1.143 + List<String> log; 1.144 + 1.145 + @Override 1.146 + public void init(ProcessingEnvironment env) { 1.147 + super.init(env); 1.148 + trees = Trees.instance(env); 1.149 + log = new ArrayList<String>(); 1.150 + } 1.151 + 1.152 + @Override 1.153 + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 1.154 + if (!roundEnv.processingOver()) { 1.155 + for (Element e: roundEnv.getRootElements()) { 1.156 + scan(trees.getPath(e)); 1.157 + } 1.158 + } 1.159 + return true; 1.160 + } 1.161 + 1.162 + void scan(TreePath path) { 1.163 + new Scanner().scan(path, null); 1.164 + } 1.165 + 1.166 + class Scanner extends TreePathScanner<Void,Void> { 1.167 + @Override 1.168 + public Void visitVariable(VariableTree tree, Void ignore) { 1.169 + TreePath p = getCurrentPath(); 1.170 + Element e = trees.getElement(p); 1.171 + if (e.getKind() == ElementKind.EXCEPTION_PARAMETER) { 1.172 + log("VariableTree: " + tree); 1.173 + log("VariableTree: elem " + print(e)); 1.174 + log("VariableTree: elem.type " + print(e.asType())); 1.175 + log("VariableTree: elem.type.elem " + print(types.asElement(e.asType()))); 1.176 + TypeMirror tm = trees.getTypeMirror(p); 1.177 + log("VariableTree: type " + print(tm)); 1.178 + log("VariableTree: type.elem " + print(types.asElement(tm))); 1.179 + if (types.asElement(tm) != null) 1.180 + log("VariableTree: type.elem.type " + print(types.asElement(tm).asType())); 1.181 + } 1.182 + return super.visitVariable(tree, null); 1.183 + } 1.184 + 1.185 + String print(TypeMirror tm) { 1.186 + return (tm == null) ? null : new TypePrinter().visit(tm); 1.187 + } 1.188 + 1.189 + String print(Element e) { 1.190 + return (e == null) ? null : (e.getKind() + " " + e.getSimpleName()); 1.191 + } 1.192 + 1.193 + void log(String msg) { 1.194 + System.err.println(msg); 1.195 + log.add(msg); 1.196 + } 1.197 + } 1.198 + 1.199 + class TypePrinter extends SimpleTypeVisitor<String, Void> { 1.200 + @Override 1.201 + protected String defaultAction(TypeMirror tm, Void ignore) { 1.202 + return String.valueOf(tm.getKind()); 1.203 + } 1.204 + 1.205 + @Override 1.206 + public String visitUnion(UnionType t, Void ignore) { 1.207 + return (t.getKind() + " " + t.getAlternatives()); 1.208 + } 1.209 + } 1.210 +}