| /******************************************************************************* |
| * Copyright (c) 2003, 2015 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * This is an implementation of an early-draft specification developed under the Java |
| * Community Process (JCP) and is made available for testing and evaluation purposes |
| * only. The code is not compatible with any specification of the JCP. |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Stephan Herrmann - Contributions for |
| * Bug 428274 - [1.8] [compiler] Cannot cast from Number to double |
| *******************************************************************************/ |
| package org.eclipse.jdt.core.tests.compiler.regression; |
| |
| import java.io.File; |
| import java.util.Map; |
| |
| import junit.framework.Test; |
| |
| import org.eclipse.jdt.core.ToolFactory; |
| import org.eclipse.jdt.core.tests.util.Util; |
| import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; |
| import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; |
| import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
| |
| @SuppressWarnings({ "unchecked", "rawtypes" }) |
| public class CastTest extends AbstractRegressionTest { |
| |
| public CastTest(String name) { |
| super(name); |
| } |
| protected Map getCompilerOptions() { |
| Map defaultOptions = super.getCompilerOptions(); |
| defaultOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.WARNING); |
| defaultOptions.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE); |
| return defaultOptions; |
| } |
| public static Test suite() { |
| return buildAllCompliancesTestSuite(testClass()); |
| } |
| |
| static { |
| // TESTS_NAMES = new String[] { "test428388d" }; |
| } |
| /* |
| * check extra checkcast (interface->same interface) |
| */ |
| public void test001() throws Exception { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X { \n" + |
| " public static void main(String[] args) { \n" + |
| " Cloneable c1 = new int[0]; \n"+ |
| " Cloneable c2 = (Cloneable)c1; \n" + |
| " System.out.print(\"SUCCESS\"); \n" + |
| " } \n" + |
| "} \n", |
| }, |
| "SUCCESS"); |
| |
| ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); |
| String actualOutput = |
| disassembler.disassemble( |
| classFileBytes, |
| "\n", |
| ClassFileBytesDisassembler.DETAILED); |
| |
| String expectedOutput = |
| " // Method descriptor #15 ([Ljava/lang/String;)V\n" + |
| " // Stack: 2, Locals: 3\n" + |
| " public static void main(java.lang.String[] args);\n" + |
| " 0 iconst_0\n" + |
| " 1 newarray int [10]\n" + |
| " 3 astore_1 [c1]\n" + |
| " 4 aload_1 [c1]\n" + |
| " 5 astore_2 [c2]\n" + |
| " 6 getstatic java.lang.System.out : java.io.PrintStream [16]\n" + |
| " 9 ldc <String \"SUCCESS\"> [22]\n" + |
| " 11 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" + |
| " 14 return\n" + |
| " Line numbers:\n" + |
| " [pc: 0, line: 3]\n" + |
| " [pc: 4, line: 4]\n" + |
| " [pc: 6, line: 5]\n" + |
| " [pc: 14, line: 6]\n" + |
| " Local variable table:\n" + |
| " [pc: 0, pc: 15] local: args index: 0 type: java.lang.String[]\n" + |
| " [pc: 4, pc: 15] local: c1 index: 1 type: java.lang.Cloneable\n" + |
| " [pc: 6, pc: 15] local: c2 index: 2 type: java.lang.Cloneable\n"; |
| int index = actualOutput.indexOf(expectedOutput); |
| if (index == -1 || expectedOutput.length() == 0) { |
| System.out.println(Util.displayString(actualOutput, 2)); |
| } |
| if (index == -1) { |
| assertEquals("Wrong contents", expectedOutput, actualOutput); |
| } |
| } |
| |
| public void test002() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " // standard expressions\n" + |
| " String s = (String) null; // UNnecessary\n" + |
| " String t = (String) \"hello\"; // UNnecessary\n" + |
| " float f = (float) 12; // UNnecessary\n" + |
| " int i = (int)12.0; // necessary\n" + |
| " }\n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 4)\n" + |
| " String s = (String) null; // UNnecessary\n" + |
| " ^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from null to String\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 5)\n" + |
| " String t = (String) \"hello\"; // UNnecessary\n" + |
| " ^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from String to String\n" + |
| "----------\n" + |
| "3. ERROR in X.java (at line 6)\n" + |
| " float f = (float) 12; // UNnecessary\n" + |
| " ^^^^^^^^^^\n" + |
| "Unnecessary cast from int to float\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| public void test003() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " // message sends \n" + |
| " foo((Object) \"hello\"); // necessary\n" + |
| " foo((String) \"hello\"); // UNnecessary\n" + |
| " foo((Object) null); // necessary\n" + |
| " foo((String) null); // UNnecessary but keep as useful documentation \n" + |
| " }\n" + |
| " static void foo(String s) {\n" + |
| " System.out.println(\"foo(String):\"+s);\n" + |
| " }\n" + |
| " static void foo(Object o) {\n" + |
| " System.out.println(\"foo(Object):\"+o);\n" + |
| " }\n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 5)\n" + |
| " foo((String) \"hello\"); // UNnecessary\n" + |
| " ^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from String to String\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| public void test004() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " // constructors\n" + |
| " new X((Object) \"hello\"); // necessary\n" + |
| " new X((String) \"hello\"); // UNnecessary\n" + |
| " new X((Object) null); // necessary\n" + |
| " new X((String) null); // UNnecessary but keep as useful documentation\n" + |
| " }\n" + |
| " X(){}\n" + |
| " X(String s){\n" + |
| " System.out.println(\"new X(String):\"+s);\n" + |
| " }\n" + |
| " X(Object o){\n" + |
| " System.out.println(\"new X(Object):\"+o);\n" + |
| " }\n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 5)\n" + |
| " new X((String) \"hello\"); // UNnecessary\n" + |
| " ^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from String to String\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| public void test005() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " // qualified allocations\n" + |
| " new X().new XM3((Object) \"hello\"); // necessary\n" + |
| " new X().new XM3((String) \"hello\"); // UNnecessary\n" + |
| " new X().new XM3((Object) null); // necessary\n" + |
| " new X().new XM3((String) null); // UNnecessary but keep as useful documentation\n" + |
| " new X().new XM3((Object) \"hello\"){}; // necessary\n" + |
| " new X().new XM3((String) \"hello\"){}; // UNnecessary\n" + |
| " new X().new XM3((Object) null){}; // necessary\n" + |
| " new X().new XM3((String) null){}; // UNnecessary but keep as useful documentation\n" + |
| " }\n" + |
| " X(){}\n" + |
| " static class XM1 extends X {}\n" + |
| " static class XM2 extends X {}\n" + |
| " class XM3 {\n" + |
| " XM3(String s){\n" + |
| " System.out.println(\"new XM3(String):\"+s);\n" + |
| " }\n" + |
| " XM3(Object o){\n" + |
| " System.out.println(\"new XM3(Object):\"+o);\n" + |
| " }\n" + |
| " } \n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 5)\n" + |
| " new X().new XM3((String) \"hello\"); // UNnecessary\n" + |
| " ^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from String to String\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 9)\n" + |
| " new X().new XM3((String) \"hello\"){}; // UNnecessary\n" + |
| " ^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from String to String\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| public void _test006() { // TODO (philippe) add support to conditional expression for unnecessary cast |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " // ternary operator\n" + |
| " String s = null, t = null; \n" + |
| " X x0 = s == t\n" + |
| " ? (X)new XM1() // UNnecessary\n" + |
| " : new X();\n" + |
| " X x1 = s == t \n" + |
| " ? (X)new XM1() // necessary\n" + |
| " : new XM2();\n" + |
| " X x2 = s == t \n" + |
| " ? new XM1()\n" + |
| " : (X)new XM2(); // necessary\n" + |
| " X x3 = s == t \n" + |
| " ? (X)new XM1() // necessary\n" + |
| " : (X)new XM2(); // necessary\n" + |
| " }\n" + |
| " X(){}\n" + |
| " static class XM1 extends X {}\n" + |
| " static class XM2 extends X {}\n" + |
| "}\n" |
| }, |
| "x", |
| null, |
| true, |
| customOptions); |
| } |
| |
| public void test007() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " X(){}\n" + |
| " class XM3 {\n" + |
| " XM3(String s){\n" + |
| " System.out.println(\"new XM3(String):\"+s);\n" + |
| " }\n" + |
| " XM3(Object o){\n" + |
| " System.out.println(\"new XM3(Object):\"+o);\n" + |
| " }\n" + |
| " } \n" + |
| " \n" + |
| " class XM4 extends XM3 {\n" + |
| " XM4(String s){\n" + |
| " super((Object) s); // necessary\n" + |
| " System.out.println(\"new XM4(String):\"+s);\n" + |
| " }\n" + |
| " XM4(Object o){\n" + |
| " super((String) o); // necessary\n" + |
| " System.out.println(\"new XM4(Object):\"+o);\n" + |
| " }\n" + |
| " XM4(Thread t){\n" + |
| " super((Object) t); // UNnecessary\n" + |
| " System.out.println(\"new XM4(Thread):\"+t);\n" + |
| " }\n" + |
| " XM4(){\n" + |
| " super((String)null); // UNnecessary but keep as useful documentation\n" + |
| " System.out.println(\"new XM4():\");\n" + |
| " }\n" + |
| " XM4(int i){\n" + |
| " super((Object)null); // necessary\n" + |
| " System.out.println(\"new XM4():\");\n" + |
| " }\n" + |
| " }\n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 22)\n" + |
| " super((Object) t); // UNnecessary\n" + |
| " ^^^^^^^^^^\n" + |
| "Unnecessary cast from Thread to Object\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| public void test008() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " boolean b1 = new XM1() instanceof X; // UNnecessary\n" + |
| " boolean b2 = new X() instanceof XM1; // necessary\n" + |
| " boolean b3 = null instanceof X;\n" + |
| " }\n" + |
| " static class XM1 extends X {}\n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 3)\n" + |
| " boolean b1 = new XM1() instanceof X; // UNnecessary\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "The expression of type X.XM1 is already an instance of type X\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| public void test009() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " boolean b1 = ((X) new XM1()) == new X(); // UNnecessary\n" + |
| " boolean b2 = ((X) new XM1()) == new XM2(); // necessary\n" + |
| " boolean b3 = ((X) null) == new X(); // UNnecessary\n" + |
| " }\n" + |
| " static class XM1 extends X {}\n" + |
| " static class XM2 extends X {}\n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ "1. ERROR in X.java (at line 3)\n" + |
| " boolean b1 = ((X) new XM1()) == new X(); // UNnecessary\n" + |
| " ^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from X.XM1 to X\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 5)\n" + |
| " boolean b3 = ((X) null) == new X(); // UNnecessary\n" + |
| " ^^^^^^^^^^\n" + |
| "Unnecessary cast from null to X\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| public void test010() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " long l1 = ((long) 1) + 2L; // UNnecessary\n" + |
| " long l2 = ((long)1) + 2; // necessary\n" + |
| " long l3 = 0;" + |
| " l3 += (long)12; // UNnecessary\n" + |
| " }\n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 3)\n" + |
| " long l1 = ((long) 1) + 2L; // UNnecessary\n" + |
| " ^^^^^^^^^^\n" + |
| "Unnecessary cast from int to long\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 5)\n" + |
| " long l3 = 0; l3 += (long)12; // UNnecessary\n" + |
| " ^^^^^^^^\n" + |
| "Unnecessary cast from int to long\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| public void test011() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " String s1 = ((long) 1) + \"hello\"; // necessary\n" + |
| " String s2 = ((String)\"hello\") + 2; // UNnecessary\n" + |
| " String s3 = ((String)null) + null; // necessary\n" + |
| " String s4 = ((int) (byte)1) + \"hello\"; // necessary\n" + |
| " }\n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 4)\n" + |
| " String s2 = ((String)\"hello\") + 2; // UNnecessary\n" + |
| " ^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from String to String\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| public void test012() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " // message sends \n" + |
| " X x = new YM1(); \n" + |
| " foo((X) x); // UNnecessary\n" + |
| " foo((XM1) x); // UNnecessary\n" + |
| " foo((YM1) x); // necessary \n" + |
| " }\n" + |
| " static void foo(X x) {}\n" + |
| " static void foo(YM1 ym1) {}\n" + |
| " static class XM1 extends X {}\n" + |
| " static class YM1 extends XM1 {}\n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 5)\n" + |
| " foo((X) x); // UNnecessary\n" + |
| " ^^^^^\n" + |
| "Unnecessary cast from X to X\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 6)\n" + |
| " foo((XM1) x); // UNnecessary\n" + |
| " ^^^^^^^\n" + |
| "Unnecessary cast from X to X.XM1\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=42289 |
| public void test013() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " \n" + |
| " public static void main(String[] args) {\n" + |
| " int a = 0, b = 1;\n" + |
| " long d;\n" + |
| " d = (long)a; // unnecessary\n" + |
| " d = (long)a + b; // necessary \n" + |
| " d = d + a + (long)b; // unnecessary\n" + |
| " }\n" + |
| "}\n" + |
| "\n", |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 6)\n" + |
| " d = (long)a; // unnecessary\n" + |
| " ^^^^^^^\n" + |
| "Unnecessary cast from int to long\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 8)\n" + |
| " d = d + a + (long)b; // unnecessary\n" + |
| " ^^^^^^^\n" + |
| "Unnecessary cast from int to long\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| // 39925 - Unnecessary instanceof checking leads to a NullPointerException |
| public void test014() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " boolean b = new Cloneable() {} instanceof Cloneable;\n" + |
| "}" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 2)\n" + |
| " boolean b = new Cloneable() {} instanceof Cloneable;\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "The expression of type new Cloneable(){} is already an instance of type Cloneable\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| // narrowing cast on base types may change value, thus necessary |
| public void test015() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " void foo() { \n" + |
| " int lineCount = 10; \n" + |
| " long time = 1000; \n" + |
| " double linePerSeconds1 = ((int) (lineCount * 10000.0 / time)) / 10.0; // necessary \n" + |
| " double linePerSeconds2 = ((double) (lineCount * 10000.0 / time)) / 10.0; // UNnecessary \n" + |
| " } \n" + |
| "}" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 6)\n" + |
| " double linePerSeconds2 = ((double) (lineCount * 10000.0 / time)) / 10.0; // UNnecessary \n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from double to double\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| // narrowing cast on base types may change value, thus necessary |
| public void test016() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " void foo() { \n" + |
| " int lineCount = 10; \n" + |
| " long time = 1000; \n" + |
| " print((int) (lineCount * 10000.0 / time)); // necessary \n" + |
| " print((double) (lineCount * 10000.0 / time)); // UNnecessary \n" + |
| " } \n" + |
| " void print(double d) {} \n" + |
| "}" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 6)\n" + |
| " print((double) (lineCount * 10000.0 / time)); // UNnecessary \n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from double to double\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| //fault tolerance (40288) |
| public void test017() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " void bar() {\n" + |
| " foo((X) this);\n" + |
| " foo((X) zork());\n" + // unbound #zork() should not cause NPE |
| " }\n" + |
| " void foo(X x) {\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 3)\n" + |
| " foo((X) this);\n" + |
| " ^^^^^^^^\n" + |
| "Unnecessary cast from X to X\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 4)\n" + |
| " foo((X) zork());\n" + |
| " ^^^^\n" + |
| "The method zork() is undefined for the type X\n" + |
| "----------\n", |
| null, |
| true, |
| customOptions); |
| } |
| //fault tolerance (40423) |
| public void test018() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "class Y {\n" + |
| " static Y[] foo(int[] tab) {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}\n" + |
| "public class X extends Y {\n" + |
| " Y[] bar() {\n" + |
| " return (Y[]) Y.foo(new double[] {});\n" + // no cast warning until method is applicable |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 8)\n" + |
| " return (Y[]) Y.foo(new double[] {});\n" + |
| " ^^^\n" + |
| "The method foo(int[]) in the type Y is not applicable for the arguments (double[])\n" + |
| "----------\n", |
| null, |
| true, |
| customOptions); |
| } |
| //fault tolerance (40288) |
| public void tes019() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " void bar() {\n" + |
| " X x1 =(X) this;\n" + |
| " X x2 = (X) zork();\n" + // unbound #zork() should not cause NPE |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 3)\n" + |
| " X x1 =(X) this;\n" + |
| " ^^^^^^^^\n" + |
| "Unnecessary cast to type X for expression of type X\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 4)\n" + |
| " X x2 = (X) zork();\n" + |
| " ^^^^\n" + |
| "The method zork() is undefined for the type X\n" + |
| "----------\n", |
| null, |
| true, |
| customOptions); |
| } |
| //fault tolerance |
| public void test020() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " void bar() {\n" + |
| " long l = (long)zork() + 2;\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 3)\n" + |
| " long l = (long)zork() + 2;\n" + |
| " ^^^^\n" + |
| "The method zork() is undefined for the type X\n" + |
| "----------\n", |
| null, |
| true, |
| customOptions); |
| } |
| |
| // unnecessary cast diagnosis should also consider receiver type (40572) |
| public void test021() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| this.runNegativeTest( |
| new String[] { |
| "p1/A.java", |
| "package p1;\n" + |
| "public class A {\n" + |
| " public class Member1 {}\n" + |
| " public class Member2 {}\n" + |
| " class Member3 {}\n" + |
| " public static class Member4 {\n" + |
| " public static class M4Member {}\n" + |
| " }\n" + |
| "}\n", |
| "p2/B.java", |
| "package p2;\n" + |
| "import p1.A;\n" + |
| "public class B extends A {\n" + |
| " public class Member1 {}\n" + |
| "}\n", |
| "p1/C.java", |
| "package p1;\n" + |
| "import p2.B;\n" + |
| "public class C extends B {\n" + |
| " void baz(B b) {\n" + |
| " ((A)b).new Member1(); // necessary since would bind to B.Member instead\n" + |
| " ((A)b).new Member2(); // UNnecessary\n" + |
| " ((A)b).new Member3(); // necessary since visibility issue\n" + |
| " ((A)b).new Member4().new M4Member(); // fault tolerance\n" + |
| " ((A)zork()).new Member1(); // fault-tolerance\n" + |
| " // anonymous\n"+ |
| " ((A)b).new Member1(){}; // necessary since would bind to B.Member instead\n" + |
| " ((A)b).new Member2(){}; // UNnecessary\n" + |
| " ((A)b).new Member3(){}; // necessary since visibility issue\n" + |
| " ((A)b).new Member4().new M4Member(){}; // fault tolerance\n" + |
| " ((A)zork()).new Member1(){}; // fault-tolerance\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "----------\n" + |
| "1. ERROR in p1\\C.java (at line 6)\n" + |
| " ((A)b).new Member2(); // UNnecessary\n" + |
| " ^^^^^^\n" + |
| "Unnecessary cast from B to A\n" + |
| "----------\n" + |
| "2. ERROR in p1\\C.java (at line 8)\n" + |
| " ((A)b).new Member4().new M4Member(); // fault tolerance\n" + |
| " ^^^^^^\n" + |
| "Unnecessary cast from B to A\n" + |
| "----------\n" + |
| "3. ERROR in p1\\C.java (at line 9)\n" + |
| " ((A)zork()).new Member1(); // fault-tolerance\n" + |
| " ^^^^\n" + |
| "The method zork() is undefined for the type C\n" + |
| "----------\n" + |
| "4. ERROR in p1\\C.java (at line 12)\n" + |
| " ((A)b).new Member2(){}; // UNnecessary\n" + |
| " ^^^^^^\n" + |
| "Unnecessary cast from B to A\n" + |
| "----------\n" + |
| "5. ERROR in p1\\C.java (at line 14)\n" + |
| " ((A)b).new Member4().new M4Member(){}; // fault tolerance\n" + |
| " ^^^^^^\n" + |
| "Unnecessary cast from B to A\n" + |
| "----------\n" + |
| "6. ERROR in p1\\C.java (at line 15)\n" + |
| " ((A)zork()).new Member1(){}; // fault-tolerance\n" + |
| " ^^^^\n" + |
| "The method zork() is undefined for the type C\n" + |
| "----------\n", |
| null, |
| true, |
| customOptions); |
| } |
| // unnecessary cast diagnosis should tolerate array receiver type (40752) |
| public void test022() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| customOptions.put(CompilerOptions.OPTION_ReportUncheckedTypeOperation, CompilerOptions.IGNORE); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X { \n" + |
| " void foo(java.util.Map map){ \n" + |
| " int[] fillPattern = new int[0]; \n" + |
| " if (fillPattern.equals((int[])map.get(\"x\"))) { \n" + |
| " } \n" + |
| " } \n"+ |
| "} \n", |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 4)\n" + |
| " if (fillPattern.equals((int[])map.get(\"x\"))) { \n" + |
| " ^^^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from Object to int[]\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| |
| // unnecessary cast diagnosis should tolerate array receiver type (40752) |
| public void test023() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| "\n" + |
| " public static void main(String[] args) {\n" + |
| " final long lgLow32BitMask1 = ~(~((long) 0) << 32); // necessary\n" + |
| " final long lgLow32BitMask2 = ~(~0 << 32); // necessary\n" + |
| " final long lgLow32BitMask3 = ~(~((long) 0L) << 32); // unnecessary\n" + |
| " final long lgLow32BitMask4 = ~(~((int) 0L) << 32); // necessary\n" + |
| " System.out.println(\"lgLow32BitMask1: \"+lgLow32BitMask1);\n" + |
| " System.out.println(\"lgLow32BitMask2: \"+lgLow32BitMask2);\n" + |
| " }\n" + |
| "}", |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 6)\n" + |
| " final long lgLow32BitMask3 = ~(~((long) 0L) << 32); // unnecessary\n" + |
| " ^^^^^^^^^^^\n" + |
| "Unnecessary cast from long to long\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| |
| // unnecessary cast diagnosis for message receiver (44400) |
| public void test024() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " public void foo(Object bar) {\n" + |
| " System.out.println(((Object) bar).toString());\n" + |
| " }\n" + |
| "}", |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 3)\n" + |
| " System.out.println(((Object) bar).toString());\n" + |
| " ^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from Object to Object\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| |
| // unnecessary cast diagnosis for message receiver (44400) |
| // variation with field access |
| public void test025() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public class X {\n" + |
| " int i;\n" + |
| " public void foo(X bar) {\n" + |
| " System.out.println(((X) bar).i);\n" + |
| " }\n" + |
| "}", |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 4)\n" + |
| " System.out.println(((X) bar).i);\n" + |
| " ^^^^^^^^^\n" + |
| "Unnecessary cast from X to X\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| /* |
| * https://bugs.eclipse.org/bugs/show_bug.cgi?id=47074 |
| */ |
| public void test026() { |
| |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| if (options.sourceLevel < ClassFileConstants.JDK1_5) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " A a = null;\n" + |
| " B b = (B) a;\n" + |
| " }\n" + |
| "}\n" + |
| "interface A {\n" + |
| " void doSomething();\n" + |
| "}\n" + |
| "interface B {\n" + |
| " int doSomething();\n" + |
| "}", |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " B b = (B) a;\n" + |
| " ^^^^^\n" + |
| "Cannot cast from A to B\n" + |
| "----------\n"); |
| return; |
| } |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " A a = null;\n" + |
| " B b = (B) a;\n" + |
| " }\n" + |
| "}\n" + |
| "interface A {\n" + |
| " void doSomething();\n" + |
| "}\n" + |
| "interface B {\n" + |
| " int doSomething();\n" + |
| "}", |
| }, |
| ""); |
| |
| } |
| /* |
| * https://bugs.eclipse.org/bugs/show_bug.cgi?id=47074 |
| */ |
| public void test027() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| if (options.sourceLevel < ClassFileConstants.JDK1_5) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " A a = null;\n" + |
| " boolean b = a instanceof B;\n" + |
| " }\n" + |
| "}\n" + |
| "interface A {\n" + |
| " void doSomething();\n" + |
| "}\n" + |
| "interface B {\n" + |
| " int doSomething();\n" + |
| "}", |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " boolean b = a instanceof B;\n" + |
| " ^^^^^^^^^^^^^^\n" + |
| "Incompatible conditional operand types A and B\n" + |
| "----------\n"); |
| return; |
| } |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " A a = null;\n" + |
| " boolean b = a instanceof B;\n" + |
| " }\n" + |
| "}\n" + |
| "interface A {\n" + |
| " void doSomething();\n" + |
| "}\n" + |
| "interface B {\n" + |
| " int doSomething();\n" + |
| "}", |
| }, |
| ""); |
| } |
| /* |
| * https://bugs.eclipse.org/bugs/show_bug.cgi?id=47074 |
| */ |
| public void test028() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| if (options.sourceLevel < ClassFileConstants.JDK1_5) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " A a = null;\n" + |
| " B b = null;\n" + |
| " boolean c = a == b;\n" + |
| " }\n" + |
| "}\n" + |
| "interface A {\n" + |
| " void doSomething();\n" + |
| "}\n" + |
| "interface B {\n" + |
| " int doSomething();\n" + |
| "}", |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 5)\n" + |
| " boolean c = a == b;\n" + |
| " ^^^^^^\n" + |
| "Incompatible operand types A and B\n" + |
| "----------\n"); |
| return; |
| } |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " A a = null;\n" + |
| " B b = null;\n" + |
| " boolean c = a == b;\n" + |
| " }\n" + |
| "}\n" + |
| "interface A {\n" + |
| " void doSomething();\n" + |
| "}\n" + |
| "interface B {\n" + |
| " int doSomething();\n" + |
| "}", |
| }, |
| ""); |
| |
| } |
| |
| /* |
| * verify error when assigning null to array |
| * http://bugs.eclipse.org/bugs/show_bug.cgi?id=26903 |
| */ |
| public void test029() { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X { \n" + |
| " public static void main(String[] args) { \n" + |
| " try { \n" + |
| " char[][] qName; \n" + |
| " qName = null; \n" + |
| " qName[0] = new char[1]; \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " try { \n" + |
| " char[][] qName; \n" + |
| " qName = (char[][])null; \n" + |
| " qName[0] = new char[1]; \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " try { \n" + |
| " char[][] qName; \n" + |
| " qName = (char[][])(char[][])(char[][])null; \n" + |
| " qName[0] = new char[2]; \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " try { \n" + |
| " char[][] qName; \n" + |
| " qName = args.length > 1 ? new char[1][2] : null; \n" + |
| " qName[0] = new char[3]; \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " System.out.println(\"SUCCESS\"); \n"+ |
| " } \n" + |
| "} \n", |
| }, |
| "SUCCESS"); |
| } |
| |
| /* |
| * verify error when assigning null to array |
| * http://bugs.eclipse.org/bugs/show_bug.cgi?id=26903 |
| */ |
| public void test030() { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X { \n" + |
| " public static void main(String[] args) { \n" + |
| " try { \n" + |
| " char[][] qName = null; \n" + |
| " qName[0] = new char[1]; \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " try { \n" + |
| " char[][] qName = (char[][])null; \n" + |
| " qName[0] = new char[1]; \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " try { \n" + |
| " char[][] qName = (char[][])(char[][])(char[][])null; \n" + |
| " qName[0] = new char[2]; \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " try { \n" + |
| " char[][] qName = args.length > 1 ? new char[1][2] : null; \n" + |
| " qName[0] = new char[3]; \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " System.out.println(\"SUCCESS\"); \n"+ |
| " } \n" + |
| "} \n", |
| }, |
| "SUCCESS"); |
| } |
| |
| /* |
| * verify error when assigning null to array |
| * http://bugs.eclipse.org/bugs/show_bug.cgi?id=26903 |
| */ |
| public void test031() { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X { \n" + |
| " public static void main(String[] args) { \n" + |
| " try { \n" + |
| " char[][] qName = null; \n" + |
| " setName(qName[0]); \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " try { \n" + |
| " char[][] qName = (char[][])null; \n" + |
| " setName(qName[0]); \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " try { \n" + |
| " char[][] qName = (char[][])(char[][])(char[][])null; \n" + |
| " setName(qName[0]); \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " try { \n" + |
| " char[][] qName = args.length > 1 ? new char[1][2] : null; \n" + |
| " setName(qName[0]); \n" + |
| " } catch(Exception e){ \n" + |
| " } \n" + |
| " System.out.println(\"SUCCESS\"); \n"+ |
| " } \n" + |
| " static void setName(char[] name) { \n"+ |
| " } \n" + |
| "} \n", |
| }, |
| "SUCCESS"); |
| } |
| /* |
| * verify error when assigning null to array |
| * http://bugs.eclipse.org/bugs/show_bug.cgi?id=26903 |
| */ |
| public void test032() { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " try {\n" + |
| " ((int[]) null)[0] = 0;\n" + |
| " ((int[]) null)[0] += 1;\n" + |
| " ((int[]) null)[0] ++;\n" + |
| " } catch (NullPointerException e) {\n" + |
| " System.out.print(\"SUCCESS\");\n" + |
| " }\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "SUCCESS"); |
| } |
| |
| /* |
| * unused cast diagnosis |
| * http://bugs.eclipse.org/bugs/show_bug.cgi?id=54763 |
| */ |
| public void test033() { |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| runNegativeTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "import java.util.ArrayList;\n" + |
| "import java.util.List;\n" + |
| "\n" + |
| "public class X {\n" + |
| " public static void main(String [] args) {\n" + |
| " List list = (List) new ArrayList();\n" + |
| " list = (List) new ArrayList();\n" + |
| " \n" + |
| " String s = (String) \"hello\";\n" + |
| " s += (List) new ArrayList();\n" + |
| " \n" + |
| " ArrayList alist = new ArrayList();\n" + |
| " List list2 = (List) alist;\n" + |
| " list2 = (List) alist;\n" + |
| " \n" + |
| " String s2 = (String) \"hello\";\n" + |
| " s2 += (List) alist;\n" + |
| " }\n" + |
| "}\n" |
| }, |
| // compiler options |
| null /* no class libraries */, |
| customOptions /* custom options */, |
| // compiler results |
| "----------\n" + /* expected compiler log */ |
| "1. ERROR in X.java (at line 6)\n" + |
| " List list = (List) new ArrayList();\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from ArrayList to List\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 7)\n" + |
| " list = (List) new ArrayList();\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from ArrayList to List\n" + |
| "----------\n" + |
| "3. ERROR in X.java (at line 9)\n" + |
| " String s = (String) \"hello\";\n" + |
| " ^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from String to String\n" + |
| "----------\n" + |
| "4. ERROR in X.java (at line 10)\n" + |
| " s += (List) new ArrayList();\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from ArrayList to List\n" + |
| "----------\n" + |
| "5. ERROR in X.java (at line 13)\n" + |
| " List list2 = (List) alist;\n" + |
| " ^^^^^^^^^^^^\n" + |
| "Unnecessary cast from ArrayList to List\n" + |
| "----------\n" + |
| "6. ERROR in X.java (at line 14)\n" + |
| " list2 = (List) alist;\n" + |
| " ^^^^^^^^^^^^\n" + |
| "Unnecessary cast from ArrayList to List\n" + |
| "----------\n" + |
| "7. ERROR in X.java (at line 16)\n" + |
| " String s2 = (String) \"hello\";\n" + |
| " ^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from String to String\n" + |
| "----------\n" + |
| "8. ERROR in X.java (at line 17)\n" + |
| " s2 += (List) alist;\n" + |
| " ^^^^^^^^^^^^\n" + |
| "Unnecessary cast from ArrayList to List\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); |
| } |
| /* |
| * check non insertion of checkcast for unnecessary cast to interfaces |
| * (same test case as test033) |
| */ |
| public void test034() throws Exception { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "import java.util.ArrayList;\n" + |
| "import java.util.List;\n" + |
| "\n" + |
| "public class X {\n" + |
| " public static void main(String [] args) {\n" + |
| " List list = (List) new ArrayList();\n" + |
| " list = (List) new ArrayList();\n" + |
| " \n" + |
| " ArrayList alist = new ArrayList();\n" + |
| " List list2 = (List) alist;\n" + |
| " list2 = (List) alist;\n" + |
| " \n" + |
| " System.out.println(\"SUCCESS\");\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "SUCCESS"); |
| |
| ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); |
| String actualOutput = |
| disassembler.disassemble( |
| classFileBytes, |
| "\n", |
| ClassFileBytesDisassembler.DETAILED); |
| |
| String expectedOutput = |
| " // Method descriptor #15 ([Ljava/lang/String;)V\n" + |
| " // Stack: 2, Locals: 4\n" + |
| " public static void main(java.lang.String[] args);\n" + |
| " 0 new java.util.ArrayList [16]\n" + |
| " 3 dup\n" + |
| " 4 invokespecial java.util.ArrayList() [18]\n" + |
| " 7 astore_1 [list]\n" + |
| " 8 new java.util.ArrayList [16]\n" + |
| " 11 dup\n" + |
| " 12 invokespecial java.util.ArrayList() [18]\n" + |
| " 15 astore_1 [list]\n" + |
| " 16 new java.util.ArrayList [16]\n" + |
| " 19 dup\n" + |
| " 20 invokespecial java.util.ArrayList() [18]\n" + |
| " 23 astore_2 [alist]\n" + |
| " 24 aload_2 [alist]\n" + |
| " 25 astore_3 [list2]\n" + |
| " 26 aload_2 [alist]\n" + |
| " 27 astore_3 [list2]\n" + |
| " 28 getstatic java.lang.System.out : java.io.PrintStream [19]\n" + |
| " 31 ldc <String \"SUCCESS\"> [25]\n" + |
| " 33 invokevirtual java.io.PrintStream.println(java.lang.String) : void [27]\n" + |
| " 36 return\n" + |
| " Line numbers:\n" + |
| " [pc: 0, line: 6]\n" + |
| " [pc: 8, line: 7]\n" + |
| " [pc: 16, line: 9]\n" + |
| " [pc: 24, line: 10]\n" + |
| " [pc: 26, line: 11]\n" + |
| " [pc: 28, line: 13]\n" + |
| " [pc: 36, line: 14]\n" + |
| " Local variable table:\n" + |
| " [pc: 0, pc: 37] local: args index: 0 type: java.lang.String[]\n" + |
| " [pc: 8, pc: 37] local: list index: 1 type: java.util.List\n" + |
| " [pc: 24, pc: 37] local: alist index: 2 type: java.util.ArrayList\n" + |
| " [pc: 26, pc: 37] local: list2 index: 3 type: java.util.List\n"; |
| int index = actualOutput.indexOf(expectedOutput); |
| if (index == -1 || expectedOutput.length() == 0) { |
| System.out.println(Util.displayString(actualOutput, 2)); |
| } |
| if (index == -1) { |
| assertEquals("Wrong contents", expectedOutput, actualOutput); |
| } |
| } |
| // javac incorrectly accepts it |
| public void test035() { |
| this.runNegativeTest( |
| new String[] { |
| "Test231.java", |
| "public class Test231 implements Test231i\n" + |
| "{\n" + |
| " void foo()\n" + |
| " {\n" + |
| " new Object()\n" + |
| " {\n" + |
| " Test231i bar()\n" + |
| " {\n" + |
| " return (Test231i)this;\n" + |
| " }\n" + |
| " };\n" + |
| " }\n" + |
| "}\n" + |
| "\n" + |
| "\n" + |
| "interface Test231i\n" + |
| "{\n" + |
| "}\n", |
| }, |
| "----------\n" + |
| "1. ERROR in Test231.java (at line 9)\n" + |
| " return (Test231i)this;\n" + |
| " ^^^^^^^^^^^^^^\n" + |
| "Cannot cast from new Object(){} to Test231i\n" + |
| "----------\n", |
| // javac options |
| JavacTestOptions.JavacHasABug.JavacBugFixed_6_10 /* javac test options */); |
| } |
| public void test036() { |
| runConformTest( |
| // test directory preparation |
| true /* flush output directory */, |
| new String[] { /* test files */ |
| "X.java", |
| "public final class X {\n" + |
| " private static final boolean DO_BUG = true;\n" + |
| "\n" + |
| " // Workaround: cast null to Base\n" + |
| " private static Base base = DO_BUG ?\n" + |
| " // (Base)null\n" + |
| " null : new Base() {\n" + |
| " public final String test() {\n" + |
| " return (\"anonymous\");\n" + |
| " }\n" + |
| " };\n" + |
| "\n" + |
| " private X() {\n" + |
| " }\n" + |
| "\n" + |
| " public static void main(String[] argv) {\n" + |
| " if (base == null)\n" + |
| " System.out.println(\"no base\");\n" + |
| " else\n" + |
| " System.out.println(base.test());\n" + |
| " }\n" + |
| "\n" + |
| " private static abstract class Base {\n" + |
| " public Base() {\n" + |
| " }\n" + |
| "\n" + |
| " public abstract String test();\n" + |
| " }\n" + |
| "}\n" |
| }, |
| // compiler results |
| "", /* expected compiler log */ |
| // runtime results |
| "no base" /* expected output string */, |
| "" /* expected error string */, |
| // javac options |
| JavacTestOptions.JavacHasABug.JavacGeneratesByteCodeUponWhichJavaThrowsAnException /* javac test options */); |
| } |
| public void test037() { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Integer[] integers = {};\n" + |
| " int[] ints = (int[]) integers;\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " int[] ints = (int[]) integers;\n" + |
| " ^^^^^^^^^^^^^^^^\n" + |
| "Cannot cast from Integer[] to int[]\n" + |
| "----------\n"); |
| } |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=101208 |
| public void test038() { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " void foo() {\n" + |
| " System.out.println(null instanceof Object);\n" + |
| " Zork z;\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\r\n" + |
| " Zork z;\r\n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n"); |
| } |
| //unnecessary cast warnings in assignment (Object o = (String) something). |
| public void test039() { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "import java.util.*;\n" + |
| "public class X {\n" + |
| " Object fo = (String) new Object();\n" + |
| " void foo(ArrayList al) {\n" + |
| " List l = (List) al;\n" + |
| " Object o;\n" + |
| " o = (ArrayList) al;\n" + |
| " Object o2 = (ArrayList) al;\n" + |
| " o = (ArrayList) l;\n" + |
| " Object o3 = (ArrayList) l;\n" + |
| " Zork z;\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. WARNING in X.java (at line 3)\n" + |
| " Object fo = (String) new Object();\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from Object to String\n" + |
| "----------\n" + |
| "2. WARNING in X.java (at line 5)\n" + |
| " List l = (List) al;\n" + |
| " ^^^^^^^^^\n" + |
| "Unnecessary cast from ArrayList to List\n" + |
| "----------\n" + |
| "3. WARNING in X.java (at line 7)\n" + |
| " o = (ArrayList) al;\n" + |
| " ^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from ArrayList to ArrayList\n" + |
| "----------\n" + |
| "4. WARNING in X.java (at line 8)\n" + |
| " Object o2 = (ArrayList) al;\n" + |
| " ^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from ArrayList to ArrayList\n" + |
| "----------\n" + |
| "5. WARNING in X.java (at line 9)\n" + |
| " o = (ArrayList) l;\n" + |
| " ^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from List to ArrayList\n" + |
| "----------\n" + |
| "6. WARNING in X.java (at line 10)\n" + |
| " Object o3 = (ArrayList) l;\n" + |
| " ^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from List to ArrayList\n" + |
| "----------\n" + |
| "7. ERROR in X.java (at line 11)\n" + |
| " Zork z;\n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n"); |
| } |
| //http://bugs.eclipse.org/bugs/show_bug.cgi?id=116647 |
| public void test040() { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " {\n" + |
| " int i = 12;\n" + |
| " int j = (byte) i;\n" + |
| " float f = (float) i;\n" + |
| " Zork z;\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. WARNING in X.java (at line 5)\n" + |
| " float f = (float) i;\n" + |
| " ^^^^^^^^^\n" + |
| "Unnecessary cast from int to float\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 6)\n" + |
| " Zork z;\n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n"); |
| } |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=158855 |
| public void test041() { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public abstract class X {\n" + |
| " class A extends X {\n" + |
| " public void callMe() {\n" + |
| " }\n" + |
| " }\n" + |
| " public abstract void callMe();\n" + |
| " class B {\n" + |
| " public void callSite() {\n" + |
| " // expect warning not there:\n" + |
| " ((A) this.getAA()).callMe();\n" + |
| " Integer max = Integer.valueOf(1);\n" + |
| " // execpted warning there:\n" + |
| " Integer other = (Integer) max;\n" + |
| " }\n" + |
| " public X getAA() {\n" + |
| " Zork z;\n" + |
| " return null;\n" + |
| " }\n" + |
| " }\n" + |
| "}", // ================= |
| }, |
| "----------\n" + |
| "1. WARNING in X.java (at line 13)\n" + |
| " Integer other = (Integer) max;\n" + |
| " ^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from Integer to Integer\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 16)\n" + |
| " Zork z;\n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n"); |
| } |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=159654 |
| public void test042() { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "import java.util.List;\n" + |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " System.out.print(\"SUCCESS\"); \n" + |
| " }\n" + |
| " \n" + |
| " public static void foo(boolean b, List l) {\n" + |
| " if (b) {\n" + |
| " String s = (String) l.get(0);\n" + |
| " }\n" + |
| " }\n" + |
| "}", |
| }, |
| "SUCCESS"); |
| } |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=159654 |
| public void test043() { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "import java.util.List;\n" + |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " System.out.print(\"SUCCESS\"); \n" + |
| " }\n" + |
| " \n" + |
| " public static void foo(boolean b, List l) {\n" + |
| " if (b) {\n" + |
| " Object o = (Object) l.get(0);\n" + |
| " }\n" + |
| " }\n" + |
| "}", |
| }, |
| "SUCCESS"); |
| } |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=159822 |
| public void test044() { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static String s;\n" + |
| " public static void main(String[] args) throws Throwable {\n" + |
| " if (args.length == 0) {\n" + |
| " Class c = Class.forName(\"X\");\n" + |
| " String s = ((X) c.newInstance()).s;\n" + |
| " System.out.println(s);\n" + |
| " }\n" + |
| " System.out.println();\n" + |
| " }\n" + |
| "}", |
| }, |
| "null"); |
| } |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=239305 |
| public void test045() { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " System.out.println(castLongToInt(3));\n" + |
| " }\n" + |
| " private static int castLongToInt(long longVal) {\n" + |
| " return (int)((long)longVal);\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "3"); |
| } |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=282869 |
| public void test046() { |
| this.runConformTest( |
| true, |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " char a = 65;\n" + |
| " String b = \"\" + a; // -> \"A\"\n" + |
| " String c = \"\" + (int) a;\n" + |
| " System.out.print(b);\n" + |
| " System.out.print(c);\n" + |
| " \n" + |
| " String logText = \" second case \";\n" + |
| " char firstChar = 65;\n" + |
| " logText += (int) firstChar;\n" + |
| " System.out.println(logText);\n" + |
| " }\n" + |
| "}", |
| }, |
| "", |
| "A65 second case 65", |
| "", |
| JavacTestOptions.SKIP); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=287676 |
| // Test to make sure that an unnecessary cast warning is produced in case of |
| // wrapper types like Integer, Character, Short, Byte, etc. |
| public void test047() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| if (options.sourceLevel < ClassFileConstants.JDK1_5) return; |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "import java.util.ArrayList;\n" + |
| "public class X{\n" + |
| " void test() {" + |
| " Integer a = 1;\n" + |
| " ArrayList<Character> aList = new ArrayList<Character>(1);\n" + |
| " a = (Integer)a + (Integer)2;\n" + |
| " if ((Character)aList.get(0) == 'c')\n" + |
| " System.out.println();\n" + |
| " }\n" + |
| "}" |
| }, |
| "----------\n" + |
| "1. WARNING in X.java (at line 5)\n" + |
| " a = (Integer)a + (Integer)2;\n" + |
| " ^^^^^^^^^^\n" + |
| "Unnecessary cast from Integer to Integer\n" + |
| "----------\n" + |
| "2. WARNING in X.java (at line 5)\n" + |
| " a = (Integer)a + (Integer)2;\n" + |
| " ^^^^^^^^^^\n" + |
| "Unnecessary cast from int to Integer\n" + |
| "----------\n" + |
| "3. WARNING in X.java (at line 6)\n" + |
| " if ((Character)aList.get(0) == 'c')\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from Character to Character\n" + |
| "----------\n" |
| ); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=302919 |
| public void test048() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| if (options.sourceLevel < ClassFileConstants.JDK1_5) return; |
| this.runNegativeTest( |
| new String[] { |
| "A.java", |
| "public class A<T> extends D<T> {\n" + |
| " public class A1 extends D1 {\n" + |
| " }\n" + |
| " void m1(A<T> tree) {\n" + |
| " A.A1 v = ((A.A1) tree.root);\n" + |
| " }\n" + |
| " Zork z;\n" + |
| "}\n" + |
| "class D<T> {\n" + |
| " protected D1 root;\n" + |
| " protected class D1 {\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in A.java (at line 7)\n" + |
| " Zork z;\n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=302919 |
| public void test049() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| if (options.sourceLevel < ClassFileConstants.JDK1_5) return; |
| this.runNegativeTest( |
| new String[] { |
| "A.java", |
| "public class A {\n" + |
| " void foo(Other2<?>.Member2<?> om2) {\n" + |
| " Other<?>.Member m = (Other<?>.Member) om2;\n" + |
| " m = om2;\n" + |
| " }\n" + |
| "}\n" + |
| "class Other<T> {\n" + |
| " class Member {}\n" + |
| "}\n" + |
| "class Other2<T> extends Other<T> {\n" + |
| " class Member2<U> extends Other<U>.Member {\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. WARNING in A.java (at line 3)\n" + |
| " Other<?>.Member m = (Other<?>.Member) om2;\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from Other2<?>.Member2<capture#1-of ?> to Other<?>.Member\n" + |
| "----------\n" |
| ); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=302919 |
| public void test050() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| if (options.sourceLevel < ClassFileConstants.JDK1_5) return; |
| this.runNegativeTest( |
| new String[] { |
| "A.java", |
| "public class A<T> extends D<T> {\n" + |
| " public class A1 extends D.D1 {\n" + |
| " }\n" + |
| " void m1(A<T> tree) {\n" + |
| " A.A1 v = ((A.A1) tree.root);\n" + |
| " }\n" + |
| " Zork z;\n" + |
| "}\n" + |
| "class D<T> {\n" + |
| " protected D1 root;\n" + |
| " protected class D1 {\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in A.java (at line 7)\n" + |
| " Zork z;\n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test051() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " boolean y = (boolean) x;\n" + |
| " System.out.println(y);\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Boolean.TRUE;\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " boolean y = (boolean) x;\n" + |
| " ^^^^^^^^^^^\n" + |
| "Cannot cast from Object to boolean\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "true" |
| ); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test052() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " byte y = (byte) x;\n" + |
| " System.out.println(y);\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Byte.valueOf((byte)1);\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " byte y = (byte) x;\n" + |
| " ^^^^^^^^\n" + |
| "Cannot cast from Object to byte\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "1" |
| ); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test053() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " char y = (char) x;\n" + |
| " System.out.println(y);\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Character.valueOf('d');\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " char y = (char) x;\n" + |
| " ^^^^^^^^\n" + |
| "Cannot cast from Object to char\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "d" |
| ); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| // Also confirm that a check cast and unboxing conversion are generated. |
| public void test054() throws Exception { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " int y = (int) x;\n" + |
| " System.out.println(y);\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Integer.valueOf(1);\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " int y = (int) x;\n" + |
| " ^^^^^^^\n" + |
| "Cannot cast from Object to int\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "1" |
| ); |
| String expectedOutput = |
| " // Method descriptor #15 ([Ljava/lang/String;)V\n" + |
| " // Stack: 2, Locals: 3\n" + |
| " public static void main(java.lang.String[] args);\n" + |
| " 0 invokestatic X.foo() : java.lang.Object [16]\n" + |
| " 3 astore_1 [x]\n" + |
| " 4 aload_1 [x]\n" + |
| " 5 checkcast java.lang.Integer [20]\n" + |
| " 8 invokevirtual java.lang.Integer.intValue() : int [22]\n" + |
| " 11 istore_2 [y]\n" + |
| " 12 getstatic java.lang.System.out : java.io.PrintStream [26]\n" + |
| " 15 iload_2 [y]\n" + |
| " 16 invokevirtual java.io.PrintStream.println(int) : void [32]\n" + |
| " 19 return\n" + |
| " Line numbers:\n" + |
| " [pc: 0, line: 3]\n" + |
| " [pc: 4, line: 4]\n" + |
| " [pc: 12, line: 5]\n" + |
| " [pc: 19, line: 6]\n" + |
| " Local variable table:\n" + |
| " [pc: 0, pc: 20] local: args index: 0 type: java.lang.String[]\n" + |
| " [pc: 4, pc: 20] local: x index: 1 type: java.lang.Object\n" + |
| " [pc: 12, pc: 20] local: y index: 2 type: int\n" + |
| " \n"; |
| File f = new File(OUTPUT_DIR + File.separator + "X.class"); |
| byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f); |
| ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED); |
| int index = result.indexOf(expectedOutput); |
| if (index == -1 || expectedOutput.length() == 0) { |
| System.out.println(Util.displayString(result, 3)); |
| } |
| if (index == -1) { |
| assertEquals("Wrong contents", expectedOutput, result); |
| } |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test055() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " long y = (long) x;\n" + |
| " System.out.println(y);\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Long.valueOf(Long.MAX_VALUE);\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " long y = (long) x;\n" + |
| " ^^^^^^^^\n" + |
| "Cannot cast from Object to long\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "9223372036854775807" |
| ); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test056() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " short y = (short) x;\n" + |
| " System.out.println(y);\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Short.valueOf((short) 1);\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " short y = (short) x;\n" + |
| " ^^^^^^^^^\n" + |
| "Cannot cast from Object to short\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "1" |
| ); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test057() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " double y = (double) x;\n" + |
| " System.out.println(y);\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Double.valueOf(1.0);\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " double y = (double) x;\n" + |
| " ^^^^^^^^^^\n" + |
| "Cannot cast from Object to double\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "1.0" |
| ); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test058() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " float y = (float) x;\n" + |
| " System.out.println(y);\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Float.valueOf(1.0f);\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 4)\n" + |
| " float y = (float) x;\n" + |
| " ^^^^^^^^^\n" + |
| "Cannot cast from Object to float\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "1.0" |
| ); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test059() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " try {\n" + |
| " int y = (int) x;\n" + |
| " } catch (ClassCastException e) {\n" + |
| " System.out.println(\"SUCCESS\");\n" + |
| " return;\n" + |
| " }\n" + |
| " System.out.println(\"FAIL\");\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Float.valueOf(1.0f);\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 5)\n" + |
| " int y = (int) x;\n" + |
| " ^^^^^^^\n" + |
| "Cannot cast from Object to int\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "SUCCESS" |
| ); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test059b() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " try {\n" + |
| " int y = (int) x;\n" + |
| " } catch (ClassCastException e) {\n" + |
| " System.out.println(\"SUCCESS\");\n" + |
| " return;\n" + |
| " }\n" + |
| " System.out.println(\"FAIL\");\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Boolean.TRUE;\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 5)\n" + |
| " int y = (int) x;\n" + |
| " ^^^^^^^\n" + |
| "Cannot cast from Object to int\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "SUCCESS" |
| ); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test059c() { |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " try {\n" + |
| " char y = (char) x;\n" + |
| " } catch (ClassCastException e) {\n" + |
| " System.out.println(\"SUCCESS\");\n" + |
| " return;\n" + |
| " }\n" + |
| " System.out.println(\"FAIL\");\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Boolean.TRUE;\n" + |
| " }\n" + |
| "}"; |
| if (options.sourceLevel < ClassFileConstants.JDK1_7) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 5)\n" + |
| " char y = (char) x;\n" + |
| " ^^^^^^^^\n" + |
| "Cannot cast from Object to char\n" + |
| "----------\n" |
| ); |
| } else { |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "SUCCESS" |
| ); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test060() { |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " Boolean y = (Boolean) x;\n" + |
| " System.out.println(y);\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Boolean.TRUE;\n" + |
| " }\n" + |
| "}"; |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "true" |
| ); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085 |
| public void test061() { |
| String source = |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Object x = foo();\n" + |
| " try {\n" + |
| " Float y = (Float) x;\n" + |
| " } catch (ClassCastException e) {\n" + |
| " System.out.println(\"SUCCESS\");\n" + |
| " return;\n" + |
| " }\n" + |
| " System.out.println(\"FAIL\");\n" + |
| " }\n" + |
| " public static Object foo() {\n" + |
| " return Boolean.TRUE;\n" + |
| " }\n" + |
| "}"; |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "SUCCESS" |
| ); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=359284 |
| // Verify that checkcast is emitted for a cast expression. |
| public void test061b() throws Exception { |
| String source = |
| "public class X {\n" + |
| "public X() {\n" + |
| " Object[] x = (Object[])null;\n" + |
| "}\n" + |
| "}\n"; |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| source |
| }, |
| "" |
| ); |
| String expectedOutput = |
| "public class X {\n" + |
| " \n" + |
| " // Method descriptor #6 ()V\n" + |
| " // Stack: 1, Locals: 2\n" + |
| " public X();\n" + |
| " 0 aload_0 [this]\n" + |
| " 1 invokespecial java.lang.Object() [8]\n" + |
| " 4 aconst_null\n" + |
| " 5 checkcast java.lang.Object[] [10]\n" + |
| " 8 astore_1 [x]\n" + |
| " 9 return\n" + |
| " Line numbers:\n" + |
| " [pc: 0, line: 2]\n" + |
| " [pc: 4, line: 3]\n" + |
| " [pc: 9, line: 4]\n" + |
| " Local variable table:\n" + |
| " [pc: 0, pc: 10] local: this index: 0 type: X\n" + |
| " [pc: 9, pc: 10] local: x index: 1 type: java.lang.Object[]\n" + |
| "}"; |
| File f = new File(OUTPUT_DIR + File.separator + "X.class"); |
| byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f); |
| ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED); |
| int index = result.indexOf(expectedOutput); |
| if (index == -1 || expectedOutput.length() == 0) { |
| System.out.println(Util.displayString(result, 3)); |
| } |
| if (index == -1) { |
| assertEquals("Wrong contents", expectedOutput, result); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=420283, [1.8] Wrong error "Type is not visible" for cast to intersection type |
| public void test420283() { |
| if (this.complianceLevel < ClassFileConstants.JDK1_5) |
| return; |
| if (this.complianceLevel < ClassFileConstants.JDK1_8) { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "import java.io.Serializable;\n" + |
| "import java.util.List;\n" + |
| "public class X {\n" + |
| " void foo(List<Integer> l) {\n" + |
| " Integer i = (Integer & Serializable) l.get(0);\n" + |
| " }\n" + |
| " public static void main(String [] args) {\n" + |
| " System.out.println(\"SUCCESS\");\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. WARNING in X.java (at line 5)\n" + |
| " Integer i = (Integer & Serializable) l.get(0);\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from Integer to Integer & Serializable\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 5)\n" + |
| " Integer i = (Integer & Serializable) l.get(0);\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Additional bounds are not allowed in cast operator at source levels below 1.8\n" + |
| "----------\n"); |
| return; |
| } |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "import java.io.Serializable;\n" + |
| "import java.util.List;\n" + |
| "public class X {\n" + |
| " void foo(List<Integer> l) {\n" + |
| " Integer i = (Integer & Serializable) l.get(0);\n" + |
| " }\n" + |
| " public static void main(String [] args) {\n" + |
| " System.out.println(\"SUCCESS\");\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "SUCCESS" |
| ); |
| } |
| |
| public void testBug428274() { |
| String source = |
| "public class Junk4 {\n" + |
| " static void setValue(Number n) {\n" + |
| " int rounded = (int) Math.round((double) n);\n" + |
| " System.out.println(rounded);\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " setValue(Double.valueOf(3.3));\n" + |
| " setValue(Double.valueOf(3.7));\n" + |
| " }\n" + |
| "}\n"; |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) { |
| runNegativeTest( |
| new String[] { |
| "Junk4.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in Junk4.java (at line 3)\n" + |
| " int rounded = (int) Math.round((double) n);\n" + |
| " ^^^^^^^^^^\n" + |
| "Cannot cast from Number to double\n" + |
| "----------\n"); |
| } else { |
| runConformTest( |
| new String[] { |
| "Junk4.java", |
| source |
| }, |
| "3\n4"); |
| } |
| } |
| public void testBug428274b() { |
| if (this.complianceLevel < ClassFileConstants.JDK1_5) |
| return; // uses generics |
| String source = |
| "public class Junk4<T> {\n" + |
| " void setValue(T n) {\n" + |
| " int rounded = (int) Math.round((double) n);\n" + |
| " System.out.println(rounded);\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " Junk4<Number> j = new Junk4<Number>();\n" + |
| " j.setValue(Double.valueOf(3.3));\n" + |
| " j.setValue(Double.valueOf(3.7));\n" + |
| " }\n" + |
| "}\n"; |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) { |
| runNegativeTest( |
| new String[] { |
| "Junk4.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in Junk4.java (at line 3)\n" + |
| " int rounded = (int) Math.round((double) n);\n" + |
| " ^^^^^^^^^^\n" + |
| "Cannot cast from T to double\n" + |
| "----------\n"); |
| } else { |
| runConformTest( |
| new String[] { |
| "Junk4.java", |
| source |
| }, |
| "3\n4"); |
| } |
| } |
| // note: spec allows all reference types, but neither javac nor common sense accept arrays :) |
| public void testBug428274c() { |
| String source = |
| "public class Junk4 {\n" + |
| " static void setValue(Object[] n) {\n" + |
| " int rounded = (int) Math.round((double) n);\n" + |
| " System.out.println(rounded);\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " setValue(new Double[] { Double.valueOf(3.3) });\n" + |
| " }\n" + |
| "}\n"; |
| runNegativeTest( |
| new String[] { |
| "Junk4.java", |
| source |
| }, |
| "----------\n" + |
| "1. ERROR in Junk4.java (at line 3)\n" + |
| " int rounded = (int) Math.round((double) n);\n" + |
| " ^^^^^^^^^^\n" + |
| "Cannot cast from Object[] to double\n" + |
| "----------\n"); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388() { |
| runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " int x = (int) \"Hello\";\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 3)\n" + |
| " int x = (int) \"Hello\";\n" + |
| " ^^^^^^^^^^^^^\n" + |
| "Cannot cast from String to int\n" + |
| "----------\n"); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388a() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " static void setValue(Number n) {\n" + |
| " int rounded = (int) Math.round((double) n);\n" + |
| " System.out.println(rounded);\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " setValue(Double.valueOf(3.3));\n" + |
| " setValue(Double.valueOf(3.7));\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "3\n4"); |
| |
| ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); |
| String actualOutput = |
| disassembler.disassemble( |
| classFileBytes, |
| "\n", |
| ClassFileBytesDisassembler.DETAILED); |
| |
| String expectedOutput = |
| " // Method descriptor #15 (Ljava/lang/Number;)V\n" + |
| " // Stack: 2, Locals: 2\n" + |
| " static void setValue(java.lang.Number n);\n" + |
| " 0 aload_0 [n]\n" + |
| " 1 checkcast java.lang.Double [16]\n" + |
| " 4 invokevirtual java.lang.Double.doubleValue() : double [18]\n" + |
| " 7 invokestatic java.lang.Math.round(double) : long [22]\n" + |
| " 10 l2i\n" + |
| " 11 istore_1 [rounded]\n" + |
| " 12 getstatic java.lang.System.out : java.io.PrintStream [28]\n" + |
| " 15 iload_1 [rounded]\n" + |
| " 16 invokevirtual java.io.PrintStream.println(int) : void [34]\n" + |
| " 19 return\n" + |
| " Line numbers:\n" + |
| " [pc: 0, line: 3]\n" + |
| " [pc: 12, line: 4]\n" + |
| " [pc: 19, line: 5]\n" + |
| " Local variable table:\n" + |
| " [pc: 0, pc: 20] local: n index: 0 type: java.lang.Number\n" + |
| " [pc: 12, pc: 20] local: rounded index: 1 type: int\n" + |
| " \n"; |
| int index = actualOutput.indexOf(expectedOutput); |
| if (index == -1 || expectedOutput.length() == 0) { |
| System.out.println(Util.displayString(actualOutput, 2)); |
| } |
| if (index == -1) { |
| assertEquals("Wrong contents", expectedOutput, actualOutput); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388b() throws Exception { |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " static void setValue(Number n) {\n" + |
| " char rounded = (char) n;\n" + |
| " System.out.println(rounded);\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " setValue(Double.valueOf(3.3));\n" + |
| " setValue(Double.valueOf(3.7));\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "----------\n" + |
| "1. ERROR in X.java (at line 3)\n" + |
| " char rounded = (char) n;\n" + |
| " ^^^^^^^^\n" + |
| "Cannot cast from Number to char\n" + |
| "----------\n"); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388c() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " static void setValue(Number n) {\n" + |
| " try {\n" + |
| " byte rounded = (byte) n;\n" + |
| " System.out.println(rounded);\n" + |
| " } catch (ClassCastException c) {\n" + |
| " System.out.println(\"CCE\");\n" + |
| " }\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " setValue(Double.valueOf(3.3));\n" + |
| " setValue(Double.valueOf(3.7));\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "CCE\nCCE"); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388d() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "import java.io.Serializable;\n" + |
| "public class X implements Serializable {\n" + |
| " static int test(Serializable v) {\n" + |
| " try {\n" + |
| " return (int)v;\n" + |
| " } catch (ClassCastException c) {\n" + |
| " System.out.println(\"CCE\");\n" + |
| " }\n" + |
| " return -1;\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " int i = test(new X());\n" + |
| " System.out.println(i);\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "CCE\n-1"); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388e() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "import java.io.Serializable;\n" + |
| "public class X implements Serializable {\n" + |
| " static int test(Serializable v) {\n" + |
| " try {\n" + |
| " return (int)v;\n" + |
| " } catch (ClassCastException c) {\n" + |
| " System.out.println(\"CCE\");\n" + |
| " }\n" + |
| " return -1;\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " int i = test(new Long(1234));\n" + |
| " System.out.println(i);\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "CCE\n-1"); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388f() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "import java.io.Serializable;\n" + |
| "public class X implements Serializable {\n" + |
| " static int test(Serializable v) {\n" + |
| " try {\n" + |
| " return (int)v;\n" + |
| " } catch (ClassCastException c) {\n" + |
| " System.out.println(\"CCE\");\n" + |
| " }\n" + |
| " return -1;\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " int i = test(new Integer(1234));\n" + |
| " System.out.println(i);\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "1234"); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388g() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "import java.io.Serializable;\n" + |
| "public class X implements Serializable {\n" + |
| " static <S extends Boolean & Serializable>int test(S b) {\n" + |
| " return (int) b;\n" + |
| " }\n" + |
| "\n" + |
| " public static void main(String[] args) {\n" + |
| " int i = test(Boolean.TRUE);\n" + |
| " System.out.println(i);\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "----------\n" + |
| "1. WARNING in X.java (at line 2)\n" + |
| " public class X implements Serializable {\n" + |
| " ^\n" + |
| "The serializable class X does not declare a static final serialVersionUID field of type long\n" + |
| "----------\n" + |
| "2. WARNING in X.java (at line 3)\n" + |
| " static <S extends Boolean & Serializable>int test(S b) {\n" + |
| " ^^^^^^^\n" + |
| "The type parameter S should not be bounded by the final type Boolean. Final types cannot be further extended\n" + |
| "----------\n" + |
| "3. ERROR in X.java (at line 4)\n" + |
| " return (int) b;\n" + |
| " ^^^^^^^\n" + |
| "Cannot cast from S to int\n" + |
| "----------\n"); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388h() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_8) |
| return; // uses intersection cast |
| this.runNegativeTest( |
| new String[] { |
| "X.java", |
| "import java.io.Serializable;\n" + |
| "public class X implements Serializable {\n" + |
| " static int test(Serializable b) {\n" + |
| " return (int) (Boolean & Serializable) b;\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " int i = test(Boolean.TRUE);\n" + |
| " System.out.println(i);\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "----------\n" + |
| "1. WARNING in X.java (at line 2)\n" + |
| " public class X implements Serializable {\n" + |
| " ^\n" + |
| "The serializable class X does not declare a static final serialVersionUID field of type long\n" + |
| "----------\n" + |
| "2. ERROR in X.java (at line 4)\n" + |
| " return (int) (Boolean & Serializable) b;\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Cannot cast from Boolean & Serializable to int\n" + |
| "----------\n"); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388i() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "import java.io.Serializable;\n" + |
| "public class X implements Serializable {\n" + |
| " static int test(Serializable v) {\n" + |
| " try {\n" + |
| " return (int)v;\n" + |
| " } catch (ClassCastException c) {\n" + |
| " System.out.println(\"CCE\");\n" + |
| " }\n" + |
| " return -1;\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " int i = test(new Integer(1234));\n" + |
| " System.out.println(i);\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "1234"); |
| ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); |
| String actualOutput = |
| disassembler.disassemble( |
| classFileBytes, |
| "\n", |
| ClassFileBytesDisassembler.DETAILED); |
| |
| String expectedOutput = |
| " // Method descriptor #17 (Ljava/io/Serializable;)I\n" + |
| " // Stack: 2, Locals: 2\n" + |
| " static int test(java.io.Serializable v);\n" + |
| " 0 aload_0 [v]\n" + |
| " 1 checkcast java.lang.Integer [18]\n" + |
| " 4 invokevirtual java.lang.Integer.intValue() : int [20]\n" + |
| " 7 ireturn\n" + |
| " 8 astore_1 [c]\n" + |
| " 9 getstatic java.lang.System.out : java.io.PrintStream [24]\n" + |
| " 12 ldc <String \"CCE\"> [30]\n" + |
| " 14 invokevirtual java.io.PrintStream.println(java.lang.String) : void [32]\n" + |
| " 17 iconst_m1\n" + |
| " 18 ireturn\n"; |
| |
| int index = actualOutput.indexOf(expectedOutput); |
| if (index == -1 || expectedOutput.length() == 0) { |
| System.out.println(Util.displayString(actualOutput, 2)); |
| } |
| if (index == -1) { |
| assertEquals("Wrong contents", expectedOutput, actualOutput); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428388, [1.8][compiler] Casting to primitives is over tolerant - probable regression since bug 428274 |
| public void test428388j() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_8) |
| return; // uses intersection cast |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "import java.io.Serializable;\n" + |
| "public class X implements Serializable {\n" + |
| " static int test(Serializable b) {\n" + |
| " return (int) (Integer & Serializable) b;\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " int i = test(10101010);\n" + |
| " System.out.println(i);\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "10101010"); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428522, [1.8] VerifyError when a non primitive type cast to primitive type |
| public void test428522() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String args[]) {\n" + |
| " long l = (long) ((Object) 100L);\n" + |
| " System.out.println(\"OK\");\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "OK", customOptions); |
| ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); |
| String actualOutput = |
| disassembler.disassemble( |
| classFileBytes, |
| "\n", |
| ClassFileBytesDisassembler.DETAILED); |
| |
| String expectedOutput = |
| " // Method descriptor #15 ([Ljava/lang/String;)V\n" + |
| " // Stack: 2, Locals: 1\n" + |
| " public static void main(java.lang.String[] args);\n" + |
| " 0 ldc2_w <Long 100> [16]\n" + |
| " 3 invokestatic java.lang.Long.valueOf(long) : java.lang.Long [18]\n" + |
| " 6 checkcast java.lang.Long [19]\n" + |
| " 9 invokevirtual java.lang.Long.longValue() : long [24]\n" + |
| " 12 pop2\n" + |
| " 13 getstatic java.lang.System.out : java.io.PrintStream [28]\n" + |
| " 16 ldc <String \"OK\"> [34]\n" + |
| " 18 invokevirtual java.io.PrintStream.println(java.lang.String) : void [36]\n" + |
| " 21 return\n" + |
| " Line numbers:\n" + |
| " [pc: 0, line: 3]\n" + |
| " [pc: 13, line: 4]\n" + |
| " [pc: 21, line: 5]\n" + |
| " Local variable table:\n" + |
| " [pc: 0, pc: 22] local: args index: 0 type: java.lang.String[]\n" + |
| "}"; |
| int index = actualOutput.indexOf(expectedOutput); |
| if (index == -1 || expectedOutput.length() == 0) { |
| System.out.println(Util.displayString(actualOutput, 2)); |
| } |
| if (index == -1) { |
| assertEquals("Wrong contents", expectedOutput, actualOutput); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428522, [1.8] VerifyError when a non primitive type cast to primitive type |
| public void test428522a() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE); |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String args[]) {\n" + |
| " long l = (long) ((Object) 100L);\n" + |
| " System.out.println(\"OK\");\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "OK", customOptions); |
| ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); |
| String actualOutput = |
| disassembler.disassemble( |
| classFileBytes, |
| "\n", |
| ClassFileBytesDisassembler.DETAILED); |
| |
| String expectedOutput = |
| " // Method descriptor #15 ([Ljava/lang/String;)V\n" + |
| " // Stack: 2, Locals: 3\n" + |
| " public static void main(java.lang.String[] args);\n" + |
| " 0 ldc2_w <Long 100> [16]\n" + |
| " 3 invokestatic java.lang.Long.valueOf(long) : java.lang.Long [18]\n" + |
| " 6 checkcast java.lang.Long [19]\n" + |
| " 9 invokevirtual java.lang.Long.longValue() : long [24]\n" + |
| " 12 lstore_1 [l]\n" + |
| " 13 getstatic java.lang.System.out : java.io.PrintStream [28]\n" + |
| " 16 ldc <String \"OK\"> [34]\n" + |
| " 18 invokevirtual java.io.PrintStream.println(java.lang.String) : void [36]\n" + |
| " 21 return\n" + |
| " Line numbers:\n" + |
| " [pc: 0, line: 3]\n" + |
| " [pc: 13, line: 4]\n" + |
| " [pc: 21, line: 5]\n" + |
| " Local variable table:\n" + |
| " [pc: 0, pc: 22] local: args index: 0 type: java.lang.String[]\n" + |
| " [pc: 13, pc: 22] local: l index: 1 type: long\n" + |
| "}"; |
| int index = actualOutput.indexOf(expectedOutput); |
| if (index == -1 || expectedOutput.length() == 0) { |
| System.out.println(Util.displayString(actualOutput, 2)); |
| } |
| if (index == -1) { |
| assertEquals("Wrong contents", expectedOutput, actualOutput); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428522, [1.8] VerifyError when a non primitive type cast to primitive type |
| public void test428522b() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String args[]) {\n" + |
| " try {\n" + |
| " int l = (int) ((Object) 100L);\n" + |
| " } catch (ClassCastException c) {\n" + |
| " System.out.println(\"CCE:OK\");\n" + |
| " }\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "CCE:OK", customOptions); |
| |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428522, [1.8] VerifyError when a non primitive type cast to primitive type |
| public void test428522c() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| " public static void main(String args[]) {\n" + |
| " int l = (int) ((Object) 100);\n" + |
| " System.out.println(\"OK\");\n" + |
| " }\n" + |
| "}\n", |
| }, |
| "OK", customOptions); |
| ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); |
| String actualOutput = |
| disassembler.disassemble( |
| classFileBytes, |
| "\n", |
| ClassFileBytesDisassembler.DETAILED); |
| |
| String expectedOutput = |
| " // Method descriptor #15 ([Ljava/lang/String;)V\n" + |
| " // Stack: 2, Locals: 1\n" + |
| " public static void main(java.lang.String[] args);\n" + |
| " 0 bipush 100\n" + |
| " 2 invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [16]\n" + |
| " 5 checkcast java.lang.Integer [17]\n" + |
| " 8 invokevirtual java.lang.Integer.intValue() : int [22]\n" + |
| " 11 pop\n" + |
| " 12 getstatic java.lang.System.out : java.io.PrintStream [26]\n" + |
| " 15 ldc <String \"OK\"> [32]\n" + |
| " 17 invokevirtual java.io.PrintStream.println(java.lang.String) : void [34]\n" + |
| " 20 return\n" + |
| " Line numbers:\n" + |
| " [pc: 0, line: 3]\n" + |
| " [pc: 12, line: 4]\n" + |
| " [pc: 20, line: 5]\n" + |
| " Local variable table:\n" + |
| " [pc: 0, pc: 21] local: args index: 0 type: java.lang.String[]\n" + |
| "}"; |
| int index = actualOutput.indexOf(expectedOutput); |
| if (index == -1 || expectedOutput.length() == 0) { |
| System.out.println(Util.displayString(actualOutput, 2)); |
| } |
| if (index == -1) { |
| assertEquals("Wrong contents", expectedOutput, actualOutput); |
| } |
| } |
| |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=441731 JDT reports unnecessary cast, using the Quickfix to remove it creates syntax error |
| public void test441731() { |
| if (this.complianceLevel < ClassFileConstants.JDK1_5) |
| return; |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "interface MUIElement {}\n" + |
| "interface MUIElementContainer<T extends MUIElement> extends MUIElement{}\n" + |
| "interface MWindowElement extends MUIElement {}\n" + |
| "interface MWindow extends MUIElementContainer<MWindowElement> {}\n" + |
| "public class X {\n" + |
| " void test(MUIElementContainer<MUIElement> me) {\n" + |
| " if(((MUIElement) me) instanceof MWindow) return;\n" + |
| " MWindow mw = (MWindow)((MUIElement)me);\n" + |
| " }\n" + |
| "}\n" |
| }, |
| customOptions); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=448112, [compiler] Compiler crash (ArrayIndexOutOfBoundsException at StackMapFrame.addStackItem()) with unused variable |
| public void test448112() throws Exception { |
| if (this.complianceLevel < ClassFileConstants.JDK1_7) |
| return; |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); |
| this.runConformTest( |
| new String[] { |
| "X.java", |
| "public class X {\n" + |
| "\n" + |
| " static class Y {\n" + |
| " public Object getAttribute(String name) {\n" + |
| " return new Long(100L);\n" + |
| " }\n" + |
| " }\n" + |
| " public static void foo2(Y y) {\n" + |
| "\n" + |
| " try {\n" + |
| " long v1 = (Long) y.getAttribute(\"v1\");\n" + |
| " long v2 = (Long) y.getAttribute(\"v2\");\n" + |
| "\n" + |
| " System.out.println(String.valueOf(v1));\n" + |
| "\n" + |
| " } catch (java.lang.Throwable t) {}\n" + |
| " }\n" + |
| " \n" + |
| " public static void main(String args[]) {\n" + |
| " foo2(new Y());\n" + |
| " }\n" + |
| "}", |
| }, |
| "100", customOptions); |
| ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); |
| String actualOutput = |
| disassembler.disassemble( |
| classFileBytes, |
| "\n", |
| ClassFileBytesDisassembler.DETAILED); |
| |
| String expectedOutput = |
| " public static void foo2(X.Y y);\n" + |
| " 0 aload_0 [y]\n" + |
| " 1 ldc <String \"v1\"> [16]\n" + |
| " 3 invokevirtual X$Y.getAttribute(java.lang.String) : java.lang.Object [18]\n" + |
| " 6 checkcast java.lang.Long [24]\n" + |
| " 9 invokevirtual java.lang.Long.longValue() : long [26]\n" + |
| " 12 lstore_1 [v1]\n" + |
| " 13 aload_0 [y]\n" + |
| " 14 ldc <String \"v2\"> [30]\n" + |
| " 16 invokevirtual X$Y.getAttribute(java.lang.String) : java.lang.Object [18]\n" + |
| " 19 checkcast java.lang.Long [24]\n" + |
| " 22 pop\n" + |
| " 23 getstatic java.lang.System.out : java.io.PrintStream [32]\n" + |
| " 26 lload_1 [v1]\n" + |
| " 27 invokestatic java.lang.String.valueOf(long) : java.lang.String [38]\n" + |
| " 30 invokevirtual java.io.PrintStream.println(java.lang.String) : void [44]\n" + |
| " 33 goto 37\n" + |
| " 36 pop\n" + |
| " 37 return\n"; |
| int index = actualOutput.indexOf(expectedOutput); |
| if (index == -1 || expectedOutput.length() == 0) { |
| System.out.println(Util.displayString(actualOutput, 2)); |
| } |
| if (index == -1) { |
| assertEquals("Wrong contents", expectedOutput, actualOutput); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=461706 [1.8][compiler] "Unnecessary cast" problems for necessary cast in lambda expression |
| public void test461706() { |
| if (this.complianceLevel < ClassFileConstants.JDK1_8) |
| return; |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| this.runConformTest( |
| new String[] { |
| "Bug.java", |
| "import java.util.ArrayList;\n" + |
| "import java.util.List;\n" + |
| "public class Bug {\n" + |
| " private static class AndCondition implements ICondition {\n" + |
| " public AndCondition(ICondition cond1, ICondition cond2) {\n" + |
| " // todo\n" + |
| " }\n" + |
| " }\n" + |
| " private static class SimpleCondition implements ICondition {\n" + |
| " }\n" + |
| " private static interface ICondition {\n" + |
| " ICondition TRUE = new SimpleCondition();\n" + |
| " default ICondition and(final ICondition cond) {\n" + |
| " return new AndCondition(this, cond);\n" + |
| " }\n" + |
| " }\n" + |
| " public static void main(final String[] args) {\n" + |
| " final List<SimpleCondition> conditions = new ArrayList<>();\n" + |
| " conditions.stream()\n" + |
| " .map(x -> (ICondition)x)\n" + |
| " .reduce((x, y) -> x.and(y))\n" + |
| " .orElse(ICondition.TRUE);\n" + |
| " }\n" + |
| "}" |
| }, |
| customOptions); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=461706 [1.8][compiler] "Unnecessary cast" problems for necessary cast in lambda expression |
| public void test461706a() { |
| if (this.complianceLevel < ClassFileConstants.JDK1_8) |
| return; |
| Map customOptions = getCompilerOptions(); |
| customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); |
| this.runNegativeTest( |
| new String[] { |
| "Bug.java", |
| "import java.util.ArrayList;\n" + |
| "import java.util.List;\n" + |
| "public class Bug {\n" + |
| " private static class AndCondition implements ICondition {\n" + |
| " public AndCondition(ICondition cond1, ICondition cond2) {\n" + |
| " // todo\n" + |
| " }\n" + |
| " }\n" + |
| " static class SimpleCondition implements ICondition {\n" + |
| " }\n" + |
| " private static interface ICondition {\n" + |
| " ICondition TRUE = new SimpleCondition();\n" + |
| " default ICondition and(final ICondition cond) {\n" + |
| " return new AndCondition(this, cond);\n" + |
| " }\n" + |
| " }\n" + |
| " public static void main(final String[] args) {\n" + |
| " final List<ICondition> conditions = new ArrayList<>();\n" + |
| " conditions.stream()\n" + |
| " .map(x -> (ICondition)x)\n" + |
| " .reduce((x, y) -> x.and(y))\n" + |
| " .orElse(ICondition.TRUE);\n" + |
| " }\n" + |
| "}" |
| }, |
| "----------\n" + |
| "1. ERROR in Bug.java (at line 20)\n" + |
| " .map(x -> (ICondition)x)\n" + |
| " ^^^^^^^^^^^^^\n" + |
| "Unnecessary cast from Bug.ICondition to Bug.ICondition\n" + |
| "----------\n", |
| null, |
| true, |
| customOptions); |
| } |
| public static Class testClass() { |
| return CastTest.class; |
| } |
| } |