mcimadamore@1436: /* mcimadamore@1436: * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. mcimadamore@1436: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. mcimadamore@1436: * mcimadamore@1436: * This code is free software; you can redistribute it and/or modify it mcimadamore@1436: * under the terms of the GNU General Public License version 2 only, as mcimadamore@1436: * published by the Free Software Foundation. mcimadamore@1436: * mcimadamore@1436: * This code is distributed in the hope that it will be useful, but WITHOUT mcimadamore@1436: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or mcimadamore@1436: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License mcimadamore@1436: * version 2 for more details (a copy is included in the LICENSE file that mcimadamore@1436: * accompanied this code). mcimadamore@1436: * mcimadamore@1436: * You should have received a copy of the GNU General Public License version mcimadamore@1436: * 2 along with this work; if not, write to the Free Software Foundation, mcimadamore@1436: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. mcimadamore@1436: * mcimadamore@1436: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA mcimadamore@1436: * or visit www.oracle.com if you need additional information or have any mcimadamore@1436: * questions. mcimadamore@1436: */ mcimadamore@1436: mcimadamore@1436: /* mcimadamore@1436: * @test mcimadamore@1436: * @bug 8002099 mcimadamore@1436: * @summary Add support for intersection types in cast expression mcimadamore@1436: */ mcimadamore@1436: mcimadamore@1436: import com.sun.source.util.JavacTask; mcimadamore@1436: import java.net.URI; mcimadamore@1436: import java.util.Arrays; mcimadamore@1436: import javax.tools.Diagnostic; mcimadamore@1436: import javax.tools.JavaCompiler; mcimadamore@1436: import javax.tools.JavaFileObject; mcimadamore@1436: import javax.tools.SimpleJavaFileObject; mcimadamore@1436: import javax.tools.StandardJavaFileManager; mcimadamore@1436: import javax.tools.ToolProvider; mcimadamore@1436: mcimadamore@1436: public class IntersectionTypeParserTest { mcimadamore@1436: mcimadamore@1436: static int checkCount = 0; mcimadamore@1436: mcimadamore@1436: enum TypeKind { mcimadamore@1436: SIMPLE("A"), mcimadamore@1436: GENERIC("A"), mcimadamore@1436: WILDCARD("A"); mcimadamore@1436: mcimadamore@1436: String typeStr; mcimadamore@1436: mcimadamore@1436: TypeKind(String typeStr) { mcimadamore@1436: this.typeStr = typeStr; mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: enum ArrayKind { mcimadamore@1436: NONE(""), mcimadamore@1436: SINGLE("[]"), mcimadamore@1436: DOUBLE("[][]"); mcimadamore@1436: mcimadamore@1436: String arrStr; mcimadamore@1436: mcimadamore@1436: ArrayKind(String arrStr) { mcimadamore@1436: this.arrStr = arrStr; mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: static class Type { mcimadamore@1436: TypeKind tk; mcimadamore@1436: ArrayKind ak; mcimadamore@1436: mcimadamore@1436: Type(TypeKind tk, ArrayKind ak) { mcimadamore@1436: this.tk = tk; mcimadamore@1436: this.ak = ak; mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: String asString() { mcimadamore@1436: return tk.typeStr + ak.arrStr; mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: enum CastKind { mcimadamore@1436: ONE("(#T0)", 1), mcimadamore@1436: TWO("(#T0 & T1)", 2), mcimadamore@1436: THREE("(#T0 & #T1 & #T2)", 3); mcimadamore@1436: mcimadamore@1436: String castTemplate; mcimadamore@1436: int nBounds; mcimadamore@1436: mcimadamore@1436: CastKind(String castTemplate, int nBounds) { mcimadamore@1436: this.castTemplate = castTemplate; mcimadamore@1436: this.nBounds = nBounds; mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: String asString(Type... types) { mcimadamore@1436: String res = castTemplate; mcimadamore@1436: for (int i = 0; i < nBounds ; i++) { mcimadamore@1436: res = res.replaceAll(String.format("#T%d", i), types[i].asString()); mcimadamore@1436: } mcimadamore@1436: return res; mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: public static void main(String... args) throws Exception { mcimadamore@1436: //create default shared JavaCompiler - reused across multiple compilations mcimadamore@1436: JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); mcimadamore@1436: StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); mcimadamore@1436: mcimadamore@1436: for (CastKind ck : CastKind.values()) { mcimadamore@1436: for (TypeKind t1 : TypeKind.values()) { mcimadamore@1436: for (ArrayKind ak1 : ArrayKind.values()) { mcimadamore@1436: Type typ1 = new Type(t1, ak1); mcimadamore@1436: if (ck.nBounds == 1) { mcimadamore@1436: new IntersectionTypeParserTest(ck, typ1).run(comp, fm); mcimadamore@1436: continue; mcimadamore@1436: } mcimadamore@1436: for (TypeKind t2 : TypeKind.values()) { mcimadamore@1436: for (ArrayKind ak2 : ArrayKind.values()) { mcimadamore@1436: Type typ2 = new Type(t2, ak2); mcimadamore@1436: if (ck.nBounds == 2) { mcimadamore@1436: new IntersectionTypeParserTest(ck, typ1, typ2).run(comp, fm); mcimadamore@1436: continue; mcimadamore@1436: } mcimadamore@1436: for (TypeKind t3 : TypeKind.values()) { mcimadamore@1436: for (ArrayKind ak3 : ArrayKind.values()) { mcimadamore@1436: Type typ3 = new Type(t3, ak3); mcimadamore@1436: new IntersectionTypeParserTest(ck, typ1, typ2, typ3).run(comp, fm); mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: System.out.println("Total check executed: " + checkCount); mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: CastKind ck; mcimadamore@1436: Type[] types; mcimadamore@1436: JavaSource source; mcimadamore@1436: DiagnosticChecker diagChecker; mcimadamore@1436: mcimadamore@1436: IntersectionTypeParserTest(CastKind ck, Type... types) { mcimadamore@1436: this.ck = ck; mcimadamore@1436: this.types = types; mcimadamore@1436: this.source = new JavaSource(); mcimadamore@1436: this.diagChecker = new DiagnosticChecker(); mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: class JavaSource extends SimpleJavaFileObject { mcimadamore@1436: mcimadamore@1436: String bodyTemplate = "class Test {\n" + mcimadamore@1436: " void test() {\n" + mcimadamore@1436: " Object o = #Cnull;\n" + mcimadamore@1436: " } }"; mcimadamore@1436: mcimadamore@1436: String source = ""; mcimadamore@1436: mcimadamore@1436: public JavaSource() { mcimadamore@1436: super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); mcimadamore@1436: source += bodyTemplate.replaceAll("#C", ck.asString(types)); mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: @Override mcimadamore@1436: public CharSequence getCharContent(boolean ignoreEncodingErrors) { mcimadamore@1436: return source; mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception { mcimadamore@1436: checkCount++; mcimadamore@1436: JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker, mcimadamore@1511: null, null, Arrays.asList(source)); mcimadamore@1436: ct.parse(); mcimadamore@1436: if (diagChecker.errorFound) { mcimadamore@1436: throw new Error("Unexpected parser error for source:\n" + mcimadamore@1436: source.getCharContent(true)); mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: mcimadamore@1436: static class DiagnosticChecker implements javax.tools.DiagnosticListener { mcimadamore@1436: mcimadamore@1436: boolean errorFound; mcimadamore@1436: mcimadamore@1436: public void report(Diagnostic diagnostic) { mcimadamore@1436: if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { mcimadamore@1436: errorFound = true; mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: } mcimadamore@1436: }