From 2b4e0bd7cce9f72ec91cc87e73deb51c397b706c Mon Sep 17 00:00:00 2001 From: Stephan Herrmann Date: Sat, 14 Jan 2012 13:31:19 +0100 Subject: Update JDT/Core to 3.7.2 RC1 via v20120111-1241 --- .../META-INF/MANIFEST.MF | 2 +- .../regression/GenericsRegressionTest.java | 86 ++- .../regression/GenericsRegressionTest_1_7.java | 22 + .../compiler/regression/MethodVerifyTest.java | 105 ++- .../compiler/regression/NullReferenceTest.java | 30 +- .../compiler/regression/StackMapAttributeTest.java | 818 ++++++++++++++++++++- .../regression/TryWithResourcesStatementTest.java | 225 +++++- .../META-INF/MANIFEST.MF | 2 +- .../jdt/core/tests/dom/ASTConverterTestAST3_2.java | 18 + .../tests/formatter/FormatterRegressionTests.java | 18 + .../core/tests/model/AbstractJavaModelTests.java | 22 +- .../jdt/core/tests/model/AttachedJavadocTests.java | 80 ++ .../jdt/core/tests/model/ClasspathTests.java | 68 ++ .../jdt/core/tests/model/JavaSearchBugsTests.java | 70 +- org.eclipse.jdt.core/.settings/.api_filters | 818 +-------------------- .../internal/compiler/batch/messages.properties | 2 +- org.eclipse.jdt.core/buildnotes_jdt-core.html | 128 ++++ .../jdt/internal/compiler/ast/DoStatement.java | 8 +- .../jdt/internal/compiler/ast/ForStatement.java | 11 + .../internal/compiler/ast/ForeachStatement.java | 2 +- .../jdt/internal/compiler/ast/ReturnStatement.java | 16 +- .../jdt/internal/compiler/ast/TryStatement.java | 27 +- .../compiler/codegen/StackMapFrameCodeStream.java | 11 +- .../compiler/flow/ConditionalFlowInfo.java | 5 + .../jdt/internal/compiler/flow/FlowContext.java | 13 +- .../jdt/internal/compiler/flow/FlowInfo.java | 6 + .../compiler/flow/UnconditionalFlowInfo.java | 24 + .../compiler/lookup/LookupEnvironment.java | 8 +- .../internal/compiler/lookup/MethodVerifier15.java | 7 +- .../compiler/lookup/ParameterizedTypeBinding.java | 4 +- .../jdt/internal/compiler/lookup/Scope.java | 5 +- .../dom/org/eclipse/jdt/core/dom/TryStatement.java | 2 +- .../internal/formatter/CodeFormatterVisitor.java | 13 +- .../org/eclipse/jdt/core/IJavaModelMarker.java | 11 +- .../jdt/core/IJavaModelStatusConstants.java | 7 + .../org/eclipse/jdt/core/JavaConventions.java | 12 +- .../model/org/eclipse/jdt/core/JavaCore.java | 14 + .../eclipse/jdt/internal/core/ClasspathEntry.java | 42 +- .../jdt/internal/core/ClasspathValidation.java | 14 +- .../core/CompilationUnitProblemFinder.java | 7 +- .../core/JavaCorePreferenceInitializer.java | 1 + .../jdt/internal/core/JavaModelManager.java | 124 ++-- .../org/eclipse/jdt/internal/core/JavaProject.java | 25 +- .../eclipse/jdt/internal/core/JavadocContents.java | 9 +- .../org/eclipse/jdt/internal/core/NameLookup.java | 7 + .../jdt/internal/core/SetClasspathOperation.java | 1 + .../eclipse/jdt/internal/core/builder/State.java | 4 +- 47 files changed, 1920 insertions(+), 1034 deletions(-) diff --git a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF index cf30c8b3c..36991c29b 100644 --- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.core.tests.compiler -Bundle-Version: 3.7.1 +Bundle-Version: 3.7.3 Bundle-ClassPath: jdtcoretestscompiler.jar Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java index 3c54f5f06..f2968e473 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -2465,4 +2465,88 @@ public void test348493a() { "\'<>\' operator is not allowed for source level below 1.7\n" + "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=366131 +public void test366131() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n" + + "class Range> {\n" + + " public boolean containsNC(T value) {\n" + + " return false;\n" + + " }\n" + + "}\n" + + "class NumberRange> extends Range {\n" + + " public boolean contains(Comparable value) {\n" + + " return castTo((Class) null).containsNC((Comparable) null);\n" + + " }\n" + + " public > NumberRange\n" + + "castTo(Class type) {\n" + + " return null;\n" + + " }\n" + + "}\n", + }, + "SUCCESS"); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=366131 +public void test366131b() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String [] args) {\n" + + " Zork z;\n" + + " }\n" + + "}\n" + + "class Range> {\n" + + " public boolean containsNC(T value) {\n" + + " return false;\n" + + " }\n" + + "}\n" + + "class NumberRange> extends Range {\n" + + " public boolean contains(Comparable value) {\n" + + " return castTo((Class) null).containsNC((Comparable) null);\n" + + " }\n" + + " public > NumberRange\n" + + "castTo(Class type) {\n" + + " return null;\n" + + " }\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " Zork z;\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n" + + "2. WARNING in X.java (at line 13)\n" + + " return castTo((Class) null).containsNC((Comparable) null);\n" + + " ^^^^^^^^^^^^^^^^^^^^\n" + + "Type safety: Unchecked invocation castTo(Class) of the generic method castTo(Class) of type NumberRange\n" + + "----------\n" + + "3. WARNING in X.java (at line 13)\n" + + " return castTo((Class) null).containsNC((Comparable) null);\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Type safety: The method containsNC(Comparable) belongs to the raw type Range. References to generic type Range should be parameterized\n" + + "----------\n" + + "4. WARNING in X.java (at line 13)\n" + + " return castTo((Class) null).containsNC((Comparable) null);\n" + + " ^^^^^^^^^^^^\n" + + "Type safety: The expression of type Class needs unchecked conversion to conform to Class>>\n" + + "----------\n" + + "5. WARNING in X.java (at line 13)\n" + + " return castTo((Class) null).containsNC((Comparable) null);\n" + + " ^^^^^\n" + + "Class is a raw type. References to generic type Class should be parameterized\n" + + "----------\n" + + "6. WARNING in X.java (at line 13)\n" + + " return castTo((Class) null).containsNC((Comparable) null);\n" + + " ^^^^^^^^^^\n" + + "Comparable is a raw type. References to generic type Comparable should be parameterized\n" + + "----------\n"); +} } \ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java index 4fddfd872..c79521ef0 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java @@ -2302,6 +2302,28 @@ public void test0060a() { false, customOptions); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=361441 +public void test0061() { + this.runNegativeTest( + new String[] { + "X.java", + "import java.net.URI;" + + "import java.nio.file.FileSystems;" + + "import java.util.Collections;\n" + + "public class X {\n" + + " public static void foo() {\n" + + " URI uri = URI.create(\"http://www.eclipse.org\");\n" + + " FileSystems.newFileSystem(uri, Collections.emptyMap());\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " FileSystems.newFileSystem(uri, Collections.emptyMap());\n" + + " ^^^^^^^^^^^^^\n" + + "The method newFileSystem(URI, Map) in the type FileSystems is not applicable for the arguments (URI, Map)\n" + + "----------\n"); +} public static Class testClass() { return GenericsRegressionTest_1_7.class; } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java index 9b37703d0..698d58758 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java @@ -11416,9 +11416,9 @@ public void test207() { }, "class java.lang.Object"); } -// https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658, make sure a bridge method -// is generated when a public method is inherited from a non-public class into a -// public class. +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343060, make sure a bridge method +// is NOT generated when a public method is inherited from a non-public class into a +// public class if the non public class happens to be in the default package. public void test208() { this.runConformTest( new String[] { @@ -11451,11 +11451,11 @@ public void test208() { "\n"+ "}\n" }, - this.complianceLevel <= ClassFileConstants.JDK1_5 ? "Annotation was found" : "Annotation was not found"); + "Annotation was found"); } -// https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658, make sure a bridge method -// is generated when a public method is inherited from a non-public class into a -// public class. +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343060, make sure a bridge method +// is NOT generated when a public method is inherited from a non-public class into a +// public class if the non public class happens to be in the default package. public void test208a() { this.runConformTest( new String[] { @@ -11489,7 +11489,7 @@ public void test208a() { "\n"+ "}\n" }, - this.complianceLevel <= ClassFileConstants.JDK1_5 ? "Annotation was found" : "Annotation was not found"); + "Annotation was found"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=322001 public void test209() { @@ -13367,7 +13367,7 @@ public void testBug317719h() throws Exception { String output = this.complianceLevel == ClassFileConstants.JDK1_6 ? "----------\n" + "1. WARNING in Test.java (at line 3)\n" + - " public class Test extends LinkedHashMap> {\n" + + " public class Test extends HashMap> {\n" + " ^^^^\n" + "The serializable class Test does not declare a static final serialVersionUID field of type long\n" + "----------\n" + @@ -13379,7 +13379,7 @@ public void testBug317719h() throws Exception { "3. WARNING in Test.java (at line 5)\n" + " public Collection get(Key k) { return null; }\n" + " ^^^^^^^^^^\n" + - "Name clash: The method get(Key) of type Test has the same erasure as get(Object) of type LinkedHashMap but does not override it\n" + + "Name clash: The method get(Key) of type Test has the same erasure as get(Object) of type HashMap but does not override it\n" + "----------\n" + "4. ERROR in Test.java (at line 6)\n" + " Zork z;\n" + @@ -13388,7 +13388,7 @@ public void testBug317719h() throws Exception { "----------\n": "----------\n" + "1. WARNING in Test.java (at line 3)\n" + - " public class Test extends LinkedHashMap> {\n" + + " public class Test extends HashMap> {\n" + " ^^^^\n" + "The serializable class Test does not declare a static final serialVersionUID field of type long\n" + "----------\n" + @@ -13400,7 +13400,7 @@ public void testBug317719h() throws Exception { "3. ERROR in Test.java (at line 5)\n" + " public Collection get(Key k) { return null; }\n" + " ^^^^^^^^^^\n" + - "Name clash: The method get(Key) of type Test has the same erasure as get(Object) of type LinkedHashMap but does not override it\n" + + "Name clash: The method get(Key) of type Test has the same erasure as get(Object) of type HashMap but does not override it\n" + "----------\n" + "4. ERROR in Test.java (at line 6)\n" + " Zork z;\n" + @@ -13411,8 +13411,8 @@ public void testBug317719h() throws Exception { new String[] { "Test.java", "import java.util.Collection;\n" + - "import java.util.LinkedHashMap;\n" + - "public class Test extends LinkedHashMap> {\n" + + "import java.util.HashMap;\n" + + "public class Test extends HashMap> {\n" + " public Collection put(Key k, Value v) { return null; }\n" + " public Collection get(Key k) { return null; }\n" + " Zork z;\n" + @@ -13420,4 +13420,81 @@ public void testBug317719h() throws Exception { }, output); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658, make sure a bridge method +// is generated when a public method is inherited from a non-public class into a +// public class if the non public class happens to be defined in a named package. +public void test288658() { + this.runConformTest( + new String[] { + "pkg/Test.java", + "package pkg;\n" + + "import java.lang.annotation.Annotation;\n"+ + "import java.lang.annotation.Retention;\n"+ + "import java.lang.annotation.RetentionPolicy;\n"+ + "import java.lang.reflect.Method;\n"+ + "\n"+ + "public class Test extends Super {\n"+ + " public static void main(String[] args) {\n"+ + " try {\n"+ + " Method m = Test.class.getMethod(\"setFoo\", String.class);\n"+ + " Annotation a = m.getAnnotation(Anno.class);\n"+ + " System.out.println(\"Annotation was \" + (a == null ? \"not \" : \"\") +\n"+ + "\"found\");\n"+ + " } catch (Exception e) {\n"+ + " e.printStackTrace();\n"+ + " }\n"+ + " }\n"+ + "}\n"+ + "\n"+ + "class Super {\n"+ + " @Anno\n"+ + " public void setFoo(String foo) {}\n"+ + "}\n"+ + "\n"+ + "@Retention(RetentionPolicy.RUNTIME)\n"+ + "@interface Anno {\n"+ + "\n"+ + "}\n" + }, + this.complianceLevel <= ClassFileConstants.JDK1_5 ? "Annotation was found" : "Annotation was not found"); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658, make sure a bridge method +// is generated when a public method is inherited from a non-public class into a +// public class if the non public class happens to be defined in a named package. +public void test288658a() { + this.runConformTest( + new String[] { + "pkg/Test.java", + "package pkg;\n" + + "import java.lang.annotation.Annotation;\n"+ + "import java.lang.annotation.Retention;\n"+ + "import java.lang.annotation.RetentionPolicy;\n"+ + "import java.lang.reflect.Method;\n"+ + "\n"+ + "public class Test extends Super {\n"+ + " public void setFoo() {}\n" + + " public static void main(String[] args) {\n"+ + " try {\n"+ + " Method m = Test.class.getMethod(\"setFoo\", String.class);\n"+ + " Annotation a = m.getAnnotation(Anno.class);\n"+ + " System.out.println(\"Annotation was \" + (a == null ? \"not \" : \"\") +\n"+ + "\"found\");\n"+ + " } catch (Exception e) {\n"+ + " e.printStackTrace();\n"+ + " }\n"+ + " }\n"+ + "}\n"+ + "\n"+ + "class Super {\n"+ + " @Anno\n"+ + " public void setFoo(String foo) {}\n"+ + "}\n"+ + "\n"+ + "@Retention(RetentionPolicy.RUNTIME)\n"+ + "@interface Anno {\n"+ + "\n"+ + "}\n" + }, + this.complianceLevel <= ClassFileConstants.JDK1_5 ? "Annotation was found" : "Annotation was not found"); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java index bcef1ea1e..0da65d4ff 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java @@ -17,6 +17,7 @@ * bug 338303 - Warning about Redundant assignment conflicts with definite assignment * bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop * bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself + * bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -44,7 +45,7 @@ public NullReferenceTest(String name) { // Only the highest compliance level is run; add the VM argument // -Dcompliance=1.4 (for example) to lower it if needed static { -// TESTS_NAMES = new String[] { "testBug348379" }; +// TESTS_NAMES = new String[] { "test358827" }; // TESTS_NUMBERS = new int[] { 561 }; // TESTS_RANGE = new int[] { 1, 2049 }; } @@ -14900,4 +14901,31 @@ public void testBug348379f() throws Exception { "----------\n"); } } +// Bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis +public void test358827() { + if (this.complianceLevel >= ClassFileConstants.JDK1_7) { + this.runNegativeTest( + new String[] { + "Bug358827.java", + "import java.io.FileReader;\n" + + "public class Bug358827 {\n" + + " Object foo2() throws Exception {\n" + + " String o = null;\n" + + " try (FileReader rf = new FileReader(\"file\")){\n" + + " o = o.toUpperCase();\n" + + " } finally {\n" + + " o = \"OK\";\n" + + " }\n" + + " return o;\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in Bug358827.java (at line 6)\n" + + " o = o.toUpperCase();\n" + + " ^\n" + + "Null pointer access: The variable o can only be null at this location\n" + + "----------\n"); + } +} } \ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java index de0e7c619..8b83af74d 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2011 IBM Corporation and others. + * Copyright (c) 2006, 2012 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 @@ -19,6 +19,7 @@ import org.eclipse.jdt.core.JavaCore; 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; public class StackMapAttributeTest extends AbstractRegressionTest { public StackMapAttributeTest(String name) { @@ -33,7 +34,7 @@ public class StackMapAttributeTest extends AbstractRegressionTest { // All specified tests which does not belong to the class are skipped... static { // TESTS_PREFIX = "testBug95521"; -// TESTS_NAMES = new String[] { "testBug83127a" }; +// TESTS_NAMES = new String[] { "testBug359495" }; // TESTS_NUMBERS = new int[] { 53 }; // TESTS_RANGE = new int[] { 23 -1,}; } @@ -6802,4 +6803,817 @@ public class StackMapAttributeTest extends AbstractRegressionTest { }, "SUCCESS"); } + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495 + public void testBug359495a() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "import java.util.List;\n" + + "import java.util.concurrent.locks.Lock;\n" + + "import java.util.Arrays;\n" + + "import java.util.concurrent.locks.ReentrantLock;\n" + + "public class X {\n" + + " public static void main(String[] args) {\n" + + " final Lock lock = new ReentrantLock();\n" + + " final List strings = Arrays.asList(args);\n" + + " lock.lock();\n" + + " try{\n" + + " for (final String string:strings){\n" + + " return;\n" + + " }\n" + + " return;\n" + + " } finally {\n" + + " lock.unlock();\n" + + " }" + + " }\n" + + "}", + }, + ""); + + 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: 6\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 new java.util.concurrent.locks.ReentrantLock [16]\n" + + " 3 dup\n" + + " 4 invokespecial java.util.concurrent.locks.ReentrantLock() [18]\n" + + " 7 astore_1 [lock]\n" + + " 8 aload_0 [args]\n" + + " 9 invokestatic java.util.Arrays.asList(java.lang.Object[]) : java.util.List [19]\n" + + " 12 astore_2 [strings]\n" + + " 13 aload_1 [lock]\n" + + " 14 invokeinterface java.util.concurrent.locks.Lock.lock() : void [25] [nargs: 1]\n" + + " 19 aload_2 [strings]\n" + + " 20 invokeinterface java.util.List.iterator() : java.util.Iterator [30] [nargs: 1]\n" + + " 25 astore 4\n" + + " 27 aload 4\n" + + " 29 invokeinterface java.util.Iterator.hasNext() : boolean [36] [nargs: 1]\n" + + " 34 ifeq 55\n" + + " 37 aload 4\n" + + " 39 invokeinterface java.util.Iterator.next() : java.lang.Object [42] [nargs: 1]\n" + + " 44 checkcast java.lang.String [46]\n" + + " 47 astore_3 [string]\n" + + " 48 aload_1 [lock]\n" + + " 49 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" + + " 54 return\n" + + " 55 aload_1 [lock]\n" + + " 56 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" + + " 61 return\n" + + " 62 astore 5\n" + + " 64 aload_1 [lock]\n" + + " 65 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" + + " 70 aload 5\n" + + " 72 athrow\n" + + " Exception Table:\n" + + " [pc: 19, pc: 48] -> 62 when : any\n" + + " Line numbers:\n" + + " [pc: 0, line: 7]\n" + + " [pc: 8, line: 8]\n" + + " [pc: 13, line: 9]\n" + + " [pc: 19, line: 11]\n" + + " [pc: 48, line: 16]\n" + + " [pc: 54, line: 12]\n" + + " [pc: 55, line: 16]\n" + + " [pc: 61, line: 14]\n" + + " [pc: 62, line: 15]\n" + + " [pc: 64, line: 16]\n" + + " [pc: 70, line: 17]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 73] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 8, pc: 73] local: lock index: 1 type: java.util.concurrent.locks.Lock\n" + + " [pc: 13, pc: 73] local: strings index: 2 type: java.util.List\n" + + " [pc: 48, pc: 55] local: string index: 3 type: java.lang.String\n" + + " Local variable type table:\n" + + " [pc: 13, pc: 73] local: strings index: 2 type: java.util.List\n" + + " Stack map table: number of frames 2\n" + + " [pc: 55, append: {java.util.concurrent.locks.Lock, java.util.List}]\n" + + " [pc: 62, same_locals_1_stack_item, stack: {java.lang.Throwable}]\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=359495 + public void testBug359495b() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "import java.util.List;\n" + + "import java.util.Iterator;\n" + + "import java.util.concurrent.locks.Lock;\n" + + "import java.util.Arrays;\n" + + "import java.util.concurrent.locks.ReentrantLock;\n" + + "public class X {\n" + + " public static void main(String[] args) {\n" + + " final Lock lock = new ReentrantLock();\n" + + " final List strings = Arrays.asList(args);\n" + + " lock.lock();\n" + + " try{\n" + + " for (Iterator i = strings.iterator(); i.hasNext();){\n" + + " return;\n" + + " }\n" + + " return;\n" + + " } finally {\n" + + " lock.unlock();\n" + + " }" + + " }\n" + + "}", + }, + ""); + + 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: 5\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 new java.util.concurrent.locks.ReentrantLock [16]\n" + + " 3 dup\n" + + " 4 invokespecial java.util.concurrent.locks.ReentrantLock() [18]\n" + + " 7 astore_1 [lock]\n" + + " 8 aload_0 [args]\n" + + " 9 invokestatic java.util.Arrays.asList(java.lang.Object[]) : java.util.List [19]\n" + + " 12 astore_2 [strings]\n" + + " 13 aload_1 [lock]\n" + + " 14 invokeinterface java.util.concurrent.locks.Lock.lock() : void [25] [nargs: 1]\n" + + " 19 aload_2 [strings]\n" + + " 20 invokeinterface java.util.List.iterator() : java.util.Iterator [30] [nargs: 1]\n" + + " 25 astore_3 [i]\n" + + " 26 aload_3 [i]\n" + + " 27 invokeinterface java.util.Iterator.hasNext() : boolean [36] [nargs: 1]\n" + + " 32 ifeq 42\n" + + " 35 aload_1 [lock]\n" + + " 36 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" + + " 41 return\n" + + " 42 aload_1 [lock]\n" + + " 43 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" + + " 48 return\n" + + " 49 astore 4\n" + + " 51 aload_1 [lock]\n" + + " 52 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" + + " 57 aload 4\n" + + " 59 athrow\n" + + " Exception Table:\n" + + " [pc: 19, pc: 35] -> 49 when : any\n" + + " Line numbers:\n" + + " [pc: 0, line: 8]\n" + + " [pc: 8, line: 9]\n" + + " [pc: 13, line: 10]\n" + + " [pc: 19, line: 12]\n" + + " [pc: 35, line: 17]\n" + + " [pc: 41, line: 13]\n" + + " [pc: 42, line: 17]\n" + + " [pc: 48, line: 15]\n" + + " [pc: 49, line: 16]\n" + + " [pc: 51, line: 17]\n" + + " [pc: 57, line: 18]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 60] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 8, pc: 60] local: lock index: 1 type: java.util.concurrent.locks.Lock\n" + + " [pc: 13, pc: 60] local: strings index: 2 type: java.util.List\n" + + " [pc: 26, pc: 42] local: i index: 3 type: java.util.Iterator\n" + + " Local variable type table:\n" + + " [pc: 13, pc: 60] local: strings index: 2 type: java.util.List\n" + + " Stack map table: number of frames 2\n" + + " [pc: 42, append: {java.util.concurrent.locks.Lock, java.util.List}]\n" + + " [pc: 49, same_locals_1_stack_item, stack: {java.lang.Throwable}]\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=362591 + public void test055() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " testError(3, 4, \"d\");\n" + + " }\n" + + " public static void testError(Number n0, Number n1, String refValue) {\n" + + " Number result = refValue.equals(\"ttt\") ? n0 : (n1 == null ? null : n1.intValue());\n" + + " System.out.println(String.valueOf(result));\n" + + " }\n" + + "}", + }, + "4"); + + 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 #27 (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 4\n" + + " public static void testError(java.lang.Number n0, java.lang.Number n1, java.lang.String refValue);\n" + + " 0 aload_2 [refValue]\n" + + " 1 ldc [30]\n" + + " 3 invokevirtual java.lang.String.equals(java.lang.Object) : boolean [32]\n" + + " 6 ifeq 13\n" + + " 9 aload_0 [n0]\n" + + " 10 goto 28\n" + + " 13 aload_1 [n1]\n" + + " 14 ifnonnull 21\n" + + " 17 aconst_null\n" + + " 18 goto 28\n" + + " 21 aload_1 [n1]\n" + + " 22 invokevirtual java.lang.Number.intValue() : int [38]\n" + + " 25 invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [16]\n" + + " 28 astore_3 [result]\n" + + " 29 getstatic java.lang.System.out : java.io.PrintStream [44]\n" + + " 32 aload_3 [result]\n" + + " 33 invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [50]\n" + + " 36 invokevirtual java.io.PrintStream.println(java.lang.String) : void [53]\n" + + " 39 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 29, line: 7]\n" + + " [pc: 39, line: 8]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 40] local: n0 index: 0 type: java.lang.Number\n" + + " [pc: 0, pc: 40] local: n1 index: 1 type: java.lang.Number\n" + + " [pc: 0, pc: 40] local: refValue index: 2 type: java.lang.String\n" + + " [pc: 29, pc: 40] local: result index: 3 type: java.lang.Number\n" + + " Stack map table: number of frames 3\n" + + " [pc: 13, same]\n" + + " [pc: 21, same]\n" + + " [pc: 28, same_locals_1_stack_item, stack: {java.lang.Number}]\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 test055a() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " Object o = args != null ? args : (args == null ? null : args.length);\n" + + " }\n" + + "}\n", + }, + ""); + } + //https://bugs.eclipse.org/bugs/show_bug.cgi?id=366999 + public void test056() throws Exception { + if (this.complianceLevel < ClassFileConstants.JDK1_7) return; + this.runConformTest( + new String[] { + "X.java", + "import java.io.BufferedReader;\n" + + "import java.io.Closeable;\n" + + "import java.io.File;\n" + + "import java.io.FileReader;\n" + + "import java.io.IOException;\n" + + "\n" + + "public class X {\n" + + "\n" + + " static class C implements Closeable {\n" + + " @Override\n" + + " public void close() throws IOException {\n" + + " //\n" + + " }\n" + + " }\n" + + "\n" + + " int run() throws IOException {\n" + + " int lcnt = 0;\n" + + " try (C c = new C();) {\n" + + " try (final BufferedReader br = new BufferedReader(new FileReader(\n" + + " new File(\"logging.properties\")))) {\n" + + " String s = null;\n" + + " while ((s = br.readLine()) != null)\n" + + " lcnt++;\n" + + " return lcnt;\n" + + " }\n" + + " } finally {\n" + + " System.out.println(\"read \" + lcnt + \" lines\");\n" + + " }\n" + + " }\n" + + "\n" + + " public static void main(final String[] args) throws IOException {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}", + }, + "SUCCESS"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test057() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " String s;\n" + + " label1: do {\n" + + " for (;;) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n", + }, + "SUCCESS"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test058() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " String s;\n" + + " label1: do {\n" + + " for (;true;) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n" }, + "SUCCESS"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test059() throws Exception { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " String s;\n" + + " label1: do {\n" + + " for (;false;) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n" }, + "----------\n" + + "1. WARNING in X.java (at line 4)\n" + + " label1: do {\n" + + " ^^^^^^\n" + + "The label label1 is never explicitly referenced\n" + + "----------\n" + + "2. ERROR in X.java (at line 5)\n" + + " for (;false;) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Unreachable code\n" + + "----------\n" + + "3. ERROR in X.java (at line 10)\n" + + " } while (s != null);\n" + + " ^\n" + + "The local variable s may not have been initialized\n" + + "----------\n"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test060() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " String s;\n" + + " label1: do {\n" + + " for (; 5 < 10;) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n" }, + "SUCCESS"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test061() throws Exception { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " int five = 5, ten = 10;\n" + + " String s;\n" + + " label1: do {\n" + + " for (; five < ten;) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n" }, + "----------\n" + + "1. WARNING in X.java (at line 9)\n" + + " continue label1;\n" + + " ^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "2. ERROR in X.java (at line 11)\n" + + " } while (s != null);\n" + + " ^\n" + + "The local variable s may not have been initialized\n" + + "----------\n"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test062() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " final int five = 5, ten = 10;\n" + + " String s;\n" + + " label1: do {\n" + + " for (; five < ten;) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n" }, + "SUCCESS"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test063() throws Exception { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " final int five = 5, ten = 10;\n" + + " String s;\n" + + " label1: do {\n" + + " for (; five > ten;) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\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" + + " label1: do {\n" + + " ^^^^^^\n" + + "The label label1 is never explicitly referenced\n" + + "----------\n" + + "2. ERROR in X.java (at line 6)\n" + + " for (; five > ten;) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Unreachable code\n" + + "----------\n" + + "3. ERROR in X.java (at line 11)\n" + + " } while (s != null);\n" + + " ^\n" + + "The local variable s may not have been initialized\n" + + "----------\n"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test064() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " String s;\n" + + " label1: do {\n" + + " while (true) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n", + }, + "SUCCESS"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test065() throws Exception { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " String s;\n" + + " label1: do {\n" + + " while (false) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n" }, + "----------\n" + + "1. WARNING in X.java (at line 4)\n" + + " label1: do {\n" + + " ^^^^^^\n" + + "The label label1 is never explicitly referenced\n" + + "----------\n" + + "2. ERROR in X.java (at line 5)\n" + + " while (false) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Unreachable code\n" + + "----------\n" + + "3. ERROR in X.java (at line 10)\n" + + " } while (s != null);\n" + + " ^\n" + + "The local variable s may not have been initialized\n" + + "----------\n"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test066() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " String s;\n" + + " label1: do {\n" + + " while(5 < 10) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n" }, + "SUCCESS"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test067() throws Exception { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " int five = 5, ten = 10;\n" + + " String s;\n" + + " label1: do {\n" + + " while (five < ten) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n" }, + "----------\n" + + "1. WARNING in X.java (at line 9)\n" + + " continue label1;\n" + + " ^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "2. ERROR in X.java (at line 11)\n" + + " } while (s != null);\n" + + " ^\n" + + "The local variable s may not have been initialized\n" + + "----------\n"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test068() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " final int five = 5, ten = 10;\n" + + " String s;\n" + + " label1: do {\n" + + " while (five < ten) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\n" + + "}\n" + + " public static void main(String [] args) {\n" + + " System.out.println(\"SUCCESS\");\n" + + " }\n" + + "}\n" }, + "SUCCESS"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test069() throws Exception { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void run() {\n" + + " final int five = 5, ten = 10;\n" + + " String s;\n" + + " label1: do {\n" + + " while (five > ten) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " } while (s != null);\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" + + " label1: do {\n" + + " ^^^^^^\n" + + "The label label1 is never explicitly referenced\n" + + "----------\n" + + "2. ERROR in X.java (at line 6)\n" + + " while (five > ten) {\n" + + " s = \"\";\n" + + " if (s == null) \n" + + " continue label1;\n" + + " }\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Unreachable code\n" + + "----------\n" + + "3. ERROR in X.java (at line 11)\n" + + " } while (s != null);\n" + + " ^\n" + + "The local variable s may not have been initialized\n" + + "----------\n"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 + public void test070() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "import java.util.ArrayList;\n" + + "import java.util.Arrays;\n" + + "import java.util.Iterator;\n" + + "import java.util.List;\n" + + "import java.util.Properties;\n" + + "import org.w3c.dom.*;\n" + + "public class X extends Object {\n" + + " public static void main(String [] args) {\n" + + " System.out.println (\"SUCCESS\");\n" + + " }\n" + + " private static class Handler extends Object {\n" + + " public int getStuff() {\n" + + " return 1;\n" + + " }\n" + + " public void handle(Element element) {\n" + + " Properties properties = new Properties();\n" + + " NamedNodeMap atts = element.getAttributes();\n" + + " if (atts != null) {\n" + + " for (int a = 0; a < atts.getLength(); a++) {\n" + + " Node att = atts.item(a);\n" + + " String name = att.getNodeName();\n" + + " String value = att.getNodeValue();\n" + + " if (\"foo\".equals(name)) {\n" + + " name = value;\n" + + " } else {\n" + + " if (!\"bar\".equals(name))\n" + + " continue;\n" + + " name = value;\n" + + " }\n" + + " properties.put(name, value);\n" + + " }\n" + + " }\n" + + " label0: do {\n" + + " Node node;\n" + + " String nodeName;\n" + + " label1: do {\n" + + " for (Iterator i = (new ArrayList(1)).iterator(); i\n" + + " .hasNext(); members.add(equals(node))) {\n" + + " node = (Node) i.next();\n" + + " nodeName = \"\" + equals(node.getNodeName());\n" + + " if (!\"foo\".equals(nodeName))\n" + + " continue label1;\n" + + " }\n" + + " break label0;\n" + + " } while (!\"bar\".equals(nodeName));\n" + + " Iterator i = (new ArrayList(1)).iterator();\n" + + " while (i.hasNext()) {\n" + + " Node n = (Node) i.next();\n" + + " String name = toString() + n.getNodeName();\n" + + " if (\"wtf\".equals(name)) {\n" + + " String propertyName = (toString() + n.getAttributes()\n" + + " .getNamedItem(\"broken\")).trim();\n" + + " String value = toString() + n;\n" + + " properties.put(propertyName, value);\n" + + " }\n" + + " }\n" + + " } while (true);\n" + + " propertiesBuilder.equals(properties);\n" + + " builder.equals(propertiesBuilder.hashCode());\n" + + " builder.equals(members);\n" + + " }\n" + + " private final Object c;\n" + + " private Object builder;\n" + + " private List members;\n" + + " private Object propertiesBuilder;\n" + + " public Handler(Object c) {\n" + + " this.c = c;\n" + + " builder = Arrays.asList(Object.class);\n" + + " builder.equals(\"foo\");\n" + + " builder.equals(\"bar\");\n" + + " members = new ArrayList();\n" + + " propertiesBuilder = Arrays.asList(Object.class);\n" + + " Object beanDefinition = propertiesBuilder.toString();\n" + + " Object holder = new String(\"stirng\");\n" + + " Arrays.asList(holder, c.toString());\n" + + " }\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " protected Object parseInternal(Element element, Object c) {\n" + + " Handler h = new Handler(c);\n" + + " h.handle(element);\n" + + " return h.getStuff();\n" + + " }\n" + + "}\n" + }, + "SUCCESS"); + } } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java index f3e0a366d..6a007f50a 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011 IBM Corporation and others. + * Copyright (c) 2011, 2012 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Stephan Herrmann - Contribution for bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -3297,6 +3298,57 @@ public void test053() { "Unhandled exception type IOException\n" + "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=348705 +// Variant of the above, witness for https://bugs.eclipse.org/358827#c6 +public void test053a() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void method1(){\n" + + " try (Y y = new Y()) { \n" + + " y.close();\n" + + " System.out.println();\n" + + " } catch (RuntimeException e) {\n" + + " } finally {\n" + + " System.out.println();\n" + + " }\n" + + " }\n" + + "}\n" + + "class Y implements Managed {\n" + + " public Y() throws CloneNotSupportedException {}\n" + + " public void close () throws ClassNotFoundException, java.io.IOException {\n" + + " }\n" + + "}\n" + + "interface Managed extends AutoCloseable {}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " try (Y y = new Y()) { \n" + + " ^\n" + + "Unhandled exception type ClassNotFoundException thrown by automatic close() invocation on y\n" + + "----------\n" + + "2. ERROR in X.java (at line 3)\n" + + " try (Y y = new Y()) { \n" + + " ^\n" + + "Unhandled exception type IOException thrown by automatic close() invocation on y\n" + + "----------\n" + + "3. ERROR in X.java (at line 3)\n" + + " try (Y y = new Y()) { \n" + + " ^^^^^^^\n" + + "Unhandled exception type CloneNotSupportedException\n" + + "----------\n" + + "4. ERROR in X.java (at line 4)\n" + + " y.close();\n" + + " ^^^^^^^^^\n" + + "Unhandled exception type ClassNotFoundException\n" + + "----------\n" + + "5. ERROR in X.java (at line 4)\n" + + " y.close();\n" + + " ^^^^^^^^^\n" + + "Unhandled exception type IOException\n" + + "----------\n"); +} // https://bugs.eclipse.org/bugs/show_bug.cgi?id=349862 (NPE when union type is used in the resource section.) public void test054() { this.runNegativeTest( @@ -3380,6 +3432,177 @@ public void test055a() { }, "Done"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=361053 +public void test057() { + this.runConformTest( + new String[] { + "X.java", + "public class X implements AutoCloseable {\n" + + " @Override\n" + + " public void close() throws Exception {\n" + + " throw new Exception();\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " final boolean foo;\n" + + " try (X a = new X(); X b = new X()) {\n" + + " foo = true;\n" + + " } catch (final Exception exception) {\n" + + " return;\n" + + " }\n" + + " }\n" + + "}\n" + }, ""); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=364008 +public void test058() { + this.runConformTest( + new String[] { + "X.java", + "import java.io.ByteArrayOutputStream;\n" + + "import java.io.FileOutputStream;\n" + + "import java.io.IOException;\n" + + "\n" + + "public class X {\n" + + "\n" + + " public static void main(final String[] args) throws IOException {\n" + + " byte[] data;\n" + + " try (final ByteArrayOutputStream os = new ByteArrayOutputStream();\n" + + " final FileOutputStream out = new FileOutputStream(\"test.dat\")) {\n" + + " data = os.toByteArray();\n" + + " }\n" + + " }\n" + + "}\n" + }, ""); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566 - In try-with-resources statement close() method of resource is not called +public void test059() { + this.runConformTest( + new String[] { + "X.java", + "import java.io.IOException;\n" + + "\n" + + "public class X implements java.lang.AutoCloseable {\n" + + " static boolean isOpen = true;\n" + + " public static void main(final String[] args) throws IOException {\n" + + " foo();\n" + + " System.out.println(isOpen);\n" + + " }\n" + + " static boolean foo() {\n" + + " try (final X x = new X()) {\n" + + " return x.num() >= 1;\n" + + " }\n" + + " }\n" + + " int num() { return 2; }\n" + + " public void close() {\n" + + " isOpen = false;\n" + + " }\n" + + "}\n" + }, + "false"); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566 - In try-with-resources statement close() method of resource is not called +public void test060() { + this.runConformTest( + new String[] { + "X.java", + "public class X implements AutoCloseable {\n" + + " static int num = 10 ;\n" + + " public static void main(String [] args) throws Exception { \n" + + " System.out.println(foo(1));\n" + + " System.out.println(foo(2));\n" + + " System.out.println(foo(3));\n" + + " }\n" + + " private static boolean foo(int where) throws Exception {\n" + + " final boolean getOut = true;\n" + + " System.out.println(\"Main\");\n" + + " try (X x1 = new X(); X x2 = new X()) {\n" + + " if (where == 1) {\n" + + " return where == 1;\n" + + " }\n" + + " System.out.println(\"Outer Try\");\n" + + " while (true) {\n" + + " try (Y y1 = new Y(); Y y2 = new Y()) { \n" + + " if (where == 2) {\n" + + " return where == 2;\n" + + " } \n" + + " System.out.println(\"Middle Try\");\n" + + " try (Z z1 = new Z(); Z z2 = new Z()) {\n" + + " System.out.println(\"Inner Try\");\n" + + " if (getOut) \n" + + " return num >= 10;\n" + + " else\n" + + " break; \n" + + " }\n" + + " }\n" + + " }\n" + + " System.out.println(\"Out of while\");\n" + + " }\n" + + " return false;\n" + + " }\n" + + " public X() {\n" + + " System.out.println(\"X::X\");\n" + + " }\n" + + " @Override\n" + + " public void close() throws Exception {\n" + + " System.out.println(\"X::~X\");\n" + + " }\n" + + "}\n" + + "class Y implements AutoCloseable {\n" + + " public Y() {\n" + + " System.out.println(\"Y::Y\");\n" + + " }\n" + + " @Override\n" + + " public void close() throws Exception {\n" + + " System.out.println(\"Y::~Y\");\n" + + " }\n" + + "}\n" + + "class Z implements AutoCloseable {\n" + + " public Z() {\n" + + " System.out.println(\"Z::Z\");\n" + + " }\n" + + " @Override\n" + + " public void close() throws Exception {\n" + + " System.out.println(\"Z::~Z\");\n" + + " }\n" + + "}\n" + }, + "Main\n" + + "X::X\n" + + "X::X\n" + + "X::~X\n" + + "X::~X\n" + + "true\n" + + "Main\n" + + "X::X\n" + + "X::X\n" + + "Outer Try\n" + + "Y::Y\n" + + "Y::Y\n" + + "Y::~Y\n" + + "Y::~Y\n" + + "X::~X\n" + + "X::~X\n" + + "true\n" + + "Main\n" + + "X::X\n" + + "X::X\n" + + "Outer Try\n" + + "Y::Y\n" + + "Y::Y\n" + + "Middle Try\n" + + "Z::Z\n" + + "Z::Z\n" + + "Inner Try\n" + + "Z::~Z\n" + + "Z::~Z\n" + + "Y::~Y\n" + + "Y::~Y\n" + + "X::~X\n" + + "X::~X\n" + + "true"); +} + public static Class testClass() { return TryWithResourcesStatementTest.class; } diff --git a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF index 8b00f1112..18ae3b783 100644 --- a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.core.tests.model;singleton:=true -Bundle-Version: 3.7.1 +Bundle-Version: 3.7.3 Bundle-ClassPath: jdtcoretestsmodel.jar Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java index 9ca2795cf..8f7991f48 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java @@ -10613,4 +10613,22 @@ public class ASTConverterTestAST3_2 extends ConverterTestSetup { assertEquals("wrong tag name", "@literal", element.getTagName()); checkSourceRange((TextElement) element.fragments().get(0), " stars**** ", source); } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=361938 + public void test0722() throws JavaModelException { + String source = "public class X {\n" + + " X(){\n" + + " try {\n" + + " }\n" + + " finally {\n" + + " }\n" + + " }\n" + + "}\n"; + + ASTParser parser = ASTParser.newParser(AST.JLS3); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setSource(source.toCharArray()); + CompilationUnit resultCompilationUnit = (CompilationUnit) parser.createAST(null); + Object o = resultCompilationUnit.types().get(0); + assertEquals(o.toString(), source); + } } \ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java index feb73b58b..2bb2efa51 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java @@ -12861,4 +12861,22 @@ public void test782() throws Exception { "}" ); } +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=359646 +public void test783() throws Exception { + this.formatterPrefs = null; + String source = + "public class X {public static void main(String[] args) {\n" + + " long x = 0x8000000000000000L;\n" + + " System.out.println(x);\n" + + " }\n" + + "}"; + formatSource(source, + "public class X {\n" + + " public static void main(String[] args) {\n" + + " long x = 0x8000000000000000L;\n" + + " System.out.println(x);\n" + + " }\n" + + "}" + ); +} } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java index a616ecd26..37eddcdfc 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -2922,13 +2922,6 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { return org.eclipse.jdt.core.tests.util.Util.toString(strings, false/*don't add extra new line*/); } protected void tearDown() throws Exception { - if (JavaModelManager.DEBUG_302850) { - System.out.println(" - Options before tear down:"); - System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); - System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); - System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); - System.out.println(org.eclipse.jdt.core.tests.util.Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); - } super.tearDown(); if (this.workingCopies != null) { @@ -2937,17 +2930,6 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { } this.wcOwner = null; - if (JavaModelManager.DEBUG_302850) { - System.out.println(" - Options before comparison with defaults:"); - System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); - System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); - System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); - System.out.println(org.eclipse.jdt.core.tests.util.Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); - System.out.println(" - Default Options before comparison:"); - System.out.println(org.eclipse.jdt.core.tests.util.Util.indentString(new CompilerOptions(JavaCore.getDefaultOptions()).toString(), 2)); - System.out.println("================================================================================"); - } - // ensure workspace options have been restored to their default Hashtable options = JavaCore.getOptions(); Hashtable defaultOptions = JavaCore.getDefaultOptions(); @@ -2955,8 +2937,6 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { "Workspace options should be back to their default", new CompilerOptions(defaultOptions).toString(), new CompilerOptions(options).toString()); - - JavaModelManager.DEBUG_302850 = false; } /** diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java index d6643d7c3..cef66efe2 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java @@ -85,6 +85,8 @@ public class AttachedJavadocTests extends ModifyingResourceTests { suite.addTest(new AttachedJavadocTests("testBug334652_2")); suite.addTest(new AttachedJavadocTests("testBug334652_3")); suite.addTest(new AttachedJavadocTests("testBug334652_4")); + suite.addTest(new AttachedJavadocTests("testBug354766")); + suite.addTest(new AttachedJavadocTests("testBug354766_2")); return suite; } @@ -964,4 +966,82 @@ public class AttachedJavadocTests extends ModifyingResourceTests { this.project.setRawClasspath(entries, null); } } + //https://bugs.eclipse.org/bugs/show_bug.cgi?id=354766 + public void testBug354766() throws CoreException, IOException { + IClasspathEntry[] entries = this.project.getRawClasspath(); + + try { + IClasspathAttribute attribute = + JavaCore.newClasspathAttribute( + IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, + "jar:platform:/resource/AttachedJavadocProject/bug354766_doc.zip!/"); + IClasspathEntry newEntry = JavaCore.newLibraryEntry(new Path("/AttachedJavadocProject/bug354766.jar"), null, null, null, new IClasspathAttribute[] { attribute}, false); + this.project.setRawClasspath(new IClasspathEntry[]{newEntry}, null); + this.project.getResolvedClasspath(false); + + IPackageFragmentRoot jarRoot = this.project.getPackageFragmentRoot(getFile("/AttachedJavadocProject/bug354766.jar")); + final IType type = jarRoot.getPackageFragment("com.test").getClassFile("PublicAbstractClass$InnerFinalException.class").getType(); + IMethod method = type.getMethod("foo", new String[0]); + assertNotNull(method); + assertTrue("Does not exist", method.exists()); + + String javadoc = method.getAttachedJavadoc(null); + assertNotNull(javadoc); + assertEquals( + "Wrong contents", + "

\r\n" + + "foo

\r\n" + + "
\r\n" + 
+					"public void foo()
\r\n" + + "
\r\n" + + "
Test method\r\n" + + "

\r\n" + + "

\r\n" + + "
\r\n" + + "
\r\n" + + "
\r\n", + javadoc); + } finally { + this.project.setRawClasspath(entries, null); + } + } + //https://bugs.eclipse.org/bugs/show_bug.cgi?id=354766 + public void testBug354766_2() throws CoreException, IOException { + IClasspathEntry[] entries = this.project.getRawClasspath(); + + try { + IClasspathAttribute attribute = + JavaCore.newClasspathAttribute( + IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, + "jar:platform:/resource/AttachedJavadocProject/bug354766_doc.zip!/"); + IClasspathEntry newEntry = JavaCore.newLibraryEntry(new Path("/AttachedJavadocProject/bug354766.jar"), null, null, null, new IClasspathAttribute[] { attribute}, false); + this.project.setRawClasspath(new IClasspathEntry[]{newEntry}, null); + this.project.getResolvedClasspath(false); + + IPackageFragmentRoot jarRoot = this.project.getPackageFragmentRoot(getFile("/AttachedJavadocProject/bug354766.jar")); + final IType type = jarRoot.getPackageFragment("com.test").getClassFile("PublicAbstractClass$InnerFinalException.class").getType(); + IMethod method = type.getMethod("InnerFinalException", new String[] { "Lcom.test.PublicAbstractClass;"}); + assertNotNull(method); + assertTrue("Does not exist", method.exists()); + + String javadoc = method.getAttachedJavadoc(null); + assertNotNull(javadoc); + assertEquals( + "Wrong contents", + "

\r\n" + + "PublicAbstractClass.InnerFinalException

\r\n" + + "
\r\n" + 
+					"public PublicAbstractClass.InnerFinalException()
\r\n" + + "
\r\n" + + "
javadoc for InnerFinalException()\r\n" + + "

\r\n" + + "

\r\n" + + "\r\n" + + "\r\n" + + "\r\n", + javadoc); + } finally { + this.project.setRawClasspath(entries, null); + } + } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java index 4166cb245..7daccdb36 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java @@ -334,6 +334,7 @@ public static Test suite() { suite.addTest(new ClasspathTests("testBug321170")); suite.addTest(new ClasspathTests("testBug229042")); suite.addTest(new ClasspathTests("testBug274737")); + suite.addTest(new ClasspathTests("testBug287164")); return suite; } public void setUpSuite() throws Exception { @@ -2020,6 +2021,7 @@ public void testClasspathValidation21() throws CoreException { public void testClasspathValidation22() throws CoreException { try { IJavaProject proj = this.createJavaProject("P", new String[] {}, ""); + proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR); IClasspathEntry[] originalCP = proj.getRawClasspath(); IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length+2]; @@ -2045,6 +2047,7 @@ public void testClasspathValidation22() throws CoreException { public void testClasspathValidation23() throws CoreException { try { IJavaProject proj = this.createJavaProject("P", new String[] {}, ""); + proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.IGNORE); IClasspathEntry[] originalCP = proj.getRawClasspath(); IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length+2]; @@ -7189,5 +7192,70 @@ public void testBug338006() throws Exception { deleteProject("P"); } } +/** + * @bug287164: Report build path error if source folder has other source folder as output folder + * + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164" + */ +public void testBug287164() throws CoreException { + try { + IJavaProject proj = this.createJavaProject("P", new String[] {}, ""); + + // Test that with the option set to IGNORE, the Java model status returns OK + proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.IGNORE); + IClasspathEntry[] originalCP = proj.getRawClasspath(); + + IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length+2]; + System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); + newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src"), new IPath[0], new Path("/P/src2")); + newCP[originalCP.length+1] = JavaCore.newSourceEntry(new Path("/P/src2"), new IPath[0], new Path("/P/src")); + + createFolder("/P/src"); + createFolder("/P/src2"); + + IJavaModelStatus status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation()); + assertTrue(status.isOK()); + assertStatus( + "OK", + status); + + proj.setRawClasspath(newCP, null); + assertMarkers("Unexpected markers", "", proj); + + // Test that with the option set to WARNING, status.isOK() returns true + proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.WARNING); + + status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation()); + assertTrue(status.isOK()); + assertStatus( + "Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'", + status); + + assertMarkers("Unexpected markers", + "Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'", proj); + + // Test that with the option set to WARNING and the presence of a more severe error scenario, the error status + // is returned + IClasspathEntry[] newCP2 = new IClasspathEntry[newCP.length+1]; + System.arraycopy(newCP, 0, newCP2, 0, newCP.length-1); + newCP2[newCP.length] = JavaCore.newLibraryEntry(new Path("/P/lib2"), null, null); + newCP2[newCP.length-1] = JavaCore.newSourceEntry(new Path("/P/src2"), new IPath[0], new Path("/P/lib2")); + + status = JavaConventions.validateClasspath(proj, newCP2, proj.getOutputLocation()); + assertFalse(status.isOK()); + assertStatus( + "Source folder \'src2\' in project 'P' cannot output to library \'lib2\'", + status); + + proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR); + status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation()); + assertStatus( + "Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'", + status); + + } finally { + this.deleteProject("P"); + } +} } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java index 1a97f60bb..377d73ff9 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -70,7 +70,6 @@ import org.eclipse.jdt.core.search.TypeNameRequestor; import org.eclipse.jdt.core.search.TypeReferenceMatch; import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.core.ClassFile; import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.SourceMethod; @@ -11586,9 +11585,9 @@ public void testBug286379b() throws CoreException { */ public void testBug286379c() throws CoreException { class TestResourceChangeListener implements IResourceChangeListener { - boolean valid = false; + boolean toRemPresent = false; public void resourceChanged(IResourceChangeEvent event) { - this.valid = validate(event.getDelta()); + this.toRemPresent = validate(event.getDelta()); } /* * Ensure that the listener receives a delta concerning the resource @@ -11611,17 +11610,6 @@ public void testBug286379c() throws CoreException { return false; } } - // print statement to debug random failures of this test - JavaModelManager.DEBUG_302850 = true; - System.out.println("================================================================================"); - System.out.println("Starting test JavaSearchBugTests.testBug286379c()..."); - System.out.println(" - Default Options at test start:"); - System.out.println(Util.indentString(new CompilerOptions(JavaCore.getDefaultOptions()).toString(), 1)); - System.out.println(" - Options at test start:"); - System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); - System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); - System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); - System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); IContentType javaContentType = Platform.getContentTypeManager().getContentType(JavaCore.JAVA_SOURCE_CONTENT_TYPE); TestResourceChangeListener changeListener = new TestResourceChangeListener(); @@ -11651,7 +11639,7 @@ public void testBug286379c() throws CoreException { // fail as we don't get any specific event from the platform to refresh the indexes. // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=118619 int counter = 0; - while (!changeListener.valid) { + while (!changeListener.toRemPresent) { try { Thread.sleep(100); } @@ -11664,21 +11652,9 @@ public void testBug286379c() throws CoreException { // Wait to be sure that indexes are ready after the new resource was added waitUntilIndexesReady(); - // print statement to debug random failures of this test - System.out.println(" - Options before first exit:"); - System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); - System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); - System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); - System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); // Restart to let the indexes to be refreshed simulateExit(); simulateRestart(); - // print statement to debug random failures of this test - System.out.println(" - Options after first restart:"); - System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); - System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); - System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); - System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); waitUntilIndexesReady(); // Search for the new type with new extension @@ -11696,22 +11672,23 @@ public void testBug286379c() throws CoreException { false /*only assume*/); // Delete the file specification + changeListener.toRemPresent = true; javaContentType.removeFileSpec("torem", IContentType.FILE_EXTENSION_SPEC); + counter = 0; + while (changeListener.toRemPresent) { + try { + Thread.sleep(100); + } + catch (InterruptedException ie) { + // skip + } + assertTrue("We should have got a resource event within a 10s delay!", counter++ < 100); + } + waitUntilIndexesReady(); - // print statement to debug random failures of this test - System.out.println(" - Options before second exit:"); - System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); - System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); - System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); - System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); // Restarting should update the index file to remove the references of any .torem files simulateExit(); - simulateRestart(); - // print statement to debug random failures of this test - System.out.println(" - Options after second restart:"); - System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); - System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); - System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); + simulateRestart(); waitUntilIndexesReady(); // Search for the new type with new extension @@ -11724,24 +11701,11 @@ public void testBug286379c() throws CoreException { IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null); assertSearchResults("No search results expected", "", collector); - System.out.println(" - Options after search:"); - System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); - System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); - System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); - System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); } finally { getWorkspace().removeResourceChangeListener(changeListener); if (javaContentType != null) javaContentType.removeFileSpec("torem", IContentType.FILE_EXTENSION_SPEC); deleteProject("P"); - System.out.println(" - Options at test end:"); - System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); - System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); - System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); - System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); - System.out.println(" - Default Options at test end:"); - System.out.println(Util.indentString(new CompilerOptions(JavaCore.getDefaultOptions()).toString(), 2)); - JavaModelManager.DEBUG_302850 = false; } } diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters index 4ead49a1e..50be07f82 100644 --- a/org.eclipse.jdt.core/.settings/.api_filters +++ b/org.eclipse.jdt.core/.settings/.api_filters @@ -1,784 +1,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties index 1ffd6ab14..e181fda48 100644 --- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties +++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties @@ -1,7 +1,7 @@ #Format: compiler.name = word1 word2 word3 compiler.name = Eclipse Compiler for Java(TM) #Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)] -compiler.version = 0.B76_R37x, 3.7.1 +compiler.version = 0.B82_R37x, 3.7.2 compiler.copyright = Copyright IBM Corp 2000, 2011. All rights reserved. ###{ObjectTeams: diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html index ef28c1f74..e5b35c3c9 100644 --- a/org.eclipse.jdt.core/buildnotes_jdt-core.html +++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html @@ -41,6 +41,134 @@ + +

+Eclipse Platform Build Notes
+Java development tools core

+Eclipse SDK 3.7.2 - January 11, 2012 - 3.7.2 +
+

What's new in this drop

+ +

Problem Reports Fixed

+366131 +[1.5][compiler] New generics compile error in Indigo SR1 for code that compiles in earlier Eclipse and javac +
302850 +13 failures in JavaModel tests for the N20100214-2000 Mac OS X - Cocoa test machine + + +

+Eclipse Platform Build Notes
+Java development tools core

+Eclipse SDK 3.7.2 - December 14, 2011 +
+

What's new in this drop

+ +

Problem Reports Fixed

+367023 +Error in JDT Core during AST creation +
367566 +In try-with-resources statement close() method of resource is not called +
366999 +VerifyError: Inconsistent stackmap frames +
364450 +Dubious class path error triggers a full rebuild + + +

+Eclipse Platform Build Notes
+Java development tools core

+Eclipse SDK 3.7.2 - November 30, 2011 +
Project org.eclipse.jdt.core v_B80_R37x +(cvs). +

What's new in this drop

+ +

Problem Reports Fixed

+359177 +Test MethodVerifyTest#testBug317719h fails when run with 1.6 JVM + + +

+Eclipse Platform Build Notes
+Java development tools core

+Eclipse SDK 3.7.2 - November 23, 2011 +
Project org.eclipse.jdt.core v_B79_R37x +(cvs). +

What's new in this drop

+ +

Problem Reports Fixed

+361053 +java.lang.VerifyError on try-with-resources +
357110 +Problem with inner classes referenced from jars or class folders: "The type ... cannot be resolved" +
362591 +VerifyError: Inconsistent stackmap frames +
343060 +Method.getMethods() returns different methods (compared to standard compiler) for public/non-public inheritance hierarchies +
361441 +Error in JDT Core during AST creation + + +

+Eclipse Platform Build Notes
+Java development tools core

+Eclipse SDK 3.7.2 - November 16, 2011 +
Project org.eclipse.jdt.core v_B78_R37x +(cvs). +

What's new in this drop

+ +

Problem Reports Fixed

+361938 +Formerly working JLS3 parser not working -- Scanner reports com.sun.jdi.InvocationException occurred invoking method. + + +

+Eclipse Platform Build Notes
+Java development tools core

+Eclipse SDK 3.7.2 - November 2, 2011 +
Project org.eclipse.jdt.core v_B77_R37x +(cvs). +

What's new in this drop

+
    +
  • Added a new API OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE(see bug 287164 for details): +
    +/**
    + * Status constant indicating that the default or specific output folder is overlapping
    + * with another source location.
    + * @since 3.6.4
    + */
    +public static final int OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = 1013;
    +
    +
  • + +
  • Added a new option CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE to report an output location overlapping another source location(see bug 287164 for details): +
    +/**
    + * Core option ID: Reporting an output location overlapping another source location.
    + * Indicate the severity of the problem reported when a source entry's output location overlaps another
    + * source entry.
    + * 
    + * Option id:"org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource"
    + * Possible values:{ "error", "warning", "ignore" }
    + * Default:"error"
    + * 
    + * @since 3.6.4
    + */
    +public static final String CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = PLUGIN_ID + ".classpath.outputOverlappingAnotherSource";
    +
    +
  • +
+

Problem Reports Fixed

+354766 +Javadoc content does not appear in content assist info window for non-static inner class constructors +
287164 +Report build path error if source folder has other source folder as output folder +
359646 +Formatter fails silently if Java source contains 0x8000000000000000L +
359495 +[1.7][compiler] VerifyError in try-finally block with lock encompassing for-each block and unlock in finally clause +
358827 +[1.7] exception analysis for t-w-r spoils null analysis +

Eclipse Platform Build Notes
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java index 5806ce8f2..774c7aae4 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -101,7 +101,11 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl (this.action == null ? actionInfo : (actionInfo.mergedWith(loopingContext.initsOnContinue))).copy()); - this.preConditionInitStateIndex = currentScope.methodScope().recordInitializationStates(actionInfo); + /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023, we reach the condition at the bottom via two arcs, + one by free fall and another by continuing... Merge initializations propagated through the two pathways, + cf, while and for loops. + */ + this.preConditionInitStateIndex = currentScope.methodScope().recordInitializationStates(actionInfo.mergedWith(loopingContext.initsOnContinue)); if (!isConditionOptimizedFalse && this.continueLabel != null) { loopingContext.complainOnDeferredFinalChecks(currentScope, condInfo); condLoopContext.complainOnDeferredFinalChecks(currentScope, condInfo); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java index 7f0b9b154..685892307 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java @@ -216,6 +216,17 @@ public class ForStatement extends Statement { exitBranch, isConditionOptimizedFalse, !isConditionTrue /*for(;;){}while(true); unreachable(); */); + // Variables initialized only for the purpose of the for loop can be removed for further flow info + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495 + if (this.initializations != null) { + for (int i = 0; i < this.initializations.length; i++) { + Statement init = this.initializations[i]; + if (init instanceof LocalDeclaration) { + LocalVariableBinding binding = ((LocalDeclaration) init).binding; + mergedInfo.resetAssignmentInfo(binding); + } + } + } this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo); return mergedInfo; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java index 3a7b16c20..42e677e40 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java @@ -118,7 +118,7 @@ public class ForeachStatement extends Statement { // code generation can be optimized when no need to continue in the loop exitBranch = flowInfo.unconditionalCopy(). - addInitializationsFrom(condInfo.initsWhenFalse()); + addNullInfoFrom(condInfo.initsWhenFalse()); // TODO (maxime) no need to test when false: can optimize (same for action being unreachable above) if ((actionInfo.tagBits & loopingContext.initsOnContinue.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java index 8d97f740f..4c9393ed7 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -54,6 +54,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl int subCount = 0; boolean saveValueNeeded = false; boolean hasValueToSave = needValueStore(); + boolean noAutoCloseables = true; do { SubRoutineStatement sub; if ((sub = traversedContext.subroutine()) != null) { @@ -69,6 +70,11 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl this.bits |= ASTNode.IsAnySubRoutineEscaping; break; } + if (sub instanceof TryStatement) { + if (((TryStatement) sub).resources.length > 0) { + noAutoCloseables = false; + } + } } traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); @@ -107,7 +113,9 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl } else { this.saveValueVariable = null; if (((this.bits & ASTNode.IsSynchronized) == 0) && this.expression != null && this.expression.resolvedType == TypeBinding.BOOLEAN) { - this.expression.bits |= ASTNode.IsReturnedValue; + if (noAutoCloseables) { // can't abruptly return in the presence of autocloseables. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566 + this.expression.bits |= ASTNode.IsReturnedValue; + } } } return FlowInfo.DEAD_END; @@ -148,11 +156,11 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) { } } if (this.saveValueVariable != null) { - codeStream.addVariable(this.saveValueVariable); codeStream.load(this.saveValueVariable); } if (this.expression != null && !alreadyGeneratedExpression) { this.expression.generateCode(currentScope, codeStream, true); + // hook necessary for Code Snippet generateStoreSaveValueIfNecessary(codeStream); } // output the suitable return bytecode or wrap the value inside a descriptor for doits @@ -179,6 +187,8 @@ public void generateReturnBytecode(CodeStream codeStream) { public void generateStoreSaveValueIfNecessary(CodeStream codeStream){ if (this.saveValueVariable != null) { codeStream.store(this.saveValueVariable, false); + // the variable is visible as soon as the local is stored + codeStream.addVariable(this.saveValueVariable); } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java index 5944bb3f0..a9fca1bfa 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -7,9 +7,11 @@ * * Contributors: * IBM Corporation - initial API and implementation - * Stephan Herrmann - Contribution for bug 332637 - Dead Code detection removing code that isn't dead * Fraunhofer FIRST - extended API and implementation * Technical University Berlin - extended API and implementation + * Stephan Herrmann - Contributions for + * bug 332637 - Dead Code detection removing code that isn't dead + * bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; @@ -74,6 +76,7 @@ public class TryStatement extends SubRoutineStatement { // for local variables table attributes int mergedInitStateIndex = -1; int preTryInitStateIndex = -1; + int postTryInitStateIndex = -1; int[] postResourcesInitStateIndexes; int naturalExitMergeInitStateIndex = -1; int[] catchExitInitStateIndexes; @@ -159,7 +162,9 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) this.bits |= ASTNode.IsTryBlockExiting; } - + if (resourcesLength > 0) { + this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo); + } // check unreachable catch blocks handlingContext.complainIfUnusedExceptionHandlers(this.scope, this); @@ -272,7 +277,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl if (closeMethod != null && closeMethod.returnType.id == TypeIds.T_void) { ReferenceBinding[] thrownExceptions = closeMethod.thrownExceptions; for (int j = 0, length = thrownExceptions.length; j < length; j++) { - handlingContext.checkExceptionHandlers(thrownExceptions[j], this.resources[j], flowInfo, currentScope); + handlingContext.checkExceptionHandlers(thrownExceptions[j], this.resources[i], flowInfo, currentScope, true); } } } @@ -285,7 +290,9 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) this.bits |= ASTNode.IsTryBlockExiting; } - + if (resourcesLength > 0) { + this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo); + } // check unreachable catch blocks handlingContext.complainIfUnusedExceptionHandlers(this.scope, this); @@ -516,6 +523,13 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) { // inline resource closure if (i > 0) { int invokeCloseStartPc = codeStream.position; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785 + if (this.postTryInitStateIndex != -1) { + /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=361053, we are just past a synthetic instance of try-catch-finally. + Our initialization type state is the same as it was at the end of the just concluded try (catch rethrows) + */ + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); + } codeStream.load(localVariable); codeStream.ifnull(exitLabel); codeStream.load(localVariable); @@ -903,9 +917,6 @@ public boolean generateSubRoutineInvocation(BlockScope currentScope, CodeStream if (isStackMapFrameCodeStream) { ((StackMapFrameCodeStream) codeStream).pushStateIndex(stateIndex); } - if (secretLocal != null) { - codeStream.addVariable(secretLocal); - } // cannot use jsr bytecode, then simply inline the subroutine // inside try block, ensure to deactivate all catch block exception handlers while inlining finally block exitAnyExceptionHandler(); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java index 14b884503..e61cde3c5 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java @@ -248,8 +248,17 @@ private void addStackDepthMarker(int pc, int delta, TypeBinding typeBinding) { this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding)); } else { int size = this.stackDepthMarkers.size(); - if (size == 0 || ((StackDepthMarker) this.stackDepthMarkers.get(size - 1)).pc != this.position) { + if (size == 0) { this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding)); + } else { + StackDepthMarker stackDepthMarker = (StackDepthMarker) this.stackDepthMarkers.get(size - 1); + if (stackDepthMarker.pc != this.position) { + this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding)); + } else { + // We replace the recorded stack depth marker with a new value that contains the given typeBinding + // This case can happen when multiple conditional expression are nested see bug 362591 + this.stackDepthMarkers.set(size - 1, new StackDepthMarker(pc, delta, typeBinding)); + } } } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java index c137b4276..5cb416656 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java @@ -252,4 +252,9 @@ public boolean isMarkedAsNullOrNonNullInAssertExpression(LocalVariableBinding lo return (this.initsWhenTrue.isMarkedAsNullOrNonNullInAssertExpression(local) || this.initsWhenFalse.isMarkedAsNullOrNonNullInAssertExpression(local)); } + +public void resetAssignmentInfo(LocalVariableBinding local) { + this.initsWhenTrue.resetAssignmentInfo(local); + this.initsWhenFalse.resetAssignmentInfo(local); +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java index e768ff0da..036b82469 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Stephan Herrmann - Contribution for bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis *******************************************************************************/ package org.eclipse.jdt.internal.compiler.flow; @@ -197,11 +198,13 @@ public void checkExceptionHandlers(TypeBinding raisedException, ASTNode location traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); - if (traversedContext instanceof InsideSubRoutineFlowContext) { - ASTNode node = traversedContext.associatedNode; - if (node instanceof TryStatement) { - TryStatement tryStatement = (TryStatement) node; - flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits + if (!isExceptionOnAutoClose) { + if (traversedContext instanceof InsideSubRoutineFlowContext) { + ASTNode node = traversedContext.associatedNode; + if (node instanceof TryStatement) { + TryStatement tryStatement = (TryStatement) node; + flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits + } } } traversedContext = traversedContext.parent; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java index fbd9d11f5..24ae47ba6 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java @@ -591,6 +591,12 @@ abstract public void markedAsNullOrNonNullInAssertExpression(LocalVariableBindin //https://bugs.eclipse.org/bugs/show_bug.cgi?id=303448 abstract public boolean isMarkedAsNullOrNonNullInAssertExpression(LocalVariableBinding local); +/** + * Resets the definite and potential initialization info for the given local variable + * @param local + */ +abstract public void resetAssignmentInfo(LocalVariableBinding local); + //{ObjectTeams: public boolean isDefinitelyAssigned(BaseCallTrackingVariable baseCallTrackingVariable) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java index 2e2fef88e..325410edf 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java @@ -2152,5 +2152,29 @@ private void combineNullStatusChangeInAssertInfo(UnconditionalFlowInfo otherInit } } } + +public void resetAssignmentInfo(LocalVariableBinding local) { + resetAssignmentInfo(local.id + this.maxFieldCount); +} + +public void resetAssignmentInfo(int position) { + if (this != DEAD_END) { + // position is zero-based + if (position < BitCacheSize) { + // use bits + long mask; + this.definiteInits &= (mask = ~(1L << position)); + this.potentialInits &= mask; + } else { + // use extra vector + int vectorIndex = (position / BitCacheSize) - 1; + if (this.extra == null || vectorIndex >= this.extra[0].length) return; // variable doesnt exist in flow info + long mask; + this.extra[0][vectorIndex] &= + (mask = ~(1L << (position % BitCacheSize))); + this.extra[1][vectorIndex] &= mask; + } + } +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java index dfe33bc69..8f93f426e 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java @@ -1464,7 +1464,13 @@ public ReferenceBinding getTypeFromCompoundName(char[][] compoundName, boolean i packageBinding.addType(binding); } else if (binding == TheNotFoundType) { // report the missing class file first - this.problemReporter.isClassPathCorrect(compoundName, this.unitBeingCompleted, this.missingClassFileLocation); + if (!wasMissingType) { + /* Since missing types have been already been complained against while producing binaries, there is no class path + * misconfiguration now that did not also exist in some equivalent form while producing the class files which encode + * these missing types. So no need to bark again. Note that wasMissingType == true signals a type referenced in a .class + * file which could not be found when the binary was produced. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450 */ + this.problemReporter.isClassPathCorrect(compoundName, this.unitBeingCompleted, this.missingClassFileLocation); + } // create a proxy for the missing BinaryType binding = createMissingType(null, compoundName); } else if (!isParameterized) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java index 7d6139b84..1eab7c306 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java @@ -14,6 +14,7 @@ package org.eclipse.jdt.internal.compiler.lookup; +import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.Argument; @@ -512,7 +513,8 @@ void checkMethods() { for (int i = 0; i < length; i++) { MethodBinding inheritedMethod = inherited[i]; if (inheritedMethod.isPublic() && !inheritedMethod.declaringClass.isPublic()) - this.type.addSyntheticBridgeMethod(inheritedMethod.original()); + if (!CharOperation.equals(inheritedMethod.declaringClass.qualifiedPackageName(), CharOperation.NO_CHAR)) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343060 + this.type.addSyntheticBridgeMethod(inheritedMethod.original()); } } @@ -596,7 +598,8 @@ void checkMethods() { if (matchMethod == null && current != null && this.type.isPublic()) { // current == null case handled already. MethodBinding inheritedMethod = inherited[i]; if (inheritedMethod.isPublic() && !inheritedMethod.declaringClass.isPublic()) { - this.type.addSyntheticBridgeMethod(inheritedMethod.original()); + if (!CharOperation.equals(inheritedMethod.declaringClass.qualifiedPackageName(), CharOperation.NO_CHAR)) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343060 + this.type.addSyntheticBridgeMethod(inheritedMethod.original()); } } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660, if current type is exposed, diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java index 79979dfea..14da64211 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2011 IBM Corporation and others. + * Copyright (c) 2005, 2012 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 @@ -710,7 +710,7 @@ public class ParameterizedTypeBinding extends ReferenceBinding implements Substi } break; case Binding.INTERSECTION_TYPE : - this.tagBits |= TagBits.HasDirectWildcard; + this.tagBits |= TagBits.HasDirectWildcard | TagBits.IsBoundParameterizedType; // Surely NOT X, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=366131 break; default : this.tagBits |= TagBits.IsBoundParameterizedType; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java index 424f75176..9bdc14e0f 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java @@ -652,7 +652,10 @@ public abstract class Scope { } return method; } - if (genericTypeArguments != null) + // if method is generic and type arguments have been supplied, only then answer a problem + // of ParameterizedMethodTypeMismatch, else a non-generic method was invoked using type arguments + // in which case this problem category will be bogus + if (genericTypeArguments != null && typeVariables != Binding.NO_TYPE_VARIABLES) return new ProblemMethodBinding(method, method.selector, arguments, ProblemReasons.ParameterizedMethodTypeMismatch); return null; // incompatible } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java index bd85911c0..bb4b3220a 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java @@ -352,7 +352,7 @@ public class TryStatement extends Statement { */ public List resources() { // more efficient than just calling unsupportedIn2_3() to check - if (this.resources == null) { + if (this.resources != null) { unsupportedIn2_3(); } return this.resources; diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java index d823ab6b6..d834f8271 100644 --- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java +++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java @@ -112,7 +112,6 @@ import org.eclipse.jdt.internal.compiler.ast.WhileStatement; import org.eclipse.jdt.internal.compiler.ast.Wildcard; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; -import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.ClassScope; import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; @@ -3845,8 +3844,7 @@ public class CodeFormatterVisitor extends ASTVisitor { if (numberOfParens > 0) { manageOpeningParenthesizedExpression(doubleLiteral, numberOfParens); } - Constant constant = doubleLiteral.constant; - if (constant != null && constant.doubleValue() < 0) { + if (isNextToken(TerminalTokens.TokenNameMINUS)) { this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); } this.scribe.printNextToken(TerminalTokens.TokenNameDoubleLiteral); @@ -4070,8 +4068,7 @@ public class CodeFormatterVisitor extends ASTVisitor { if (numberOfParens > 0) { manageOpeningParenthesizedExpression(floatLiteral, numberOfParens); } - Constant constant = floatLiteral.constant; - if (constant != null && floatLiteral.constant.floatValue() < 0) { + if (isNextToken(TerminalTokens.TokenNameMINUS)) { this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); } this.scribe.printNextToken(TerminalTokens.TokenNameFloatingPointLiteral); @@ -4384,8 +4381,7 @@ public class CodeFormatterVisitor extends ASTVisitor { if (numberOfParens > 0) { manageOpeningParenthesizedExpression(intLiteral, numberOfParens); } - Constant constant = intLiteral.constant; - if (constant != null && constant.intValue() < 0) { + if (isNextToken(TerminalTokens.TokenNameMINUS)) { this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); } this.scribe.printNextToken(TerminalTokens.TokenNameIntegerLiteral); @@ -4435,8 +4431,7 @@ public class CodeFormatterVisitor extends ASTVisitor { if (numberOfParens > 0) { manageOpeningParenthesizedExpression(longLiteral, numberOfParens); } - Constant constant = longLiteral.constant; - if (constant != null && constant.longValue() < 0) { + if (isNextToken(TerminalTokens.TokenNameMINUS)) { this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); } this.scribe.printNextToken(TerminalTokens.TokenNameLongLiteral); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java index dbc6e55c7..8d485abb8 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -114,4 +114,13 @@ public interface IJavaModelMarker { * @since 2.0 */ String CLASSPATH_FILE_FORMAT = "classpathFileFormat"; //$NON-NLS-1$ + + /** + * Output overlapping another source attribute (value "outputOverlappingSource"). + * Used only on buildpath problem markers. The value of this attribute is + * either "true" or "false". + * + * @since 3.6.4 + */ + String OUTPUT_OVERLAPPING_SOURCE = "outputOverlappingSource"; //$NON-NLS-1$ } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java index 4cc2f456b..a88db5e10 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java @@ -345,4 +345,11 @@ public interface IJavaModelStatusConstants { * @since 3.7 */ public static final int CANNOT_RETRIEVE_ATTACHED_JAVADOC_TIMEOUT = 1012; + + /** + *

Status constant indicating that the default or specific output folder is overlapping + * with another source location.

+ * @since 3.6.4 + */ + public static final int OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = 1013; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java index a051e9122..4575100cf 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -618,11 +618,13 @@ public final class JavaConventions { *
  • The project output location path cannot be null, must be absolute and located inside the project. *
  • Specific output locations (specified on source entries) can be null, if not they must be located inside the project, *
  • A project entry cannot refer to itself directly (that is, a project cannot prerequisite itself). - *
  • Classpath entries or output locations cannot coincidate or be nested in each other, except for the following scenarii listed below: - *
    • A source folder can coincidate with its own output location, in which case this output can then contain library archives. - * However, a specific output location cannot coincidate with any library or a distinct source folder than the one referring to it.
    • + *
    • Classpath entries or output locations cannot coincide or be nested in each other, except for the following scenarios listed below: + *
      • A source folder can coincide with its own output location, in which case this output can then contain library archives. + * However, a specific output location cannot coincide with any library or a distinct source folder than the one referring to it.
        + * Note: Since 3.8, this behavior can be overridden by configuring {@link JavaCore#CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE} + *
      • *
      • A source/library folder can be nested in any source folder as long as the nested folder is excluded from the enclosing one.
      • - *
      • An output location can be nested in a source folder, if the source folder coincidates with the project itself, or if the output + *
      • An output location can be nested in a source folder, if the source folder coincides with the project itself, or if the output * location is excluded from the source folder. *
      *
    diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java index 37afb4b9a..25e2c9d3a 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java @@ -1846,6 +1846,19 @@ public final class JavaCore extends Plugin { * @category CoreOptionID */ public static final String CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS = PLUGIN_ID + ".classpath.multipleOutputLocations"; //$NON-NLS-1$ + /** + * Core option ID: Reporting an output location overlapping another source location. + *

    Indicate the severity of the problem reported when a source entry's output location overlaps another + * source entry.

    + * + *
    + *
    Option id:
    "org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource"
    + *
    Possible values:
    { "error", "warning", "ignore" }
    + *
    Default:
    "warning"
    + *
    + * @since 3.6.4 + */ + public static final String CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = PLUGIN_ID + ".classpath.outputOverlappingAnotherSource"; //$NON-NLS-1$ /** * Core option ID: Set the timeout value for retrieving the method's parameter names from javadoc. *

    Timeout in milliseconds to retrieve the method's parameter names from javadoc. @@ -3714,6 +3727,7 @@ public final class JavaCore extends Plugin { try { if (JavaBuilder.DEBUG) System.out.println("Touching " + project.getElementName()); //$NON-NLS-1$ + new ClasspathValidation((JavaProject) project).validate(); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164 project.getProject().touch(progressMonitor2); } catch (CoreException e) { // could not touch this project: ignore diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java index d8086ffc9..6cfc987c1 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java @@ -1776,6 +1776,7 @@ public class ClasspathEntry implements IClasspathEntry { // perform one separate iteration so as to not take precedence over previously checked scenarii (in particular should // diagnose nesting source folder issue before this one, for example, [src]"Project/", [src]"Project/source/" and output="Project/" should // first complain about missing exclusion pattern + IJavaModelStatus cachedStatus = null; for (int i = 0 ; i < length; i++) { IClasspathEntry entry = classpath[i]; if (entry == null) continue; @@ -1788,30 +1789,53 @@ public class ClasspathEntry implements IClasspathEntry { if (kind == IClasspathEntry.CPE_SOURCE) { IPath output = entry.getOutputLocation(); - if (output == null) continue; // 36465 - for 2.0 backward compatibility, only check specific output locations (the default can still coincidate) - // if (output == null) output = projectOutputLocation; // if no specific output, still need to check using default output (this line would check default output) + if (output == null) output = projectOutputLocation; // if no specific output, still need to check using default output (this line would check default output) for (int j = 0; j < length; j++) { IClasspathEntry otherEntry = classpath[j]; if (otherEntry == entry) continue; - // Build some common strings for status message - boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0)); - String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString(); - switch (otherEntry.getEntryKind()) { case IClasspathEntry.CPE_SOURCE : - if (otherEntry.getPath().equals(output)) { - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] {entryPathMsg, otherPathMsg, projectName})); + // Bug 287164 : Report errors of overlapping output locations only if the user sets the corresponding preference. + // The check is required for backward compatibility with bug-fix 36465. + String option = javaProject.getOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, true); + if (otherEntry.getPath().equals(output) + && !JavaCore.IGNORE.equals(option)) { + boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0)); + String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString(); + if (JavaCore.ERROR.equals(option)) { + return new JavaModelStatus(IStatus.ERROR, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, + Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] { + entryPathMsg, otherPathMsg, projectName })); + } + if (cachedStatus == null) { + // Note that the isOK() is being overridden to return true. This is an exceptional scenario + cachedStatus = new JavaModelStatus(IStatus.OK, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, + Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] { + entryPathMsg, otherPathMsg, projectName })){ + public boolean isOK() { + return true; + } + }; + } } break; case IClasspathEntry.CPE_LIBRARY : - if (otherEntry.getPath().equals(output)) { + if (output != projectOutputLocation && otherEntry.getPath().equals(output)) { + boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0)); + String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString(); return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotUseLibraryAsOutput, new String[] {entryPathMsg, otherPathMsg, projectName})); } } } } } + + // NOTE: The above code that checks for IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, can be configured to return + // a WARNING status and hence should be at the end of this validation method. Any other code that might return a more severe ERROR should be + // inserted before the mentioned code. + if (cachedStatus != null) return cachedStatus; + return JavaModelStatus.VERIFIED_OK; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java index ea310a3c2..345535ac1 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -12,6 +12,7 @@ package org.eclipse.jdt.internal.core; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaModelStatus; import org.eclipse.jdt.core.JavaModelException; @@ -37,7 +38,7 @@ public class ClasspathValidation { // project doesn't exist IProject resource = this.project.getProject(); if (resource.isAccessible()) { - this.project.flushClasspathProblemMarkers(true/*flush cycle markers*/, true/*flush classpath format markers*/); + this.project.flushClasspathProblemMarkers(true/*flush cycle markers*/, true/*flush classpath format markers*/, true /*flush overlapping output markers*/); // remove problems and tasks created by the builder JavaBuilder.removeProblemsAndTasksFor(resource); @@ -56,12 +57,15 @@ public class ClasspathValidation { } // update classpath format problems - this.project.flushClasspathProblemMarkers(false/*cycle*/, true/*format*/); + this.project.flushClasspathProblemMarkers(false/*cycle*/, true/*format*/, false/*overlapping*/); if (!status.isOK()) this.project.createClasspathProblemMarker(status); + // update overlapping output problem markers + this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/, true/*overlapping*/); + // update resolved classpath problems - this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/); + this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/, false/*overlapping*/); if (rawClasspath != JavaProject.INVALID_CLASSPATH && outputLocation != null) { for (int i = 0; i < rawClasspath.length; i++) { @@ -71,7 +75,7 @@ public class ClasspathValidation { } } status = ClasspathEntry.validateClasspath(this.project, rawClasspath, outputLocation); - if (!status.isOK()) + if (status.getCode() != IStatus.OK) this.project.createClasspathProblemMarker(status); } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java index f2b617350..4a1d8ba87 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -100,8 +100,9 @@ public class CompilationUnitProblemFinder extends Compiler { */ public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) { // ensure to jump back to toplevel type for first one (could be a member) -// while (sourceTypes[0].getEnclosingType() != null) -// sourceTypes[0] = sourceTypes[0].getEnclosingType(); + while (sourceTypes[0].getEnclosingType() != null) { + sourceTypes[0] = sourceTypes[0].getEnclosingType(); + } CompilationResult result = new CompilationResult(sourceTypes[0].getFileName(), 1, 1, this.options.maxProblemsPerUnit); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java index 532ed94d7..835d1d6bf 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java @@ -58,6 +58,7 @@ public class JavaCorePreferenceInitializer extends AbstractPreferenceInitializer defaultOptionsMap.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.IGNORE); defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, JavaCore.ENABLED); defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, JavaCore.ENABLED); + defaultOptionsMap.put(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.WARNING); // encoding setting comes from resource plug-in optionNames.add(JavaCore.CORE_ENCODING); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java index 1b901c567..010e2a322 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -1417,9 +1417,7 @@ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeLis public static boolean CP_RESOLVE_VERBOSE_ADVANCED = false; public static boolean CP_RESOLVE_VERBOSE_FAILURE = false; public static boolean ZIP_ACCESS_VERBOSE = false; - // temporary debug flag to track failures of bug 302850 - public static boolean DEBUG_302850 = false; - + /** * A cache of opened zip files per thread. * (for a given thread, the object value is a HashMap from IPath to java.io.ZipFile) @@ -1486,7 +1484,8 @@ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeLis propertyName.equals(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS) || propertyName.equals(JavaCore.CORE_INCOMPLETE_CLASSPATH) || propertyName.equals(JavaCore.CORE_CIRCULAR_CLASSPATH) || - propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL)) { + propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL) || + propertyName.equals(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE)) { JavaModelManager manager = JavaModelManager.getJavaModelManager(); IJavaModel model = manager.getJavaModel(); IJavaProject[] projects; @@ -2158,13 +2157,10 @@ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeLis // return cached options if already computed Hashtable cachedOptions; // use a local variable to avoid race condition (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=256329 ) if ((cachedOptions = this.optionsCache) != null) { - if (DEBUG_302850) checkTaskTags("Retrieving options from optionsCache", this.optionsCache); //$NON-NLS-1$ return new Hashtable(cachedOptions); } - if (DEBUG_302850) System.out.println("optionsCache was null"); //$NON-NLS-1$ if (!Platform.isRunning()) { this.optionsCache = getDefaultOptionsNoInitialization(); - if (DEBUG_302850) checkTaskTags("Platform is not running", this.optionsCache); //$NON-NLS-1$ return new Hashtable(this.optionsCache); } // init @@ -2180,7 +2176,6 @@ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeLis options.put(propertyName, propertyValue); } } - if (DEBUG_302850) checkTaskTags("Options initialized from preferences", options); //$NON-NLS-1$ // set deprecated options using preferences service lookup Iterator deprecatedEntries = this.deprecatedOptions.entrySet().iterator(); @@ -2206,30 +2201,12 @@ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeLis addDeprecatedOptions(options); Util.fixTaskTags(options); - if (DEBUG_302850) checkTaskTags("Retrieved options from preferences", options); //$NON-NLS-1$ // store built map in cache this.optionsCache = new Hashtable(options); - if (DEBUG_302850) checkTaskTags("Stored optionsCache", this.optionsCache); //$NON-NLS-1$ - // return built map return options; } - // debugging bug 302850: - private void checkTaskTags(String msg, Hashtable someOptions) { - System.out.println(msg); - Object taskTags = someOptions.get(JavaCore.COMPILER_TASK_TAGS); - System.out.println(" + Task tags: " + taskTags); //$NON-NLS-1$ - if (taskTags == null || "".equals(taskTags)) { //$NON-NLS-1$ - System.out.println(" - option names: "+this.optionNames); //$NON-NLS-1$ - System.out.println(" - Call stack:"); //$NON-NLS-1$ - StackTraceElement[] elements = new Exception().getStackTrace(); - for (int i=0,n=elements.length; i