Merge branch 'master' into BETA_JAVA9
Conflicts:
org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/APTProblem.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/APTProblem.java
index 1eb5b18..ac7043b 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/APTProblem.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/APTProblem.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2008 BEA Systems, Inc.
+ * Copyright (c) 2005, 2015 BEA Systems, Inc.
* 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,6 +101,10 @@
public boolean isWarning() {
return _severity == Severity.WARNING;
}
+
+ public boolean isInfo() {
+ return _severity == Severity.INFO;
+ }
public String toString()
{
diff --git a/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/dispatch/IdeAnnotationProcessorManager.java b/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/dispatch/IdeAnnotationProcessorManager.java
index a640b71..12cfc0c 100644
--- a/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/dispatch/IdeAnnotationProcessorManager.java
+++ b/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/dispatch/IdeAnnotationProcessorManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 BEA Systems, Inc.
+ * Copyright (c) 2007, 2015 BEA Systems, Inc 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:
* wharley@bea.com - initial API and implementation
+ * IBM Corporation - Bug 478427
*
*******************************************************************************/
@@ -97,7 +98,7 @@
}
_processors.add(pi);
return pi;
- } catch (CoreException e) {
+ } catch (CoreException | NoClassDefFoundError e) {
Apt6Plugin.log(e, "Unable to create instance of annotation processor " + entry.getKey()); //$NON-NLS-1$
}
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
index 9faff6b..e97fd1d 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/typeutils/TypeUtilsProc.java b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/typeutils/TypeUtilsProc.java
index 73130a8..b0b4a36 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/typeutils/TypeUtilsProc.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/typeutils/TypeUtilsProc.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 - 2012 BEA Systems, Inc. and others
+ * Copyright (c) 2007 - 2015 BEA Systems, Inc. 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:
* Walter Harley - initial API and implementation
+ * IBM Corporation - Bug 382590
*******************************************************************************/
package org.eclipse.jdt.compiler.apt.tests.processors.typeutils;
@@ -405,10 +406,6 @@
return false;
}
ExecutableType etm = (ExecutableType)tm;
- if (!etm.getParameterTypes().isEmpty()) {
- reportError(method + ": member m() should be void, but it had parameters");
- return false;
- }
if (!_typeUtils.isSameType(etm.getReturnType(), longType)) {
reportError(method + ": member m() should have Long return type, but found " + etm.getReturnType());
return false;
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/AsMemberOf.java b/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/AsMemberOf.java
index 5df21e7..473887c 100644
--- a/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/AsMemberOf.java
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/AsMemberOf.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Walter Harley and others
+ * Copyright (c) 2015 Walter Harley 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
@@ -15,7 +15,7 @@
*/
public class AsMemberOf<T> {
private T f;
- private T m() { return f; }
+ protected T m(T[] t1, T t2) { return f; }
E<Integer> e = new E<Integer>();
// Type parameter 'T' of static class is unrelated to 'T' of containing class
@@ -39,7 +39,7 @@
// even when accesed through a subclass; this is not explicitly specified, but
// is true for javac 1.6.
T publicize() {
- return (m() == null) ? new C<T>().x() : new D().x();
+ return (m(null, null) == null) ? new C<T>().x() : new D().x();
}
}
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java
index dabeb0e..820a899 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java
@@ -7,7 +7,7 @@
*
* Contributors:
* Walter Harley - initial API and implementation
- * IBM Corporation - fix for 342598
+ * IBM Corporation - fix for 342598, 382590
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.apt.model;
@@ -85,8 +85,8 @@
MethodBinding methodBinding = (MethodBinding) elementImpl._binding;
while (referenceBinding != null) {
for (MethodBinding method : referenceBinding.methods()) {
- if (CharOperation.equals(method.selector, methodBinding.selector)
- && method.areParameterErasuresEqual(methodBinding)) {
+ if (CharOperation.equals(method.selector, methodBinding.selector) &&
+ (method.original() == methodBinding || method.areParameterErasuresEqual(methodBinding))) {
return this._env.getFactory().newTypeMirror(method);
}
}
diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ParticipantBuildTests.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ParticipantBuildTests.java
index 3ebc172..3da8163 100644
--- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ParticipantBuildTests.java
+++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ParticipantBuildTests.java
@@ -69,6 +69,7 @@
public int getSourceLineNumber() { return 1; }
public boolean isError() { return true; }
public boolean isWarning() { return false; }
+ public boolean isInfo() { return false; }
public void setSourceEnd(int sourceEnd) {/* not needed */}
public void setSourceLineNumber(int lineNumber) {/* not needed */}
public void setSourceStart(int sourceStart) {/* not needed */}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index 69a4f05..f7501d8 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -103,14 +103,6 @@
long compliance;
public static final long EXIT_VALUE_MASK = 0x00000000FFFFFFFFL;
public static final long ERROR_LOG_MASK = 0xFFFFFFFF00000000L;
- private static final String[] jarsNames = new String[] {
- "/lib/vm.jar",
- "/lib/rt.jar",
- "/lib/core.jar",
- "/lib/security.jar",
- "/lib/xml.jar",
- "/lib/graphics.jar"
- };
private String classpath;
JavacCompiler(String rootDirectoryPath) throws IOException, InterruptedException {
this(rootDirectoryPath, null);
@@ -163,11 +155,6 @@
this.minor = minorFromRawVersion(this.version, rawVersion);
this.rawVersion = rawVersion;
StringBuffer classpathBuffer = new StringBuffer(" -classpath ");
- for (int i = 0, l = jarsNames.length; i < l; i++) {
- classpathBuffer.append(rootDirectoryPath);
- classpathBuffer.append(jarsNames[i]);
- classpathBuffer.append(File.pathSeparator);
- }
this.classpath = classpathBuffer.toString();
}
// projects known raw versions to minors; minors should grow with time, so
@@ -206,6 +193,12 @@
if ("1.8.0-ea".equals(rawVersion) || ("1.8.0".equals(rawVersion))) {
return 0000;
}
+ if ("1.8.0_40".equals(rawVersion)) {
+ return 1000; // corresponds to JLS maintenance release 2015-02-13
+ }
+ if ("1.8.0_60".equals(rawVersion)) {
+ return 1500;
+ }
}
throw new RuntimeException("unknown raw javac version: " + rawVersion);
}
@@ -1734,6 +1727,9 @@
if (newOptions.indexOf(" -d ") < 0) {
options.setCompilerOptions(newOptions.concat(" -d ."));
}
+ if (newOptions.indexOf(" -Xlint") < 0) {
+ options.setCompilerOptions(newOptions.concat(" -Xlint"));
+ }
String testName = testName();
Iterator compilers = javacCompilers.iterator();
while (compilers.hasNext()) {
@@ -3011,7 +3007,7 @@
version = version.substring(0, eol);
cmdLineHeader.append(" -d ");
cmdLineHeader.append(JAVAC_OUTPUT_DIR_NAME.indexOf(" ") != -1 ? "\"" + JAVAC_OUTPUT_DIR_NAME + "\"" : JAVAC_OUTPUT_DIR_NAME);
- cmdLineHeader.append(" -source 1.5 -deprecation -Xlint:unchecked "); // enable recommended warnings
+ cmdLineHeader.append(" -source 1.5 -deprecation -Xlint "); // enable recommended warnings
// WORK new javac system does not do that... reconsider
// REVIEW consider enabling all warnings instead? Philippe does not see
// this as ez to use (too many changes in logs)
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
index 2bdac0c..2efbb3e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
@@ -11480,4 +11480,174 @@
"Type mismatch: cannot convert from RetentionPolicy[] to RetentionPolicy\n" +
"----------\n");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=472178
+public void test472178() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_8) {
+ return; // Enough to run in 3 levels rather!
+ }
+ String source =
+ "import java.lang.annotation.ElementType;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import java.lang.annotation.RetentionPolicy;\n" +
+ "import java.lang.annotation.Target;\n" +
+ "import java.util.ArrayList;\n" +
+ "import java.util.Iterator;\n" +
+ " \n" +
+ "/**\n" +
+ " * @author gglab\n" +
+ " */\n" +
+ "public class Test<X> extends ArrayList<X> {\n" +
+ " public void iterateRemove()\n" +
+ " {\n" +
+ " for (Iterator<X> iter = this.iterator(); iter.hasNext();) {\n" +
+ " Object key = iter.next();\n" +
+ " @Flowannotation\n" +
+ " Foo<@Flowannotation String> f = new Foo<String>();\n" +
+ " @Flowannotation long l = (@Flowannotation long)f.getI(); // this line causes parse error\n" +
+ " iter.remove();\n" +
+ " }\n" +
+ " }\n" +
+ " \n" +
+ " @Flowannotation\n" +
+ " class Foo<@Flowannotation T>\n" +
+ " {\n" +
+ " @Flowannotation\n" +
+ " public int getI()\n" +
+ " {\n" +
+ " return 3;\n" +
+ " }\n" +
+ " }\n" +
+ " \n" +
+ " @Target({ ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.METHOD, ElementType.LOCAL_VARIABLE, ElementType.TYPE, ElementType.FIELD,\n" +
+ " ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})\n" +
+ " @Retention(RetentionPolicy.RUNTIME)\n" +
+ " @interface Flowannotation {}\n" +
+ " public static void main(String[] args) {}\n" +
+ "}";
+ String expectedOutput =
+ " // Method descriptor #6 ()V\n" +
+ " // Stack: 3, Locals: 6\n" +
+ " public void iterateRemove();\n" +
+ " 0 aload_0 [this]\n" +
+ " 1 invokevirtual Test.iterator() : Iterator [17]\n" +
+ " 4 astore_1 [iter]\n" +
+ " 5 goto 37\n" +
+ " 8 aload_1 [iter]\n" +
+ " 9 invokeinterface Iterator.next() : Object [21] [nargs: 1]\n" +
+ " 14 astore_2 [key]\n" +
+ " 15 new Test$Foo [27]\n" +
+ " 18 dup\n" +
+ " 19 aload_0 [this]\n" +
+ " 20 invokespecial Test$Foo(Test) [29]\n" +
+ " 23 astore_3 [f]\n" +
+ " 24 aload_3 [f]\n" +
+ " 25 invokevirtual Test$Foo.getI() : int [32]\n" +
+ " 28 i2l\n" +
+ " 29 lstore 4 [l]\n" +
+ " 31 aload_1 [iter]\n" +
+ " 32 invokeinterface Iterator.remove() : void [36] [nargs: 1]\n" +
+ " 37 aload_1 [iter]\n" +
+ " 38 invokeinterface Iterator.hasNext() : boolean [39] [nargs: 1]\n" +
+ " 43 ifne 8\n" +
+ " 46 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 14]\n" +
+ " [pc: 8, line: 15]\n" +
+ " [pc: 15, line: 17]\n" +
+ " [pc: 24, line: 18]\n" +
+ " [pc: 31, line: 19]\n" +
+ " [pc: 37, line: 14]\n" +
+ " [pc: 46, line: 21]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 47] local: this index: 0 type: Test\n" +
+ " [pc: 5, pc: 46] local: iter index: 1 type: Iterator\n" +
+ " [pc: 15, pc: 37] local: key index: 2 type: Object\n" +
+ " [pc: 24, pc: 37] local: f index: 3 type: Foo\n" +
+ " [pc: 31, pc: 37] local: l index: 4 type: long\n" +
+ " Local variable type table:\n" +
+ " [pc: 0, pc: 47] local: this index: 0 type: Test<X>\n" +
+ " [pc: 5, pc: 46] local: iter index: 1 type: Iterator<X>\n" +
+ " [pc: 24, pc: 37] local: f index: 3 type: String>\n" +
+ " Stack map table: number of frames 2\n" +
+ " [pc: 8, append: {Iterator}]\n" +
+ " [pc: 37, same]\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #55 @Flowannotation(\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 24\n" +
+ " type argument index = 0\n" +
+ " )\n" +
+ " #55 @Flowannotation(\n" +
+ " target type = 0x40 LOCAL_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 24, pc: 37] index: 3\n" +
+ " location = [INNER_TYPE]\n" +
+ " )\n" +
+ " #55 @Flowannotation(\n" +
+ " target type = 0x40 LOCAL_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 24, pc: 37] index: 3\n" +
+ " location = [INNER_TYPE, TYPE_ARGUMENT(0)]\n" +
+ " )\n" +
+ " #55 @Flowannotation(\n" +
+ " target type = 0x40 LOCAL_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 31, pc: 37] index: 4\n" +
+ " )\n";
+ checkClassFile("Test", source, expectedOutput, ClassFileBytesDisassembler.DETAILED | ClassFileBytesDisassembler.COMPACT);
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=470665
+public void testBug470665() throws Exception {
+ if (this.complianceLevel <= ClassFileConstants.JDK1_7) {
+ return; // Enough to run in the last two levels!
+ }
+ boolean apt = this.enableAPT;
+ String[] sources = new String[] {
+ "A.java",
+ "public final class A {\n" +
+ " String myString;\n" +
+ " public interface B {\n" +
+ " void test();\n" +
+ " }\n" +
+ " private final B b = new B() {\n" +
+ " @Override\n" +
+ " public void test() {}\n" +
+ " }\n" +
+ "};\n" +
+ "}",
+ "B.java",
+ "public class B {\n" +
+ " private static class X {\n" +
+ " static final Object instance1;\n" +
+ " static {\n" +
+ " try {\n" +
+ " instance1 = new Object();\n" +
+ " } catch (Throwable e) {\n" +
+ " throw new AssertionError(e);\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " X x = new X();\n" +
+ " Object o = X.instance1;\n" +
+ "}"
+ };
+ try {
+ this.enableAPT = true;
+ runNegativeTest(sources,
+ "----------\n" +
+ "1. ERROR in A.java (at line 10)\n" +
+ " };\n" +
+ " ^\n" +
+ "Syntax error on token \"}\", delete this token\n" +
+ "----------\n" +
+ "----------\n" +
+ "1. WARNING in B.java (at line 12)\n" +
+ " X x = new X();\n" +
+ " ^^^^^^^\n" +
+ "Access to enclosing constructor B.X() is emulated by a synthetic accessor method\n" +
+ "----------\n");
+ } finally {
+ this.enableAPT = apt;
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FieldAccessTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FieldAccessTest.java
index d8afbee..6953309 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FieldAccessTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FieldAccessTest.java
@@ -14,6 +14,7 @@
import junit.framework.Test;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
@SuppressWarnings({ "unchecked", "rawtypes" })
@@ -769,6 +770,26 @@
"The field B.field is hiding a field from type Interface\n" +
"----------\n");
}
+public void testBug361039() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // to leverage autounboxing
+ runNegativeTest(
+ new String[] {
+ "Bug361039.java",
+ "public class Bug361039 {\n" +
+ " public Bug361039(boolean b) {\n" +
+ " }\n" +
+ " private Object foo() {\n" +
+ " return new Bug361039(!((Boolean)this.f));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Bug361039.java (at line 5)\n" +
+ " return new Bug361039(!((Boolean)this.f));\n" +
+ " ^\n" +
+ "f cannot be resolved or is not a field\n" +
+ "----------\n");
+}
public static Class testClass() {
return FieldAccessTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
index 60fbfd6..c230094 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
@@ -16827,7 +16827,9 @@
"6. WARNING in X.java (at line 10)\n" +
" EnumSet<Enum> eSet = EnumSet.allOf(c);\n" +
" ^\n" +
- "Type safety: The expression of type Class needs unchecked conversion to conform to Class<Enum>\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ? "Type safety: The expression of type Class needs unchecked conversion to conform to Class<Enum>\n"
+ : "Type safety: The expression of type Class needs unchecked conversion to conform to Class<Enum<Enum<E>>>\n") +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=86838 - variation
@@ -32091,7 +32093,9 @@
"5. WARNING in X.java (at line 7)\n" +
" Comparable c = newInstance2(x);\n" +
" ^\n" +
- "Type safety: The expression of type X needs unchecked conversion to conform to X<Comparable>\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ? "Type safety: The expression of type X needs unchecked conversion to conform to X<Comparable>\n"
+ : "Type safety: The expression of type X needs unchecked conversion to conform to X<Comparable<Comparable<B>>>\n") +
"----------\n" +
"6. ERROR in X.java (at line 9)\n" +
" Zork z;\n" +
@@ -33467,7 +33471,9 @@
"4. WARNING in X.java (at line 9)\n" +
" Iterator<Number> it1 = X.chain(new Iterator[] { l1.iterator(), l2.iterator() });\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: The expression of type Iterator[] needs unchecked conversion to conform to Iterator<Number>[]\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ? "Type safety: The expression of type Iterator[] needs unchecked conversion to conform to Iterator<Number>[]\n"
+ : "Type safety: The expression of type Iterator[] needs unchecked conversion to conform to Iterator<Object>[]\n") +
"----------\n" +
"5. ERROR in X.java (at line 14)\n" +
" Iterator<Number> it2 = X.chain(l1.iterator(), l2.iterator());\n" +
@@ -33605,7 +33611,7 @@
"4. WARNING in X.java (at line 9)\n" +
" Iterator<Number> it1 = X.chain(new Iterator[] { l1.iterator(), l2.iterator() });\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: The expression of type Iterator[] needs unchecked conversion to conform to Iterator<? extends Number>[]\n" +
+ "Type safety: The expression of type Iterator[] needs unchecked conversion to conform to Iterator<? extends Object>[]\n" +
"----------\n" +
"5. WARNING in X.java (at line 14)\n" +
" Iterator<Number> it2 = X.chain(l1.iterator(), l2.iterator());\n" +
@@ -50350,10 +50356,23 @@
" ^^^^^^^^^^^\n" +
"Type safety: Unchecked invocation foo(List, IllegalArgumentException) of the generic method foo(List<U>, T) of type X\n" +
"----------\n" +
- "3. WARNING in X.java (at line 8)\n" +
- " foo(l, iae);\n" +
- " ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ?
+ "3. WARNING in X.java (at line 8)\n" +
+ " foo(l, iae);\n" +
+ " ^\n" +
+ "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n"
+ :
+ "3. ERROR in X.java (at line 8)\n" +
+ " foo(l, iae);\n" +
+ " ^^^^^^^^^^^\n" +
+ "Unhandled exception type Throwable\n" + // new error since 1.8 (bug 473657)
+ "----------\n" +
+ "4. WARNING in X.java (at line 8)\n" +
+ " foo(l, iae);\n" +
+ " ^\n" +
+ "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n"
+ ) +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=258798 - variation
@@ -50385,10 +50404,23 @@
" ^^^^^^^^^^^^^\n" +
"Type safety: Unchecked invocation X(List, IllegalArgumentException) of the generic constructor X(List<U>, T) of type X\n" +
"----------\n" +
- "3. WARNING in X.java (at line 8)\n" +
- " new X(l, iae);\n" +
- " ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ?
+ "3. WARNING in X.java (at line 8)\n" +
+ " new X(l, iae);\n" +
+ " ^\n" +
+ "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n"
+ :
+ "3. ERROR in X.java (at line 8)\n" +
+ " new X(l, iae);\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "Unhandled exception type Throwable\n" + // new error since 1.8 (bug 473657)
+ "----------\n" +
+ "4. WARNING in X.java (at line 8)\n" +
+ " new X(l, iae);\n" +
+ " ^\n" +
+ "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n"
+ ) +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=258798 - variation
@@ -50420,10 +50452,23 @@
" ^^^^^^^^^^^^^^^\n" +
"Type safety: Unchecked invocation X(List, IllegalArgumentException) of the generic constructor X(List<U>, T) of type X\n" +
"----------\n" +
- "3. WARNING in X.java (at line 8)\n" +
- " new X(l, iae){};\n" +
- " ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ?
+ "3. WARNING in X.java (at line 8)\n" +
+ " new X(l, iae){};\n" +
+ " ^\n" +
+ "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n"
+ :
+ "3. ERROR in X.java (at line 8)\n" +
+ " new X(l, iae){};\n" +
+ " ^^^^^^^^^^^^^^^\n" +
+ "Unhandled exception type Throwable\n" + // new error since 1.8 (bug 473657)
+ "----------\n" +
+ "4. WARNING in X.java (at line 8)\n" +
+ " new X(l, iae){};\n" +
+ " ^\n" +
+ "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n"
+ ) +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=258798 - variation
@@ -50446,7 +50491,6 @@
" }\n" +
"}\n",//-----------------------------------------------------------------------
},
- (this.complianceLevel < ClassFileConstants.JDK1_8 ?
"----------\n" +
"1. WARNING in X.java (at line 7)\n" +
" this((List) null, null);\n" +
@@ -50487,44 +50531,7 @@
" super((List)lu, t);\n" +
" ^^^^\n" +
"List is a raw type. References to generic type List<E> should be parameterized\n" +
- "----------\n"
- : // 1.8 infers T in this((List) null, null) to RuntimeException, hence no error here (2. above)
- "----------\n" +
- "1. WARNING in X.java (at line 7)\n" +
- " this((List) null, null);\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: Unchecked invocation X(List, null) of the generic constructor X(List<U>, T) of type X\n" +
- "----------\n" +
- "2. WARNING in X.java (at line 7)\n" +
- " this((List) null, null);\n" +
- " ^^^^^^^^^^^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n" +
- "----------\n" +
- "3. WARNING in X.java (at line 7)\n" +
- " this((List) null, null);\n" +
- " ^^^^\n" +
- "List is a raw type. References to generic type List<E> should be parameterized\n" +
- "----------\n" +
- "4. WARNING in X.java (at line 12)\n" +
- " super((List)lu, t);\n" +
- " ^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: Unchecked invocation X(List, T) of the generic constructor X(List<U>, T) of type X\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 12)\n" +
- " super((List)lu, t);\n" +
- " ^^^^^^^^^^^^^^^^^^^\n" +
- "Unhandled exception type Throwable\n" +
- "----------\n" +
- "6. WARNING in X.java (at line 12)\n" +
- " super((List)lu, t);\n" +
- " ^^^^^^^^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<List<?>>\n" +
- "----------\n" +
- "7. WARNING in X.java (at line 12)\n" +
- " super((List)lu, t);\n" +
- " ^^^^\n" +
- "List is a raw type. References to generic type List<E> should be parameterized\n" +
- "----------\n"));
+ "----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=260567
public void test1440() {
@@ -50762,7 +50769,6 @@
"\n" +
"}\n",
},
- (this.complianceLevel < ClassFileConstants.JDK1_8 ?
"----------\n" +
"1. WARNING in X.java (at line 8)\n" +
" static void bar(List l) {\n" +
@@ -50792,12 +50798,16 @@
"6. WARNING in X.java (at line 9)\n" +
" new X(l).foo(l);\n" +
" ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<Throwable>\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ? "Type safety: The expression of type List needs unchecked conversion to conform to List<Throwable>\n"
+ : "Type safety: The expression of type List needs unchecked conversion to conform to List<RuntimeException>\n" ) +
"----------\n" +
"7. WARNING in X.java (at line 9)\n" +
" new X(l).foo(l);\n" +
" ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<Throwable>\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ? "Type safety: The expression of type List needs unchecked conversion to conform to List<Throwable>\n"
+ : "Type safety: The expression of type List needs unchecked conversion to conform to List<RuntimeException>\n" ) +
"----------\n" +
"8. WARNING in X.java (at line 11)\n" +
" static void baz(List l) throws IOException {\n" +
@@ -50863,100 +50873,7 @@
" new <IOException> X(l){}. <IOException> foo(l);\n" +
" ^\n" +
"Type safety: The expression of type List needs unchecked conversion to conform to List<IOException>\n" +
- "----------\n"
- : // 1.8 infers type parameters in throws clauses to RuntimeException, hence no errors
- "----------\n" +
- "1. WARNING in X.java (at line 8)\n" +
- " static void bar(List l) {\n" +
- " ^^^^\n" +
- "List is a raw type. References to generic type List<E> should be parameterized\n" +
- "----------\n" +
- "2. WARNING in X.java (at line 9)\n" +
- " new X(l).foo(l);\n" +
- " ^^^^^^^^\n" +
- "Type safety: Unchecked invocation X(List) of the generic constructor X(List<T>) of type X\n" +
- "----------\n" +
- "3. WARNING in X.java (at line 9)\n" +
- " new X(l).foo(l);\n" +
- " ^^^^^^^^^^^^^^^\n" +
- "Type safety: Unchecked invocation foo(List) of the generic method foo(List<T>) of type X\n" +
- "----------\n" +
- "4. WARNING in X.java (at line 9)\n" +
- " new X(l).foo(l);\n" +
- " ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<RuntimeException>\n" +
- "----------\n" +
- "5. WARNING in X.java (at line 9)\n" +
- " new X(l).foo(l);\n" +
- " ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<RuntimeException>\n" +
- "----------\n" +
- "6. WARNING in X.java (at line 11)\n" +
- " static void baz(List l) throws IOException {\n" +
- " ^^^^\n" +
- "List is a raw type. References to generic type List<E> should be parameterized\n" +
- "----------\n" +
- "7. WARNING in X.java (at line 12)\n" +
- " new <IOException> X(l). <IOException> foo(l);\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: Unchecked invocation X(List) of the generic constructor X(List<T>) of type X\n" +
- "----------\n" +
- "8. WARNING in X.java (at line 12)\n" +
- " new <IOException> X(l). <IOException> foo(l);\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: Unchecked invocation foo(List) of the generic method foo(List<T>) of type X\n" +
- "----------\n" +
- "9. WARNING in X.java (at line 12)\n" +
- " new <IOException> X(l). <IOException> foo(l);\n" +
- " ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<IOException>\n" +
- "----------\n" +
- "10. WARNING in X.java (at line 12)\n" +
- " new <IOException> X(l). <IOException> foo(l);\n" +
- " ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<IOException>\n" +
- "----------\n" +
- "11. WARNING in X.java (at line 15)\n" +
- " X(List l, long l2) throws IOException {\n" +
- " ^^^^\n" +
- "List is a raw type. References to generic type List<E> should be parameterized\n" +
- "----------\n" +
- "12. WARNING in X.java (at line 16)\n" +
- " <IOException> this(l);\n" +
- " ^^^^^^^^\n" +
- "Type safety: Unchecked invocation X(List) of the generic constructor X(List<T>) of type X\n" +
- "----------\n" +
- "13. WARNING in X.java (at line 16)\n" +
- " <IOException> this(l);\n" +
- " ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<IOException>\n" +
- "----------\n" +
- "14. WARNING in X.java (at line 19)\n" +
- " static void baz2(List l) throws IOException {\n" +
- " ^^^^\n" +
- "List is a raw type. References to generic type List<E> should be parameterized\n" +
- "----------\n" +
- "15. WARNING in X.java (at line 20)\n" +
- " new <IOException> X(l){}. <IOException> foo(l);\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: Unchecked invocation X(List) of the generic constructor X(List<T>) of type X\n" +
- "----------\n" +
- "16. WARNING in X.java (at line 20)\n" +
- " new <IOException> X(l){}. <IOException> foo(l);\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: Unchecked invocation foo(List) of the generic method foo(List<T>) of type X\n" +
- "----------\n" +
- "17. WARNING in X.java (at line 20)\n" +
- " new <IOException> X(l){}. <IOException> foo(l);\n" +
- " ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<IOException>\n" +
- "----------\n" +
- "18. WARNING in X.java (at line 20)\n" +
- " new <IOException> X(l){}. <IOException> foo(l);\n" +
- " ^\n" +
- "Type safety: The expression of type List needs unchecked conversion to conform to List<IOException>\n" +
- "----------\n"
- ));
+ "----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=202393
public void test1446() {
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 30c5d06..3f85381 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
@@ -5453,7 +5453,7 @@
"The method addUnique(Map.Entry) in the type EcoreEMap is not applicable for the arguments (Object)\n" +
"----------\n");
}
-public void testBug453253() {
+public void testBug454644() {
runNegativeTest(
new String[] {
"example/CollectionFactory.java",
@@ -5561,71 +5561,45 @@
"\n" +
"}\n"
},
- (this.complianceLevel < ClassFileConstants.JDK1_8 ?
- "----------\n" +
- "1. WARNING in example\\CollectionFactory.java (at line 42)\n" +
- " @SuppressWarnings({ \"unchecked\", \"cast\" })\n" +
- " ^^^^^^\n" +
- "Unnecessary @SuppressWarnings(\"cast\")\n" +
- "----------\n" +
- "2. WARNING in example\\CollectionFactory.java (at line 55)\n" +
- " return EnumSet.copyOf((EnumSet) collection);\n" +
- " ^^^^^^^\n" +
- "EnumSet is a raw type. References to generic type EnumSet<E> should be parameterized\n" +
- "----------\n" +
- "3. WARNING in example\\CollectionFactory.java (at line 87)\n" +
- " return EnumSet.noneOf((Class) elementType);\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: Unchecked invocation noneOf(Class) of the generic method noneOf(Class<E>) of type EnumSet\n" +
- "----------\n" +
- "4. WARNING in example\\CollectionFactory.java (at line 87)\n" +
- " return EnumSet.noneOf((Class) elementType);\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: The expression of type EnumSet needs unchecked conversion to conform to Collection<E>\n" +
- "----------\n" +
- "5. WARNING in example\\CollectionFactory.java (at line 87)\n" +
- " return EnumSet.noneOf((Class) elementType);\n" +
- " ^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: The expression of type Class needs unchecked conversion to conform to Class<E>\n" +
- "----------\n" +
- "6. WARNING in example\\CollectionFactory.java (at line 87)\n" +
- " return EnumSet.noneOf((Class) elementType);\n" +
- " ^^^^^\n" +
- "Class is a raw type. References to generic type Class<T> should be parameterized\n" +
- "----------\n" +
- "7. WARNING in example\\CollectionFactory.java (at line 94)\n" +
- " return (Collection<E>) collectionClass.newInstance();\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: Unchecked cast from capture#13-of ? to Collection<E>\n" +
- "----------\n"
- :
- "----------\n" +
- "1. ERROR in example\\CollectionFactory.java (at line 55)\n" +
- " return EnumSet.copyOf((EnumSet) collection);\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type mismatch: cannot convert from EnumSet<Enum<Enum<E>>> to Collection<E>\n" +
- "----------\n" +
- "2. WARNING in example\\CollectionFactory.java (at line 55)\n" +
- " return EnumSet.copyOf((EnumSet) collection);\n" +
- " ^^^^^^^\n" +
- "EnumSet is a raw type. References to generic type EnumSet<E> should be parameterized\n" +
- "----------\n" +
- "3. ERROR in example\\CollectionFactory.java (at line 87)\n" +
- " return EnumSet.noneOf((Class) elementType);\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type mismatch: cannot convert from EnumSet<Enum<Enum<E>>> to Collection<E>\n" +
- "----------\n" +
- "4. WARNING in example\\CollectionFactory.java (at line 87)\n" +
- " return EnumSet.noneOf((Class) elementType);\n" +
- " ^^^^^\n" +
- "Class is a raw type. References to generic type Class<T> should be parameterized\n" +
- "----------\n" +
- "5. WARNING in example\\CollectionFactory.java (at line 94)\n" +
- " return (Collection<E>) collectionClass.newInstance();\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: Unchecked cast from capture#13-of ? to Collection<E>\n" +
- "----------\n"
- ));
+ "----------\n" +
+ "1. WARNING in example\\CollectionFactory.java (at line 42)\n" +
+ " @SuppressWarnings({ \"unchecked\", \"cast\" })\n" +
+ " ^^^^^^\n" +
+ "Unnecessary @SuppressWarnings(\"cast\")\n" +
+ "----------\n" +
+ "2. WARNING in example\\CollectionFactory.java (at line 55)\n" +
+ " return EnumSet.copyOf((EnumSet) collection);\n" +
+ " ^^^^^^^\n" +
+ "EnumSet is a raw type. References to generic type EnumSet<E> should be parameterized\n" +
+ "----------\n" +
+ "3. WARNING in example\\CollectionFactory.java (at line 87)\n" +
+ " return EnumSet.noneOf((Class) elementType);\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Type safety: Unchecked invocation noneOf(Class) of the generic method noneOf(Class<E>) of type EnumSet\n" +
+ "----------\n" +
+ "4. WARNING in example\\CollectionFactory.java (at line 87)\n" +
+ " return EnumSet.noneOf((Class) elementType);\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Type safety: The expression of type EnumSet needs unchecked conversion to conform to Collection<E>\n" +
+ "----------\n" +
+ "5. WARNING in example\\CollectionFactory.java (at line 87)\n" +
+ " return EnumSet.noneOf((Class) elementType);\n" +
+ " ^^^^^^^^^^^^^^^^^^^\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ? "Type safety: The expression of type Class needs unchecked conversion to conform to Class<E>\n"
+ : "Type safety: The expression of type Class needs unchecked conversion to conform to Class<Enum<Enum<E>>>\n") +
+ "----------\n" +
+ "6. WARNING in example\\CollectionFactory.java (at line 87)\n" +
+ " return EnumSet.noneOf((Class) elementType);\n" +
+ " ^^^^^\n" +
+ "Class is a raw type. References to generic type Class<T> should be parameterized\n" +
+ "----------\n" +
+ "7. WARNING in example\\CollectionFactory.java (at line 94)\n" +
+ " return (Collection<E>) collectionClass.newInstance();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Type safety: Unchecked cast from capture#13-of ? to Collection<E>\n" +
+ "----------\n"
+ );
}
// original test case, documenting existing compiler behavior
public void testBug456459a() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
index ea993b2..42089e6 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
@@ -5492,4 +5492,168 @@
"missing cannot be resolved\n" +
"----------\n");
}
+public void testBug471280_comment0() {
+ runConformTest(
+ new String[] {
+ "Test0.java",
+ "import java.util.*;\n" +
+ "import java.util.function.*;\n" +
+ "import java.util.concurrent.*;\n" +
+ "\n" +
+ "public class Test0 {\n" +
+ " public CompletableFuture<List<String>> does_not_compile() throws Exception {\n" +
+ " CompletableFuture<List<String>> firstAsync = new CompletableFuture<>();\n" +
+ " firstAsync.complete(Collections.singletonList(\"test\"));\n" +
+ " // The following line gives error \"Type mismatch: cannot convert from CompletableFuture<Object> to CompletableFuture<List<String>>\"\n" +
+ " return transform(firstAsync, first -> Collections.singletonList(first.get(0)));\n" +
+ " }\n" +
+ "\n" +
+ " public CompletableFuture<List<String>> does_compile() throws Exception {\n" +
+ " CompletableFuture<List<String>> firstAsync = new CompletableFuture<>();\n" +
+ " firstAsync.complete(Collections.singletonList(\"test\"));\n" +
+ " return transform(firstAsync, first -> {\n" +
+ " return Collections.singletonList(first.get(0));\n" +
+ " });\n" +
+ " }\n" +
+ "\n" +
+ " public <T, R> CompletableFuture<R> transform(CompletableFuture<T> future, Function<T, R> fun) throws Exception {\n" +
+ " return future.thenApply(fun);\n" +
+ " }\n" +
+ "}\n"
+ });
+}
+public void testBug471280_comment3() {
+ runConformTest(
+ new String[] {
+ "Test3.java",
+ "import java.util.*;\n" +
+ "import java.util.stream.*;\n" +
+ "\n" +
+ "public class Test3 {\n" +
+ " public <T> T generic(T value) {\n" +
+ " return value;\n" +
+ " }\n" +
+ "\n" +
+ " public void mapExample(Map<String, String> input) {\n" +
+ " // does not compile with ejc: Type mismatch: cannot convert from Map<Object,Object> to Map<String,String>\n" +
+ " Map<String, String> mapped = input.entrySet()\n" +
+ " .stream()\n" +
+ " .collect(Collectors.toMap(e -> e.getKey(), e -> generic(e.getValue())));\n" +
+ " }\n" +
+ "}\n"
+ });
+}
+public void testBug464496() {
+ runConformTest(
+ new String[] {
+ "Value.java",
+ "public class Value<V> {\n" +
+ " private final V value;\n" +
+ " public Value(V value) {\n" +
+ " this.value = value;\n" +
+ " }\n" +
+ " public V get() {\n" +
+ " return value;\n" +
+ " }\n" +
+ " public static <V> V getValue(Value<V> value) {\n" +
+ " return value.get();\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " Value<Integer> intValue = new Value<>(42);\n" +
+ " long longPrimitive = getValue(intValue); // fails in 1.8 compiler \n" +
+ " System.out.println(longPrimitive);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "42");
+}
+public void testBug473657() {
+ runConformTest(
+ new String[] {
+ "T2.java",
+ "interface I<T> {\n" +
+ "}\n" +
+ "\n" +
+ "@SuppressWarnings({\"unchecked\", \"rawtypes\"})\n" +
+ "abstract class T1<T> implements I<T> {\n" +
+ " public I<T> t(I<? extends Number> l2) {\n" +
+ " return T2.m((I) this, (I) l2);\n" +
+ " }\n" +
+ " public I<T> t(Number l2) {\n" +
+ " return T2.m((I) this, (I) T2.t(l2));\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "public abstract class T2 {\n" +
+ " public static <T> I<T> t(T t) {\n" +
+ " return null;\n" +
+ " }\n" +
+ " public static <T extends Number> I<T> m(I<T> l1, I<? extends Number> l2) {\n" +
+ " return null;\n" +
+ " }\n" +
+ " public static <T extends Number> I<T> m(T l1, Number l2) {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ });
+}
+public void testBug478848() {
+ runNegativeTest(
+ new String[] {
+ "InferenceBug.java",
+ "import java.util.Optional;\n" +
+ "public class InferenceBug {\n" +
+ " \n" +
+ " static class Wrapper<T> {\n" +
+ " T value;\n" +
+ " public T getValue() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " }\n" +
+ " \n" +
+ " static class C1 {\n" +
+ " //an optional array of String wrappers\n" +
+ " public Optional<? extends Wrapper<String>[]> optionalArrayOfStringWrappers() {\n" +
+ " return Optional.empty();\n" +
+ " }\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " C1 c1 = new C1();\n" +
+ " for (Wrapper<String> attribute: c1.optionalArrayOfStringWrappers().get()) {\n" +
+ " // error in previous line:\n" +
+ " // Can only iterate over an array or an instance of java.lang.Iterable\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in InferenceBug.java (at line 20)\n" +
+ " for (Wrapper<String> attribute: c1.optionalArrayOfStringWrappers().get()) {\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Can only iterate over an array or an instance of java.lang.Iterable\n" +
+ "----------\n");
+}
+public void testBug479167() {
+ runConformTest(
+ new String[] {
+ "ToArray.java",
+ "import java.io.Serializable;\n" +
+ "interface ArrayFunction<E> {\n" +
+ " <S extends E> E[] apply(@SuppressWarnings(\"unchecked\") S... es);\n" +
+ "}\n" +
+ "public class ToArray<E extends Cloneable & Serializable> implements ArrayFunction<E> {\n" +
+ " public final @SafeVarargs @Override <S extends E> E[] apply(S... es) {\n" +
+ " return es;\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " ArrayFunction<String[]> toArray = new ToArray<>();\n" +
+ " String[][] array = toArray.apply(args);\n" +
+ " System.out.print(array.getClass().getName());\n" +
+ " }\n" +
+ "}\n"
+ },
+ "[[Ljava.lang.String;");
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
index ca9fc45..bd96e34 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
@@ -2841,4 +2841,170 @@
"}"
});
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=477891, [1.8] regression caused by the fix for bug 438812: order dependencies in analysis of default method inheritance
+ public void test477891_comment0() throws Exception {
+ this.runNegativeTest(
+ new String[] {
+ "D.java",
+ "interface A {\n" +
+ " public default void display() {\n" +
+ " System.out.println(\"Display from A\");\n" +
+ " }\n" +
+ "}\n" +
+ "interface B extends A {\n" +
+ " @Override\n" +
+ " public default void display() {\n" +
+ " System.out.println(\"Display from B\");\n" +
+ " }\n" +
+ "}\n" +
+ "interface C extends A {\n" +
+ " @Override\n" +
+ " public void display();\n" +
+ "}\n" +
+ "public interface D extends B, C {\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in D.java (at line 16)\n" +
+ " public interface D extends B, C {\n" +
+ " ^\n" +
+ "The default method display() inherited from B conflicts with another method inherited from C\n" +
+ "----------\n");
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=477891, [1.8] regression caused by the fix for bug 438812: order dependencies in analysis of default method inheritance
+ public void test477891_comment0_a() throws Exception {
+ this.runNegativeTest(
+ new String[] {
+ "D.java",
+ "interface A {\n" +
+ " public default void display() {\n" +
+ " System.out.println(\"Display from A\");\n" +
+ " }\n" +
+ "}\n" +
+ "interface B extends A {\n" +
+ " @Override\n" +
+ " public default void display() {\n" +
+ " System.out.println(\"Display from B\");\n" +
+ " }\n" +
+ "}\n" +
+ "interface C extends A {\n" +
+ " @Override\n" +
+ " public void display();\n" +
+ "}\n" +
+ "public interface D extends C, B {\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in D.java (at line 16)\n" +
+ " public interface D extends C, B {\n" +
+ " ^\n" +
+ "The default method display() inherited from B conflicts with another method inherited from C\n" +
+ "----------\n");
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=477891, [1.8] regression caused by the fix for bug 438812: order dependencies in analysis of default method inheritance
+ public void test477891_comment3_a() throws Exception {
+ this.runNegativeTest(
+ new String[] {
+ "Z.java",
+ "import java.util.*;\n" +
+ "interface Z<E> extends X<E>, Y<E> {\n" +
+ "}\n" +
+ "interface Y<E> extends AB<E> {\n" +
+ " @Override\n" +
+ " default Spliterator<E> spliterator() { return null; };\n" +
+ "}\n" +
+ "interface X<E> extends AB<E> {\n" +
+ " @Override\n" +
+ " Spliterator<E> spliterator();\n" +
+ "}\n" +
+ "interface AB<E> {\n" +
+ " default Spliterator<E> spliterator() { return null; }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Z.java (at line 2)\n" +
+ " interface Z<E> extends X<E>, Y<E> {\n" +
+ " ^\n" +
+ "The default method spliterator() inherited from Y<E> conflicts with another method inherited from X<E>\n" +
+ "----------\n");
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=477891, [1.8] regression caused by the fix for bug 438812: order dependencies in analysis of default method inheritance
+ public void test477891_comment3_b() throws Exception {
+ this.runNegativeTest(
+ new String[] {
+ "Z.java",
+ "import java.util.*;\n" +
+ "interface Z<E> extends Y<E>, X<E> {\n" +
+ "}\n" +
+ "interface Y<E> extends AB<E> {\n" +
+ " @Override\n" +
+ " default Spliterator<E> spliterator() { return null; };\n" +
+ "}\n" +
+ "interface X<E> extends AB<E> {\n" +
+ " @Override\n" +
+ " Spliterator<E> spliterator();\n" +
+ "}\n" +
+ "interface AB<E> {\n" +
+ " default Spliterator<E> spliterator() { return null; }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Z.java (at line 2)\n" +
+ " interface Z<E> extends Y<E>, X<E> {\n" +
+ " ^\n" +
+ "The default method spliterator() inherited from Y<E> conflicts with another method inherited from X<E>\n" +
+ "----------\n");
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=477891, [1.8] regression caused by the fix for bug 438812: order dependencies in analysis of default method inheritance
+ public void test477891_comment3_c() throws Exception {
+ this.runNegativeTest(
+ new String[] {
+ "Z.java",
+ "import java.util.*;\n" +
+ "interface Z<E> extends X<E>, Y<E> {\n" +
+ "}\n" +
+ "interface Y<E> extends AB<E> {\n" +
+ " @Override\n" +
+ " default Spliterator<E> spliterator() { return null; };\n" +
+ "}\n" +
+ "interface X<E> {\n" +
+ " Spliterator<E> spliterator();\n" +
+ "}\n" +
+ "interface AB<E> {\n" +
+ " default Spliterator<E> spliterator() { return null; }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Z.java (at line 2)\n" +
+ " interface Z<E> extends X<E>, Y<E> {\n" +
+ " ^\n" +
+ "The default method spliterator() inherited from Y<E> conflicts with another method inherited from X<E>\n" +
+ "----------\n");
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=477891, [1.8] regression caused by the fix for bug 438812: order dependencies in analysis of default method inheritance
+ public void test477891_comment3_d() throws Exception {
+ this.runNegativeTest(
+ new String[] {
+ "Z.java",
+ "import java.util.*;\n" +
+ "interface Z<E> extends Y<E>, X<E> {\n" +
+ "}\n" +
+ "interface Y<E> extends AB<E> {\n" +
+ " @Override\n" +
+ " default Spliterator<E> spliterator() { return null; };\n" +
+ "}\n" +
+ "interface X<E> {\n" +
+ " Spliterator<E> spliterator();\n" +
+ "}\n" +
+ "interface AB<E> {\n" +
+ " default Spliterator<E> spliterator() { return null; }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Z.java (at line 2)\n" +
+ " interface Z<E> extends Y<E>, X<E> {\n" +
+ " ^\n" +
+ "The default method spliterator() inherited from Y<E> conflicts with another method inherited from X<E>\n" +
+ "----------\n");
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaRegressionTest.java
index 7e1b888..ea3ac35 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaRegressionTest.java
@@ -360,6 +360,11 @@
" .forEach(entry -> test() ? bad() : returnType());\n" +
" ^^^^^^^\n" +
"The method forEach(Consumer<? super Map.Entry<Object,Object>>) in the type Iterable<Map.Entry<Object,Object>> is not applicable for the arguments ((<no type> entry) -> {})\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 6)\n" +
+ " .forEach(entry -> test() ? bad() : returnType());\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Invalid expression as statement\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=449824, [1.8] Difference in behaviour with method references and lambdas
@@ -810,6 +815,11 @@
" r.accept((l) -> (doItOnTheClass(new Object())));\n" +
" ^^^^^^\n" +
"The method accept(Test.Listener) in the type Test.Receiver is not applicable for the arguments ((<no type> l) -> {})\n" +
+ "----------\n" +
+ "2. ERROR in Test.java (at line 4)\n" +
+ " r.accept((l) -> (doItOnTheClass(new Object())));\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Invalid expression as statement\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=463526
@@ -912,6 +922,85 @@
},
"");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=477888
+// [1.8][compiler] Compiler silently produces garbage but editor shows no errors
+public void testBug477888() {
+ runNegativeTest(new String [] {
+ "Test.java",
+ "import java.io.IOException;\n" +
+ "import java.nio.file.Files;\n" +
+ "import java.nio.file.Paths;\n" +
+ "import java.util.function.Consumer;\n" +
+ "public class Test {\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " Files.lines(Paths.get(args[0])).filter(x -> {return !x.startsWith(\".\");}).forEach(printMe());\n" +
+ " }\n" +
+ " private static Consumer<String> printMe() {\n" +
+ " return x -> x.isEmpty() ? System.out.println() : System.out.println(getIndex() + \" \" + x); // error must be reported here!\n" +
+ " }\n" +
+ " static int idx;\n" +
+ "\n" +
+ " private static int getIndex() {\n" +
+ " return ++idx;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Test.java (at line 10)\n" +
+ " return x -> x.isEmpty() ? System.out.println() : System.out.println(getIndex() + \" \" + x); // error must be reported here!\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Invalid expression as statement\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=472648
+// [compiler][1.8] Lambda expression referencing method with generic type has incorrect compile errors
+public void testBug472648() {
+ runNegativeTest(new String [] {
+ "Test.java",
+ "import java.util.ArrayList;\n" +
+ "import java.util.List;\n" +
+ "import java.util.function.Consumer;\n" +
+ "public class Test {\n" +
+ " public static void main(String argv[]) {\n" +
+ " new Test();\n" +
+ " }\n" +
+ " public Test() {\n" +
+ " List<Number> numList = new ArrayList<>();\n" +
+ " numList.add(1);\n" +
+ " numList.add(1.5);\n" +
+ " numList.add(2);\n" +
+ " numList.add(2.5);\n" +
+ " forEachValueOfType(numList, Integer.class, (Integer i) -> (System.out.println(Integer.toString(i))));\n" +
+ " }\n" +
+ " private <T> void forEachValueOfType(List<?> list, Class<T> type, Consumer<T> action) {\n" +
+ " \n" +
+ " for (Object o : list) {\n" +
+ " if (type.isAssignableFrom(o.getClass())) {\n" +
+ " @SuppressWarnings(\"unchecked\")\n" +
+ " T convertedObject = (T) o;\n" +
+ " action.accept(convertedObject);\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in Test.java (at line 14)\n" +
+ " forEachValueOfType(numList, Integer.class, (Integer i) -> (System.out.println(Integer.toString(i))));\n" +
+ " ^^^^^^^^^^^^^^^^^^\n" +
+ "The method forEachValueOfType(List<?>, Class<T>, Consumer<T>) in the type Test is not applicable for the arguments (List<Number>, Class<Integer>, (Integer i) -> {})\n" +
+ "----------\n" +
+ "2. ERROR in Test.java (at line 14)\n" +
+ " forEachValueOfType(numList, Integer.class, (Integer i) -> (System.out.println(Integer.toString(i))));\n" +
+ " ^^^^^^^\n" +
+ "Incompatible type specified for lambda expression's parameter i\n" +
+ "----------\n" +
+ "3. ERROR in Test.java (at line 14)\n" +
+ " forEachValueOfType(numList, Integer.class, (Integer i) -> (System.out.println(Integer.toString(i))));\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Invalid expression as statement\n" +
+ "----------\n");
+}
public static Class testClass() {
return LambdaRegressionTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodParametersAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodParametersAttributeTest.java
index 2bb7707..dd5e3ea 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodParametersAttributeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodParametersAttributeTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2014 Jesper Steen Moeller and others.
+ * Copyright (c) 2013, 2015 Jesper Steen Moeller 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
@@ -874,6 +874,65 @@
" final synthetic this$1\n";
assertSubstring(actualOutput, expectedOutput);
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=476528
+ public void test016() throws Exception {
+ // Test that the name argument of enum valueOf shows up as mandated
+
+ this.runParameterNameTest(
+ "Foo.java",
+ "public enum Foo {\n" +
+ " BAR;\n" +
+ " public static Foo valueOf(int intParameter) {\n" +
+ " return BAR;\n" +
+ " }\n" +
+ " public static Foo valueOf2(int intParameter) {\n" +
+ " return BAR;\n" +
+ " } \n" +
+ "}\n");
+
+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+ String path = OUTPUT_DIR + File.separator + "Foo.class";
+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(path));
+ String actualOutput =
+ disassembler.disassemble(
+ classFileBytes,
+ "\n",
+ ClassFileBytesDisassembler.DETAILED);
+
+ String expectedOutput =
+ " // Stack: 1, Locals: 1\n" +
+ " public static Foo valueOf(int intParameter);\n" +
+ " 0 getstatic Foo.BAR : Foo [17]\n" +
+ " 3 areturn\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 4]\n" +
+ " Method Parameters:\n" +
+ " intParameter\n" +
+ " \n" +
+ " // Method descriptor #27 (I)LFoo;\n" +
+ " // Stack: 1, Locals: 1\n" +
+ " public static Foo valueOf2(int intParameter);\n" +
+ " 0 getstatic Foo.BAR : Foo [17]\n" +
+ " 3 areturn\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 7]\n" +
+ " Method Parameters:\n" +
+ " intParameter\n";
+ assertSubstring(actualOutput, expectedOutput);
+ // Test that synthetic method gets the right parameter names
+ expectedOutput =
+ " public static Foo valueOf(java.lang.String name);\n" +
+ " 0 ldc <Class Foo> [1]\n" +
+ " 2 aload_0 [name]\n" +
+ " 3 invokestatic java.lang.Enum.valueOf(java.lang.Class, java.lang.String) : java.lang.Enum [39]\n" +
+ " 6 checkcast Foo [1]\n" +
+ " 9 areturn\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 1]\n" +
+ " Method Parameters:\n" +
+ " mandated name\n";
+ assertSubstring(actualOutput, expectedOutput);
+ }
private void runParameterNameTest(String fileName, String body) {
Map compilerOptions = getCompilerOptions();
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 a0f73bc..1c11f10 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
@@ -14134,4 +14134,75 @@
assertEquals("Wrong contents", expectedOutput, result);
}
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=469454, The compiler generates wrong code during inheritance
+public void testBug469454() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "TestClass.java",
+ "public class TestClass {\n" +
+ " public static class A {\n" +
+ " public static A method() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " }\n" +
+ " public static class B extends A {\n" +
+ " public static B method() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(B.class.getDeclaredMethods().length);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "1");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=469454, The compiler generates wrong code during inheritance
+public void testBug469454a() throws Exception {
+ this.runNegativeTest(
+ new String[] {
+ "TestClass.java",
+ "public class TestClass {\n" +
+ " public static class A {\n" +
+ " public final A method() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " }\n" +
+ " public static class B extends A {\n" +
+ " @Override\n" +
+ " public B method() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(B.class.getDeclaredMethods().length);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in TestClass.java (at line 9)\n" +
+ " public B method() {\n" +
+ " ^^^^^^^^\n" +
+ "Cannot override the final method from TestClass.A\n" +
+ "----------\n",
+ null,
+ true,
+ null,
+ true,
+ false,
+ false);
+ String expectedOutput = " public bridge synthetic TestClass.A method();";
+
+ File f = new File(OUTPUT_DIR + File.separator + "TestClass$B.class");
+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+ String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
+ int index = result.indexOf(expectedOutput);
+ if (index != -1 || expectedOutput.length() == 0) {
+ System.out.println(Util.displayString(result, 3));
+ }
+ if (index != -1) {
+ assertEquals("Wrong contents", expectedOutput, result);
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index 5cc5e96..ef189dd 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -8286,4 +8286,226 @@
getCompilerOptions(),
"");
}
+public void testBug474239() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR);
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runConformTestWithLibs(
+ new String[] {
+ "Test.java",
+ "public class Test {\n" +
+ " static String s1 = null, s2 = null;\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " int val = (int) System.currentTimeMillis();\n" +
+ " switch (val % 2) {\n" +
+ " case 0:\n" +
+ " if (s1 != null)\n" +
+ " s2 = \"\";\n" +
+ " break;\n" +
+ " case 1:\n" +
+ " if (s1 != null) // compiler thinks s1 is never null at this point\n" +
+ " throw new RuntimeException(\"\");\n" +
+ " break;\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+}
+public void testBug474239b() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR);
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runConformTestWithLibs(
+ new String[] {
+ "Test.java",
+ "public class Test {\n" +
+ " static String s2 = null;\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " int val = (int) System.currentTimeMillis();\n" +
+ " switch (val % 2) {\n" +
+ " case 0:\n" +
+ " s2 = \"\";\n" +
+ " break;\n" +
+ " case 1:\n" +
+ " if (s2 != null)\n" +
+ " throw new RuntimeException(\"\");\n" +
+ " break;\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+}
+public void testBug472663() {
+ runConformTestWithLibs(
+ new String[] {
+ "test/Callee.java",
+ "package test;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "\n" +
+ "@NonNullByDefault\n" +
+ "public class Callee {\n" +
+ " public static String staticOtherClass(String foo) {\n" +
+ " return foo;\n" +
+ " }\n" +
+ "\n" +
+ " public String instanceOtherClass(String foo) {\n" +
+ " return foo;\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+ // and now consume Callee.class:
+ runConformTestWithLibs(
+ new String[] {
+ "test/Caller.java",
+ "package test;\n" +
+ "\n" +
+ "import java.util.function.Function;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "\n" +
+ "@NonNullByDefault\n" +
+ "public class Caller {\n" +
+ " public void foo(final Callee callee) {\n" +
+ " Function<String, String> function;\n" +
+ "\n" +
+ " // assignments with warnings (wrong):\n" +
+ " function = Callee::staticOtherClass;\n" +
+ " function = callee::instanceOtherClass;\n" +
+ "\n" +
+ " // assignments with no warnings (ok):\n" +
+ " function = foo -> Callee.staticOtherClass(foo);\n" +
+ " function = foo -> callee.instanceOtherClass(foo);\n" +
+ " function = Caller::staticSameClass;\n" +
+ " function = this::instanceSameClass;\n" +
+ " }\n" +
+ "\n" +
+ " public static String staticSameClass(String foo) {\n" +
+ " return foo;\n" +
+ " }\n" +
+ "\n" +
+ " public String instanceSameClass(String foo) {\n" +
+ " return foo;\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+}
+public void testBug467094() {
+ runConformTestWithLibs(
+ new String[] {
+ "A.java",
+ "class A {;\n"+
+ " @org.eclipse.jdt.annotation.NonNull String @org.eclipse.jdt.annotation.Nullable [] x;\n"+
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+}
+public void testBug467094_local() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "public class X {\n"+
+ " void foo(@org.eclipse.jdt.annotation.NonNull Object[] o) {\n"+
+ " o.hashCode();\n"+
+ " if (o != null) {\n"+
+ " System.out.print(o.toString());\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"
+ },
+ getCompilerOptions(),
+ "----------\n"+
+ "1. ERROR in X.java (at line 4)\n" +
+ " if (o != null) {\n" +
+ " ^\n" +
+ "Redundant null check: The variable o cannot be null at this location\n" +
+ "----------\n");
+}
+public void testBug467094_method() {
+ runConformTestWithLibs(
+ new String[] {
+ "A.java",
+ "class A {;\n"+
+ " @org.eclipse.jdt.annotation.NonNull String @org.eclipse.jdt.annotation.Nullable [] m(){\n" +
+ " return null;\n" +
+ " }\n" +
+ " int usage(){\n" +
+ " if(m() == null) return 1; \n" +
+ " return 0; \n" +
+ " }\n"+
+ "}\n"
+ }, getCompilerOptions(), "");
+}
+public void testBug440398() {
+ runConformTestWithLibs(
+ new String[] {
+ "NullTest.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "@NonNullByDefault({})\r\n" +
+ "public class NullTest {\r\n" +
+ " public static @NonNull Object[] obj = null;\r\n" +
+ " public static void main(String[] args) {\r\n" +
+ " obj = null;\r\n" +
+ " if (obj == null) { // WARNING 1\r\n" +
+ " System.out.println(\"NULL\"); // WARNING 2\r\n" +
+ " }\r\n" +
+ " }\r\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "",
+ "NULL");
+}
+public void testBug440398_comment2() {
+ runConformTestWithLibs(
+ new String[] {
+ "MyClass.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "@NonNullByDefault({DefaultLocation.FIELD})\n" +
+ "public class MyClass {\n" +
+ " private @NonNull String [] names = new @NonNull String[]{\"Alice\", \"Bob\", \"Charlie\"};\n" +
+ "\n" +
+ " public String getName(int index) {\n" +
+ " String name = names[index];\n" +
+ " return name; /* statement A */\n" +
+ " }\n" +
+ "}",
+ },
+ getCompilerOptions(),
+ "");
+}
+public void testBug440398_comment2a() {
+ runConformTestWithLibs(
+ new String[] {
+ "p/package-info.java",
+ "@org.eclipse.jdt.annotation.NonNullByDefault({org.eclipse.jdt.annotation.DefaultLocation.FIELD})\n" +
+ "package p;\n",
+ "p/MyClass.java",
+ "package p;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "public class MyClass {\n" +
+ " private @NonNull String [] names = new @NonNull String[]{\"Alice\", \"Bob\", \"Charlie\"};\n" +
+ "\n" +
+ " public String getName(int index) {\n" +
+ " String name = names[index];\n" +
+ " return name; /* statement A */\n" +
+ " }\n" +
+ "}",
+ },
+ getCompilerOptions(),
+ "");
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java
index b7b1910..9f6865c 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -3193,5 +3193,38 @@
"The type I is ambiguous\n" +
"----------\n");
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=479287
+ // erroneous compile error using static imports and generics
+ public void testBug479287() {
+ this.runConformTest(
+ new String[] {
+ "joetest/GenericsIssue.java",
+ "package joetest;\n" +
+ "import static joetest.GenericsIssueCollaborator.takesAnything;\n" +
+ "import java.util.Collection;\n" +
+ "import java.util.Collections;\n" +
+ "public class GenericsIssue {\n" +
+ " private void oddCompileError() {\n" +
+ " takesAnything(returnThings(\"works without wildcard in return value\"));\n" +
+ " GenericsIssueCollaborator.takesAnything(returnThingsWildcard(\"works without static import\"));\n" +
+ " takesAnything(returnThingsWildcard(\"doesn\'t work with static import\"));\n" +
+ " }\n" +
+ " private <T> Collection<T> returnThings(T thing) {\n" +
+ " return Collections.singleton(thing);\n" +
+ " }\n" +
+ " \n" +
+ " private <T> Collection<? extends T> returnThingsWildcard(T toReturn) {\n" +
+ " return Collections.singleton(toReturn);\n" +
+ " }\n" +
+ "}",
+ "joetest/GenericsIssueCollaborator.java",
+ "package joetest;\n" +
+ "public class GenericsIssueCollaborator {\n" +
+ " public static <T> void takesAnything(T thing) {\n" +
+ " System.out.println(\"TOOK IT: \" + thing);\n" +
+ " }\n" +
+ "}"
+ });
+ }
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
index c13eec8..a5410d3 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
@@ -5191,5 +5191,126 @@
IMethodBinding binding = lambdaExpression.resolveMethodBinding();
assertTrue("Should be a varargs", binding.isVarargs());
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=463942
+public void testBug463942_001() throws JavaModelException {
+ String contents =
+ "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" +
+ "@interface Marker {\n" +
+ " String value() default \"\";\n" +
+ "}\n" +
+ "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" +
+ "@interface Marker2 {\n" +
+ " String value() default \"22\";\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public String @Marker(\"i0\") @Marker2 [] [] @Marker(\"i1\") [] str = null;\n" +
+ "}";
+
+ this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true);
+ ASTNode node = buildAST(contents, this.workingCopy);
+ assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
+ CompilationUnit compilationUnit = (CompilationUnit) node;
+ assertProblemsSize(compilationUnit, 0);
+
+ /* public String @Marker("i0") @Marker2 [] [] @Marker("i1") [] str = null; */
+ node = getASTNode(compilationUnit, 2, 0);
+ assertTrue("Not a field declaration", node.getNodeType() == ASTNode.FIELD_DECLARATION);
+ FieldDeclaration field = (FieldDeclaration) node;
+ List fragments = field.fragments();
+ assertEquals("Incorrect no of fragments", 1, fragments.size());
+ VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0);
+ IVariableBinding variable = fragment.resolveBinding();
+ assertNotNull("Should not be null", variable);
+ ITypeBinding typeBinding = variable.getType();
+ assertNotNull("Should not be null", typeBinding);
+ IAnnotationBinding[][] dimAnnotations = typeBinding.getTypeAnnotationsOnDimensions();
+
+ assertEquals("Incorrect type annotations", 3, dimAnnotations.length);
+ IAnnotationBinding[] annotations = dimAnnotations[0];
+ assertTrue("Incorrect number of annotations", annotations.length == 2);
+ assertEquals("Incorrect type annotations", "@Marker(value = i0)", annotations[0].toString());
+ assertEquals("Incorrect type annotations", "@Marker2()", annotations[1].toString());
+ annotations = dimAnnotations[1];
+ assertTrue("Incorrect number of annotations", annotations.length == 0);
+ annotations = dimAnnotations[2];
+ assertTrue("Incorrect number of annotations", annotations.length == 1);
+ assertEquals("Incorrect type annotations", "@Marker(value = i1)", annotations[0].toString());
+
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=399792
+public void testBug470794_001() throws JavaModelException {
+ String content =
+ "public class X {\n" +
+ " Object o = (I & J) () -> {};" +
+ " public K main(Object o) {\n" +
+ " K oo = (I & J & K) o;\n" +
+ " return oo;\n" +
+ " }\n" +
+ "}\n" +
+ "interface I {\n" +
+ " public void foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " public void foo();\n" +
+ " public void bar();\n" +
+ "}\n" +
+ "interface K {\n" +
+ " public void foo();\n" +
+ " public void bar();\n" +
+ "}\n";
+
+ this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true);
+ ASTNode node = buildAST(content, this.workingCopy, true);
+ assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
+ CompilationUnit unit = (CompilationUnit) node;
+ TypeDeclaration type = (TypeDeclaration) unit.types().get(0);
+ node = (ASTNode) type.bodyDeclarations().get(0);
+ assertEquals("Not a field Declaration", ASTNode.FIELD_DECLARATION, node.getNodeType());
+ FieldDeclaration field = (FieldDeclaration) node;
+ assertEquals("Field should not be malformed", 0, (field.getFlags() & ASTNode.MALFORMED));
+
+ List fragments = field.fragments();
+ assertEquals("Incorrect no of fragments", 1, fragments.size());
+ VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0);
+ CastExpression cast = (CastExpression) fragment.getInitializer();
+ Type castType = cast.getType();
+ assertEquals("Not an intersection cast type", ASTNode.INTERSECTION_TYPE, castType.getNodeType());
+ assertTrue("Not an intersection cast type", castType.isIntersectionType());
+ assertEquals("Type should not be malformed", 0, (castType.getFlags() & ASTNode.MALFORMED));
+ ITypeBinding binding = castType.resolveBinding();
+ assertNotNull("binding is null", binding);
+ assertTrue("Not an intersection type binding", binding.isIntersectionType());
+ {
+ ITypeBinding [] intersectionBindings = binding.getTypeBounds();
+ String[] expectedTypes = new String[]{"I", "J"};
+ assertTrue("Incorrect number of intersection bindings", intersectionBindings.length == expectedTypes.length);
+ for (int i = 0, l = intersectionBindings.length; i < l; ++i) {
+ assertTrue("Unexpected Intersection Type", expectedTypes[i].equals(intersectionBindings[i].getName()));
+ }
+ }
+
+ node = (ASTNode) type.bodyDeclarations().get(1);
+ assertEquals("Not a method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType());
+ MethodDeclaration method = (MethodDeclaration) node;
+ assertEquals("Method should not be malformed", 0, (method.getFlags() & ASTNode.MALFORMED));
+
+ List statements = method.getBody().statements();
+ VariableDeclarationStatement statement = (VariableDeclarationStatement) statements.get(0);
+ fragment = (VariableDeclarationFragment) statement.fragments().get(0);
+ cast = (CastExpression) fragment.getInitializer();
+ castType = cast.getType();
+ binding = castType.resolveBinding();
+ assertNotNull("binding is null", binding);
+ assertTrue("Not an intersection type binding", binding.isIntersectionType());
+ {
+ ITypeBinding [] intersectionBindings = binding.getTypeBounds();
+ String[] expectedTypes = new String[]{"I", "J", "K"};
+ assertTrue("Incorrect number of intersection bindings", intersectionBindings.length == expectedTypes.length);
+ for (int i = 0, l = intersectionBindings.length; i < l; ++i) {
+ assertTrue("Unexpected Intersection Type", expectedTypes[i].equals(intersectionBindings[i].getName()));
+ }
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
index 4e357e8..9893639 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
@@ -11174,4 +11174,638 @@
"}";
formatSource(source);
}
+/**
+ * https://bugs.eclipse.org/474629 - [save actions][clean up] Exceptions thrown
+ */
+public void testBug474629() {
+ this.formatterPrefs.alignment_for_binary_expression |= Alignment.M_INDENT_ON_COLUMN;
+ String source = "aaaaa + bbbb";
+ formatSource(source, source, CodeFormatter.K_EXPRESSION, 0, true);
}
+/**
+ * https://bugs.eclipse.org/467618 - [formatter] Empty lines should not affect indentation of wrapped elements
+ */
+public void testBug467618() {
+ this.formatterPrefs.alignment_for_enum_constants = Alignment.M_NEXT_PER_LINE_SPLIT + Alignment.M_INDENT_ON_COLUMN + Alignment.M_FORCE;
+ String source =
+ "public enum E2 {\r\n" +
+ "\r\n" +
+ " FOOBAR,\r\n" +
+ "\r\n" +
+ " FOOBARBAZ,\r\n" +
+ "\r\n" +
+ " FOO;\r\n" +
+ "}";
+ formatSource(source,
+ "public enum E2 {\r\n" +
+ "\r\n" +
+ " FOOBAR,\r\n" +
+ "\r\n" +
+ " FOOBARBAZ,\r\n" +
+ "\r\n" +
+ " FOO;\r\n" +
+ "}"
+ );
+}
+/**
+ * @bug 474916: [formatter] Formatting GridBagLayout from Java 8 takes too long
+ * @test test that formatting finishes in reasonable time
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=474916"
+ */
+public void testBug474916() {
+ String source =
+ "/**\r\n" +
+ " * < \r\n" +
+ " * > <p style='color:red'> Test </p>\r\n" +
+ " * <a title=\"I like to 'quote' it\" \r\n" +
+ "href = 'http://www.eclipse.org'>Toast</a> */\r\n" +
+ "class A {}";
+ formatSource(source,
+ "/**\r\n" +
+ " * < >\r\n" +
+ " * <p style='color:red'>\r\n" +
+ " * Test\r\n" +
+ " * </p>\r\n" +
+ " * <a title=\"I like to 'quote' it\" href = 'http://www.eclipse.org'>Toast</a>\r\n" +
+ " */\r\n" +
+ "class A {\r\n" +
+ "}"
+ );
+}
+/**
+ * https://bugs.eclipse.org/474918 - [formatter] doesn't align fields in declarations of annotations, enums and anonymous classes
+ */
+public void testBug474918() {
+ this.formatterPrefs.align_type_members_on_columns = true;
+ String source =
+ "import java.util.function.Function;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ " private Function mapper = (Object a) -> {\r\n" +
+ " return a.toString().equals(\"test\");\r\n" +
+ " };\r\n" +
+ " String ssssssssssssssss = \"dsadaaaaaaaaaaaaaaaaaaaaaaaaa\"; //$NON-NLS-1$ // B // A\r\n" +
+ "\r\n" +
+ " int bb = 4;\r\n" +
+ "\r\n" +
+ " Object c = new Object() {\r\n" +
+ " int a = 55;\r\n" +
+ " Object cdddddddddddd = null;\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " private enum E {\r\n" +
+ " AAA, BBB;\r\n" +
+ " int a = 55;\r\n" +
+ " String sssss = \"ssssss\";\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " private @interface II {\r\n" +
+ " int aaaaaa = 1;\r\n" +
+ " String bbbbbbbbb = \"default\";\r\n" +
+ " }\r\n" +
+ "}";
+ formatSource(source,
+ "import java.util.function.Function;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ " private Function mapper = (Object a) -> {\r\n" +
+ " return a.toString().equals(\"test\");\r\n" +
+ " };\r\n" +
+ " String ssssssssssssssss = \"dsadaaaaaaaaaaaaaaaaaaaaaaaaa\"; //$NON-NLS-1$ //\r\n" +
+ " // B\r\n" +
+ " // //\r\n" +
+ " // A\r\n" +
+ "\r\n" +
+ " int bb = 4;\r\n" +
+ "\r\n" +
+ " Object c = new Object() {\r\n" +
+ " int a = 55;\r\n" +
+ " Object cdddddddddddd = null;\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " private enum E {\r\n" +
+ " AAA, BBB;\r\n" +
+ " int a = 55;\r\n" +
+ " String sssss = \"ssssss\";\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " private @interface II {\r\n" +
+ " int aaaaaa = 1;\r\n" +
+ " String bbbbbbbbb = \"default\";\r\n" +
+ " }\r\n" +
+ "}"
+ );
+}
+/**
+ * https://bugs.eclipse.org/474918 - [formatter] doesn't align fields in declarations of annotations, enums and anonymous classes
+ */
+public void testBug474918b() {
+ this.formatterPrefs.align_type_members_on_columns = true;
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
+ String source =
+ "import java.util.function.Function;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ " private Function mapper = (Object a) -> {\r\n" +
+ " return a.toString().equals(\"test\");\r\n" +
+ " };\r\n" +
+ " String ssssssssssssssss = \"dsadaaaaaaaaaaaaaaaaaaaaaaaaa\"; //$NON-NLS-1$ // B // A\r\n" +
+ "\r\n" +
+ " int bb = 4;\r\n" +
+ "\r\n" +
+ " Object c = new Object() {\r\n" +
+ " int a = 55;\r\n" +
+ " Object cdddddddddddd = null;\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " private enum E {\r\n" +
+ " AAA, BBB;\r\n" +
+ " int a = 55;\r\n" +
+ " String sssss = \"ssssss\";\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " private @interface II {\r\n" +
+ " int aaaaaa = 1;\r\n" +
+ " String bbbbbbbbb = \"default\";\r\n" +
+ " }\r\n" +
+ "}";
+ formatSource(source,
+ "import java.util.function.Function;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ " private Function mapper = (Object a) -> {\r\n" +
+ " return a.toString().equals(\"test\");\r\n" +
+ " };\r\n" +
+ " String ssssssssssssssss = \"dsadaaaaaaaaaaaaaaaaaaaaaaaaa\"; //$NON-NLS-1$ //\r\n" +
+ " // B\r\n" +
+ " // //\r\n" +
+ " // A\r\n" +
+ "\r\n" +
+ " int bb = 4;\r\n" +
+ "\r\n" +
+ " Object c = new Object() {\r\n" +
+ " int a = 55;\r\n" +
+ " Object cdddddddddddd = null;\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " private enum E {\r\n" +
+ " AAA, BBB;\r\n" +
+ " int a = 55;\r\n" +
+ " String sssss = \"ssssss\";\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " private @interface II {\r\n" +
+ " int aaaaaa = 1;\r\n" +
+ " String bbbbbbbbb = \"default\";\r\n" +
+ " }\r\n" +
+ "}"
+ );
+}
+/**
+ * https://bugs.eclipse.org/474918 - [formatter] doesn't align fields in declarations of annotations, enums and anonymous classes
+ */
+public void testBug474918c() {
+ this.formatterPrefs.align_type_members_on_columns = true;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = true;
+ String source =
+ "import java.util.function.Function;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ " private Function mapper = (Object a) -> {\r\n" +
+ " return a.toString().equals(\"test\");\r\n" +
+ " };\r\n" +
+ " String ssssssssssssssss = \"dsadaaaaaaaaaaaaaaaaaaaaaaaaa\"; //$NON-NLS-1$ // B // A\r\n" +
+ "\r\n" +
+ " int bb = 4;\r\n" +
+ "\r\n" +
+ " Object c = new Object() {\r\n" +
+ " int a = 55;\r\n" +
+ " Object cdddddddddddd = null;\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " private enum E {\r\n" +
+ " AAA, BBB;\r\n" +
+ " int a = 55;\r\n" +
+ " String sssss = \"ssssss\";\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " private @interface II {\r\n" +
+ " int aaaaaa = 1;\r\n" +
+ " String bbbbbbbbb = \"default\";\r\n" +
+ " }\r\n" +
+ "}";
+ formatSource(source,
+ "import java.util.function.Function;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ " private Function mapper = (Object a) -> {\r\n" +
+ " return a.toString().equals(\"test\");\r\n" +
+ " };\r\n" +
+ " String ssssssssssssssss = \"dsadaaaaaaaaaaaaaaaaaaaaaaaaa\"; //$NON-NLS-1$ //\r\n" +
+ " // B\r\n" +
+ " // //\r\n" +
+ " // A\r\n" +
+ "\r\n" +
+ " int bb = 4;\r\n" +
+ "\r\n" +
+ " Object c = new Object() {\r\n" +
+ " int a = 55;\r\n" +
+ " Object cdddddddddddd = null;\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " private enum E {\r\n" +
+ " AAA, BBB;\r\n" +
+ " int a = 55;\r\n" +
+ " String sssss = \"ssssss\";\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " private @interface II {\r\n" +
+ " int aaaaaa = 1;\r\n" +
+ " String bbbbbbbbb = \"default\";\r\n" +
+ " }\r\n" +
+ "}"
+ );
+}
+/**
+ * https://bugs.eclipse.org/475865 - JDT deletes code
+ */
+public void testBug475865() {
+ String source =
+ "public class Snippet {\r\n" +
+ "\r\n" +
+ " Runnable disposeRunnable = this::dispose();\r\n" +
+ "\r\n" +
+ " void dispose() {\r\n" +
+ " }\r\n" +
+ "}";
+ formatSource(source);
+}
+/**
+ * https://bugs.eclipse.org/435241 - [1.8][lambda][formatter] if/else within lambda is incorrectly formatted
+ */
+public void testBug435241() {
+ this.formatterPrefs.brace_position_for_block = DefaultCodeFormatterConstants.NEXT_LINE;
+ this.formatterPrefs.insert_new_line_before_else_in_if_statement = true;
+ String source =
+ "public class Snippet {\r\n" +
+ " public static void main(String[] args) {\r\n" +
+ " Executors.newSingleThreadExecutor().execute(() -> {\r\n" +
+ " if (true)\r\n" +
+ " {\r\n" +
+ " System.err.println(\"foo\");\r\n" +
+ " }\r\n" +
+ " else\r\n" +
+ " {\r\n" +
+ " System.err.println(\"bar\");\r\n" +
+ " }\r\n" +
+ " });\r\n" +
+ " }\r\n" +
+ "}";
+ formatSource(source);
+}
+/**
+ * https://bugs.eclipse.org/472815 - [formatter] 'Indent Empty lines' option doesn't work inside empty blocks
+ */
+public void testBug472815() {
+ this.formatterPrefs.number_of_empty_lines_to_preserve = 2;
+ String source =
+ "public class Snippet {\r\n" +
+ "\r\n" +
+ " int[] a1 = { };\r\n" +
+ " int[] a2 = {\r\n" +
+ " };\r\n" +
+ " int[] a3 = {\r\n" +
+ "\r\n" +
+ " };\r\n" +
+ " int[] a4 = {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " };\r\n" +
+ " int[] a5 = {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " void f1() { }\r\n" +
+ " void f2() {\r\n" +
+ " }\r\n" +
+ " void f3() {\r\n" +
+ "\r\n" +
+ " }\r\n" +
+ " void f4() {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " }\r\n" +
+ " void f5() {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " }\r\n" +
+ "}";
+ formatSource(source,
+ "public class Snippet {\r\n" +
+ "\r\n" +
+ " int[] a1 = {};\r\n" +
+ " int[] a2 = {};\r\n" +
+ " int[] a3 = {\r\n" +
+ "\r\n" +
+ " };\r\n" +
+ " int[] a4 = {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " };\r\n" +
+ " int[] a5 = {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " void f1() {\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " void f2() {\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " void f3() {\r\n" +
+ "\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " void f4() {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " void f5() {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " }\r\n" +
+ "}"
+ );
+}
+/**
+ * https://bugs.eclipse.org/472815 - [formatter] 'Indent Empty lines' option doesn't work inside empty blocks
+ */
+public void testBug472815b() {
+ this.formatterPrefs.number_of_empty_lines_to_preserve = 2;
+ this.formatterPrefs.indent_empty_lines = true;
+ String source =
+ "public class Snippet {\r\n" +
+ "\r\n" +
+ " int[] a1 = { };\r\n" +
+ " int[] a2 = {\r\n" +
+ " };\r\n" +
+ " int[] a3 = {\r\n" +
+ "\r\n" +
+ " };\r\n" +
+ " int[] a4 = {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " };\r\n" +
+ " int[] a5 = {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " void f1() { }\r\n" +
+ " void f2() {\r\n" +
+ " }\r\n" +
+ " void f3() {\r\n" +
+ "\r\n" +
+ " }\r\n" +
+ " void f4() {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " }\r\n" +
+ " void f5() {\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ " }\r\n" +
+ "}";
+ formatSource(source,
+ "public class Snippet {\r\n" +
+ " \r\n" +
+ " int[] a1 = {};\r\n" +
+ " int[] a2 = {};\r\n" +
+ " int[] a3 = {\r\n" +
+ " \r\n" +
+ " };\r\n" +
+ " int[] a4 = {\r\n" +
+ " \r\n" +
+ " \r\n" +
+ " };\r\n" +
+ " int[] a5 = {\r\n" +
+ " \r\n" +
+ " \r\n" +
+ " };\r\n" +
+ " \r\n" +
+ " void f1() {\r\n" +
+ " }\r\n" +
+ " \r\n" +
+ " void f2() {\r\n" +
+ " }\r\n" +
+ " \r\n" +
+ " void f3() {\r\n" +
+ " \r\n" +
+ " }\r\n" +
+ " \r\n" +
+ " void f4() {\r\n" +
+ " \r\n" +
+ " \r\n" +
+ " }\r\n" +
+ " \r\n" +
+ " void f5() {\r\n" +
+ " \r\n" +
+ " \r\n" +
+ " }\r\n" +
+ "}"
+ );
+}
+/**
+ * https://bugs.eclipse.org/472413 - [formatter] Wrap all arguments on new lines and prefer outer expressions result is inconsistent
+ */
+public void testBug472413() {
+ this.formatterPrefs.alignment_for_arguments_in_method_invocation =
+ DefaultCodeFormatterOptions.Alignment.M_ONE_PER_LINE_SPLIT
+ + DefaultCodeFormatterOptions.Alignment.M_INDENT_BY_ONE;
+ this.formatterPrefs.page_width = 80;
+ String source =
+ "class Snippet {\r\n" +
+ "\r\n" +
+ " void foo1() {\r\n" +
+ " Other.bar(\r\n" +
+ " 100,\r\n" +
+ " nestedMethod2Arg(\r\n" +
+ " nestedMethod1Arg(\r\n" +
+ " nestedMethod2Arg(nestedMethod1Arg(nestedMethod2Arg(\r\n" +
+ " nestedMethod1Arg(nestedMethod1Arg(nestedMethod1Arg(\r\n" +
+ " nested(200, 300, 400, 500, 600, 700, 800, 900)))),\r\n" +
+ " null)), null)),\r\n" +
+ " null),\r\n" +
+ " 100);\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " void foo2() {\r\n" +
+ " nestedMethodAAAA(\r\n" +
+ " nestedMethodBBBB(\r\n" +
+ " nestedMethodCCC(dddddd(200, 300, 400, 500, 600, 700, 800, 900)),\r\n" +
+ " null));\r\n" +
+ " nestedMethodAAAA(nestedMethodBBBB(\r\n" +
+ " nestedMethodCCC(dddddd(200, 300, 400, 500, 600, 700, 800, 900)),\r\n" +
+ " null));\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " void foo3() {\r\n" +
+ " nestedMethodAAAA(\r\n" +
+ " nestedMethodBBBB(\r\n" +
+ " nestedMethodCCC(dddddd(200, 300, 400, 500, 600, 700, 800, 900)),\r\n" +
+ " null),\r\n" +
+ " null);\r\n" +
+ " nestedMethodAAAA(nestedMethodBBBB(\r\n" +
+ " nestedMethodCCC(dddddd(200, 300, 400, 500, 600, 700, 800, 900)),\r\n" +
+ " null), null);\r\n" +
+ " }\r\n" +
+ "}";
+ formatSource(source,
+ "class Snippet {\r\n" +
+ "\r\n" +
+ " void foo1() {\r\n" +
+ " Other.bar(\r\n" +
+ " 100,\r\n" +
+ " nestedMethod2Arg(\r\n" +
+ " nestedMethod1Arg(\r\n" +
+ " nestedMethod2Arg(\r\n" +
+ " nestedMethod1Arg(\r\n" +
+ " nestedMethod2Arg(\r\n" +
+ " nestedMethod1Arg(\r\n" +
+ " nestedMethod1Arg(\r\n" +
+ " nestedMethod1Arg(\r\n" +
+ " nested(\r\n" +
+ " 200,\r\n" +
+ " 300,\r\n" +
+ " 400,\r\n" +
+ " 500,\r\n" +
+ " 600,\r\n" +
+ " 700,\r\n" +
+ " 800,\r\n" +
+ " 900)))),\r\n" +
+ " null)),\r\n" +
+ " null)),\r\n" +
+ " null),\r\n" +
+ " 100);\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " void foo2() {\r\n" +
+ " nestedMethodAAAA(\r\n" +
+ " nestedMethodBBBB(\r\n" +
+ " nestedMethodCCC(dddddd(200, 300, 400, 500, 600, 700, 800, 900)),\r\n" +
+ " null));\r\n" +
+ " nestedMethodAAAA(\r\n" +
+ " nestedMethodBBBB(\r\n" +
+ " nestedMethodCCC(dddddd(200, 300, 400, 500, 600, 700, 800, 900)),\r\n" +
+ " null));\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ " void foo3() {\r\n" +
+ " nestedMethodAAAA(\r\n" +
+ " nestedMethodBBBB(\r\n" +
+ " nestedMethodCCC(dddddd(200, 300, 400, 500, 600, 700, 800, 900)),\r\n" +
+ " null),\r\n" +
+ " null);\r\n" +
+ " nestedMethodAAAA(\r\n" +
+ " nestedMethodBBBB(\r\n" +
+ " nestedMethodCCC(dddddd(200, 300, 400, 500, 600, 700, 800, 900)),\r\n" +
+ " null),\r\n" +
+ " null);\r\n" +
+ " }\r\n" +
+ "}"
+ );
+}
+/**
+ * https://bugs.eclipse.org/475793 - [formatter] Incorrect whitespace after lambda block
+ */
+public void testBug475793() {
+ this.formatterPrefs.insert_new_line_in_empty_block = false;
+ String source =
+ "public class C {\r\n" +
+ " public void f() {\r\n" +
+ " Foo.bar(() -> {} , IllegalArgumentException.class);\r\n" +
+ " }\r\n" +
+ "}";
+ formatSource(source,
+ "public class C {\r\n" +
+ " public void f() {\r\n" +
+ " Foo.bar(() -> {}, IllegalArgumentException.class);\r\n" +
+ " }\r\n" +
+ "}"
+ );
+}
+/**
+ * https://bugs.eclipse.org/475746 - [formatter] insert-space rules sometimes ignored with anonymous subclass or when Annotations present
+ */
+public void testBug475746() {
+ this.formatterPrefs.insert_new_line_in_empty_block = false;
+ this.formatterPrefs.insert_space_after_opening_paren_in_method_invocation = true;
+ this.formatterPrefs.insert_space_before_closing_paren_in_method_invocation = true;
+ this.formatterPrefs.insert_space_after_opening_paren_in_method_declaration = true;
+ this.formatterPrefs.insert_space_before_closing_paren_in_method_declaration = true;
+ this.formatterPrefs.insert_space_after_opening_paren_in_constructor_declaration = true;
+ this.formatterPrefs.insert_space_before_closing_paren_in_constructor_declaration = true;
+ this.formatterPrefs.insert_space_after_opening_paren_in_annotation = true;
+ this.formatterPrefs.insert_space_before_closing_paren_in_annotation = true;
+ String source =
+ "import java.awt.*;\r\n" +
+ "\r\n" +
+ "public class MyClass {\r\n" +
+ "\r\n" +
+ " @Annotation( Arrays.asList( \"\" ))\r\n" +
+ " static Point p = new Point( x, y) {\r\n" +
+ " @Override\r\n" +
+ " public int hashCode( ) {\r\n" +
+ " return 42;\r\n" +
+ " }\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " MyClass( @Annotation( \"annotationVal\" ) String s)\r\n" +
+ " {\r\n" +
+ " Foo.bar( ( @Annotation( \"annotationVal\" ) int a) -> { } , IllegalArgumentException.class );\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ "}";
+ formatSource(source,
+ "import java.awt.*;\r\n" +
+ "\r\n" +
+ "public class MyClass {\r\n" +
+ "\r\n" +
+ " @Annotation( Arrays.asList( \"\" ) )\r\n" +
+ " static Point p = new Point( x, y ) {\r\n" +
+ " @Override\r\n" +
+ " public int hashCode() {\r\n" +
+ " return 42;\r\n" +
+ " }\r\n" +
+ " };\r\n" +
+ "\r\n" +
+ " MyClass( @Annotation( \"annotationVal\" ) String s ) {\r\n" +
+ " Foo.bar( ( @Annotation( \"annotationVal\" ) int a ) -> {}, IllegalArgumentException.class );\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ "}"
+ );
+}
+/**
+ * https://bugs.eclipse.org/477005 - [formatter] NullPointerException when first line is empty and indented
+ */
+public void testBug477005() {
+ this.formatterPrefs.indent_empty_lines = true;
+ this.formatterPrefs.blank_lines_before_package = 2;
+ String source =
+ "\r\n" +
+ "\r\n" +
+ "package test;\r\n" +
+ "\r\n" +
+ "public class MyClass {\r\n" +
+ "}";
+ formatSource(source);
+}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java
index 48dcc5a..052ab58 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java
@@ -7223,4 +7223,103 @@
" // bbb\n" +
"}");
}
+/**
+ * https://bugs.eclipse.org/475294 - [formatter] "Preserve whitespace..." problems with wrapped line comments
+ */
+public void testBug475294() {
+ this.formatterPrefs.comment_preserve_white_space_between_code_and_line_comments = true;
+ String source =
+ "public class A {\n" +
+ " void a() {\n" +
+ " System.out.println();// aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " }\n" +
+ "}";
+ formatSource(source,
+ "public class A {\n" +
+ " void a() {\n" +
+ " System.out.println();// aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " }\n" +
+ "}");
+}
+/**
+ * https://bugs.eclipse.org/475294 - [formatter] "Preserve whitespace..." problems with wrapped line comments
+ */
+public void testBug475294b() {
+ this.formatterPrefs.comment_preserve_white_space_between_code_and_line_comments = true;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = true;
+ String source =
+ "public class A {\n" +
+ " void a() {\n" +
+ " System.out.println();// aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " }\n" +
+ "}";
+ formatSource(source,
+ "public class A {\n" +
+ " void a() {\n" +
+ " System.out.println();// aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " System.out.println(); // aaaaaaa bbbbbbbbbbbbbbb ccccccccccccc\n" +
+ " // ddddddddddddddd eeeeeeeeeeeeeee\n" +
+ " }\n" +
+ "}");
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
index 07b52f5..20c9af0 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
@@ -194,6 +194,12 @@
" class Inner {\n" +
" Inner() {\n" +
" }\n" +
+ " class WW {\n" +
+ " WW() {}\n" +
+ " class WWW {\n" +
+ " WWW() {}\n" +
+ " }\n" +
+ " }\n" +
" }\n" +
"}"
};
@@ -900,6 +906,12 @@
" class Inner {\n" +
" Inner() {\n" +
" }\n" +
+ " class WW {\n" +
+ " WW() {}\n" +
+ " class WWW {\n" +
+ " WWW() {}\n" +
+ " }\n" +
+ " }\n" +
" }\n" +
"}",
type.getSource());
@@ -1046,6 +1058,32 @@
type.getSource());
attachSource(root, null, null); // detach source
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=476304
+public void testInnerClass10() throws JavaModelException {
+ IJavaProject project = this.getJavaProject("/AttachSourceTests");
+ IPackageFragmentRoot root = project.getPackageFragmentRoot(getFile("/AttachSourceTests/innerClasses.jar"));
+ attachSource(root, "/AttachSourceTests/innerClassessrc.zip", null);
+ IPackageFragment fragment = root.getPackageFragment("inner");
+
+ IType type = fragment.getClassFile("X$Inner$WW.class").getType();
+ assertSourceEquals(
+ "Unexpected source",
+ "class WW {\n" +
+ " WW() {}\n" +
+ " class WWW {\n" +
+ " WWW() {}\n" +
+ " }\n" +
+ " }",
+ type.getSource());
+ type = fragment.getClassFile("X$Inner$WW$WWW.class").getType();
+ assertSourceEquals(
+ "Unexpected source",
+ "class WWW {\n" +
+ " WWW() {}\n" +
+ " }",
+ type.getSource());
+ attachSource(root, null, null); // detach source
+}
/**
* Ensures that a source folder can be attached to a lib folder.
*/
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 b90ac98..824c5d5 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
@@ -14328,5 +14328,110 @@
if (ProjectA != null) deleteProject(ProjectA);
}
}
+/** @bug 476738
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=476738"
+ */
+public void testBug476738_001() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface I { \n" +
+ " public void query(Foo.InnerKey key);// Search result of method query(Foo.InnerKey) returns the method query(Bar.InnerKey) too \n" +
+ " public void query(Bar.InnerKey key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "class Bar {\n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "\n" +
+ "class X {\n" +
+ " public static void foo(I i, Foo.InnerKey key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " public static void bar(I i, Bar.InnerKey key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " public static I getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query";
+ int start = str.indexOf(selection);
+ int length = selection.length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern leftPattern = (MethodPattern) SearchPattern.createPattern(elements[0], REFERENCES, EXACT_RULE | ERASURE_RULE);
+ MethodPattern rightPattern = (MethodPattern) SearchPattern.createPattern(elements[0], REFERENCES, EXACT_RULE | ERASURE_RULE);
+ SearchPattern pattern = SearchPattern.createOrPattern(leftPattern, rightPattern);
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/X.java void X.foo(I, Foo.InnerKey) [query(key)] EXACT_MATCH"
+ );
+}
+/** @bug 476738
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=476738"
+ */
+public void testBug476738_002() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface I { \n" +
+ " public void query/* one */(Foo.InnerKey key);// Search result of method query(Foo.InnerKey) returns the method query(Bar.InnerKey) too \n" +
+ " public void query/* two */(Bar.InnerKey key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "class Bar {\n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "\n" +
+ "class X {\n" +
+ " public static void foo(I i, Foo.InnerKey key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " public static void bar(I i, Bar.InnerKey key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " public static I getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query";
+ String selection1 = "query/* one */";
+ String selection2 = "query/* two */";
+ int start = str.indexOf(selection1);
+ int length = selection.length();
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern leftPattern = (MethodPattern) SearchPattern.createPattern(elements[0], REFERENCES, EXACT_RULE | ERASURE_RULE);
+
+ start = str.indexOf(selection2);
+ length = selection.length();
+ elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern rightPattern = (MethodPattern) SearchPattern.createPattern(elements[0], REFERENCES, EXACT_RULE | ERASURE_RULE);
+
+ SearchPattern pattern = SearchPattern.createOrPattern(leftPattern, rightPattern);
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/X.java void X.foo(I, Foo.InnerKey) [query(key)] EXACT_MATCH\n" +
+ "src/X.java void X.bar(I, Bar.InnerKey) [query(key)] EXACT_MATCH"
+ );
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
index 5969c4c..4c0e682 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
@@ -18,10 +18,9 @@
import java.util.ArrayList;
import java.util.List;
-import junit.framework.Test;
-
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
@@ -34,8 +33,12 @@
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.core.search.TypeNameMatch;
+import org.eclipse.jdt.core.search.TypeNameMatchRequestor;
import org.eclipse.jdt.internal.core.search.matching.MethodPattern;
+import junit.framework.Test;
+
// The size of JavaSearchBugsTests.java is very big, Hence continuing here.
@SuppressWarnings({"rawtypes", "unchecked"})
public class JavaSearchBugsTests2 extends AbstractJavaSearchTests {
@@ -1907,4 +1910,55 @@
deleteProject("P");
}
}
+
+ public void testBug473921() throws Exception {
+ try {
+ IJavaProject p = this.createJavaProject(
+ "P",
+ new String[] {},
+ new String[] { "/P/lib473921.jar", "JCL17_LIB" },
+ new String[][] {{ "p/*" }, { }},
+ new String[][] {{ "**/*" }, { }},
+ null/*no project*/,
+ null/*no inclusion pattern*/,
+ null/*no exclusion pattern*/,
+ null/*no exported project*/,
+ "",
+ null/*no source outputs*/,
+ null/*no inclusion pattern*/,
+ null/*no exclusion pattern*/,
+ "1.7"
+ );
+ org.eclipse.jdt.core.tests.util.Util.createJar(
+ new String[] {
+ "p/Enclosing.java",
+ "package p;\n" +
+ "public class Enclosing { enum Nested { A, B } }\n"
+ },
+ p.getProject().getLocation().append("lib473921.jar").toOSString(),
+ "1.7");
+ refresh(p);
+
+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { p });
+ class Collector extends TypeNameMatchRequestor {
+ List<TypeNameMatch> matches = new ArrayList<>();
+ @Override
+ public void acceptTypeNameMatch(TypeNameMatch match) {
+ this.matches.add(match);
+ }
+ }
+ Collector collector = new Collector();
+ new SearchEngine().searchAllTypeNames(
+ null,
+ new char[][] { "Nested".toCharArray() },
+ scope,
+ collector,
+ IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
+ null);
+ assertEquals(1, collector.matches.size());
+ assertEquals(IAccessRule.K_ACCESSIBLE, collector.matches.get(0).getAccessibility());
+ } finally {
+ deleteProject("P");
+ }
+ }
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewrite18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewrite18Test.java
index 055fd36..ec3300a 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewrite18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewrite18Test.java
@@ -22,11 +22,14 @@
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.Annotation;
+import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
@@ -752,6 +755,48 @@
}
}
+ public void testBug474270_since_8() throws Exception {
+ String contents =
+ "package pack1;\n" +
+ "import java.util.Comparator;\n" +
+ "interface Comparator<T> {\n" +
+ " int compare(T o1, T o2);\n" +
+ " public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ " Comparator mComparator1 = null;\n" +
+ " Comparator mComparator2 = (pObj1, pObj2) -> mComparator1.compare(pObj1, pObj2);\n" +
+ " X() {mComparator1 = Comparator.naturalOrder();}\n" +
+ "}\n";
+ createFolder("/" + PROJECT + "/src/pack1");
+ createFile("/" + PROJECT + "/src/pack1/X.java", contents);
+
+ ICompilationUnit cu = getCompilationUnit("/" + PROJECT + "/src/pack1/X.java");
+ ASTParser parser = ASTParser.newParser(AST.JLS8);
+ parser.setSource(cu);
+ parser.setResolveBindings(true);
+ parser.setStatementsRecovery(true);
+ CompilationUnit astRoot = (CompilationUnit) parser.createAST(null);
+ TypeDeclaration type= (TypeDeclaration) astRoot.types().get(1);
+ MethodDeclaration [] methods = type.getMethods();
+ MethodDeclaration method = methods[0];
+ ExpressionStatement stmt = (ExpressionStatement) method.getBody().statements().get(0);
+ Assignment assignment = (Assignment) stmt.getExpression();
+ MethodInvocation invocation = (MethodInvocation) assignment.getRightHandSide();
+ ITypeBinding typeBinding = invocation.resolveTypeBinding();
+ typeBinding = typeBinding.getDeclaredMethods()[0].getParameterTypes()[0];
+ contents = "package pack2;\n" +
+ "\n" +
+ "public class A{}\n";
+ createFolder("/" + PROJECT + "/src/pack2");
+ createFile("/" + PROJECT + "/src/pack2/A.java", contents);
+ cu = getCompilationUnit("/" + PROJECT + "/src/pack2/A.java");
+ ImportRewrite rewrite = newImportsRewrite(cu, new String[0], 99, 99, true);
+ rewrite.addImport(typeBinding, astRoot.getAST());
+ }
+
private void assertEqualStringIgnoreDelim(String actual, String expected) throws IOException {
StringAsserts.assertEqualStringIgnoreDelim(actual, expected);
}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR308/testLambda/A_out.java b/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR308/testLambda/A_out.java
index ac92b6f..24670c6 100644
--- a/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR308/testLambda/A_out.java
+++ b/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR308/testLambda/A_out.java
@@ -44,7 +44,7 @@
}
}
- .howMany();
+ .howMany();
};
}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR335/testLambda/A_out.java b/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR335/testLambda/A_out.java
index 11e7d9a..1638629 100644
--- a/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR335/testLambda/A_out.java
+++ b/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR335/testLambda/A_out.java
@@ -48,7 +48,7 @@
}
}
- .howMany();
+ .howMany();
};
}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR335/testLambdaOptions/A_out.java b/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR335/testLambdaOptions/A_out.java
index 2c0e1f0..05a86b6 100644
--- a/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR335/testLambdaOptions/A_out.java
+++ b/org.eclipse.jdt.core.tests.model/workspace/FormatterJSR335/testLambdaOptions/A_out.java
@@ -51,7 +51,7 @@
}
}
- .howMany();
+ .howMany();
};
}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index 391c763..6968ee2 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -683,6 +683,14 @@
}
}
+ public void logUnavaibleAPT(String className) {
+ if ((this.tagBits & Logger.XML) != 0) {
+ this.parameters.put(Logger.MESSAGE, this.main.bind("configure.unavailableAPT", className)); //$NON-NLS-1$
+ printTag(Logger.ERROR_TAG, this.parameters, true, true);
+ }
+ this.printlnErr(this.main.bind("configure.unavailableAPT", className)); //$NON-NLS-1$
+ }
+
public void logIncorrectVMVersionForAnnotationProcessing() {
if ((this.tagBits & Logger.XML) != 0) {
this.parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
@@ -4030,17 +4038,16 @@
this.classNames = null;
}
protected void initializeAnnotationProcessorManager() {
+ String className = "org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager"; //$NON-NLS-1$
try {
- Class c = Class.forName("org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager"); //$NON-NLS-1$
+ Class c = Class.forName(className);
AbstractAnnotationProcessorManager annotationManager = (AbstractAnnotationProcessorManager) c.newInstance();
annotationManager.configure(this, this.expandedCommandLine);
annotationManager.setErr(this.err);
annotationManager.setOut(this.out);
this.batchCompiler.annotationProcessorManager = annotationManager;
- } catch (ClassNotFoundException e) {
- // ignore
- } catch (InstantiationException e) {
- // should not happen
+ } catch (ClassNotFoundException | InstantiationException e) {
+ this.logger.logUnavaibleAPT(className);
throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation();
} catch (IllegalAccessException e) {
// should not happen
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 cceb509..25f27ab 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
@@ -104,6 +104,7 @@
configure.accessRuleAfterDestinationPath = access rules cannot follow destination path entries: {0}
configure.duplicateDestinationPathEntry = duplicate destination path entry in {0} option
configure.invalidClassName = invalid class name: {0}
+configure.unavailableAPT = Unable to load annotation processing manager {0} from classpath.
configure.incorrectVMVersionforAPT = Annotation processing got disabled, since it requires a 1.6 compliant JVM
configure.incompatibleSourceForCldcTarget=Target level ''{0}'' is incompatible with source level ''{1}''. A source level ''1.3'' or lower is required
configure.incompatibleComplianceForCldcTarget=Target level ''{0}'' is incompatible with compliance level ''{1}''. A compliance level ''1.4''or lower is required
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
index 555bdcf..4be2814 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
@@ -2022,6 +2022,7 @@
prepareForHeaders();
goForHeaders();
this.diet = true; // passed this point, will not consider method bodies
+ this.dietInt = 0;
}
return RESTART;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java
index 3fe14ec..55b0453 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -149,4 +149,13 @@
public Object[] getExtraMarkerAttributeValues() {
return DefaultProblem.EMPTY_VALUES;
}
+/**
+ * {@inheritDoc}
+ * <p>Note: This implementation always returns <code>false</code>, subclasses can override.</p>
+ *
+ * @since 3.12
+ */
+public boolean isInfo() {
+ return false;
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index d30135f..e92d6bf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -302,6 +302,14 @@
boolean isWarning();
/**
+ * Checks the severity to see if the problem is an information.
+ *
+ * @return true if the information bit is set for the severity, false otherwise
+ * @since 3.12
+ */
+boolean isInfo();
+
+/**
* Set the end position of the problem (inclusive), or -1 if unknown.
* Used for shifting problem positions.
*
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 8720e8f..4b0996d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -4004,7 +4004,8 @@
if (isConstructor) { // insert String name,int ordinal
length = writeArgumentName(ConstantPool.EnumName, ClassFileConstants.AccSynthetic, length);
length = writeArgumentName(ConstantPool.EnumOrdinal, ClassFileConstants.AccSynthetic, length);
- } else if (CharOperation.equals(ConstantPool.ValueOf, binding.selector)) { // insert String name
+ } else if (binding instanceof SyntheticMethodBinding
+ && CharOperation.equals(ConstantPool.ValueOf, binding.selector)) { // insert String name
length = writeArgumentName(ConstantPool.Name, ClassFileConstants.AccMandated, length);
targetParameters = Binding.NO_PARAMETERS; // Override "unknown" synthetics below
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
index 6eb5627..4651364 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -40,6 +40,8 @@
* bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
* bug 412149 - [1.8][compiler] Emit repeated annotations into the designated container
* bug 419209 - [1.8] Repeating container annotations should be rejected in the presence of annotation it contains
+ * Till Brychcy - Contributions for
+ * bug 467094 - [1.8][null] TYPE_USE NullAnnotations of array contents are applied to field.
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -988,6 +990,9 @@
local.declaration.bits |= HasTypeAnnotations;
typeRef.bits |= HasTypeAnnotations;
local.type = mergeAnnotationsIntoType(scope, se8Annotations, se8nullBits, se8NullAnnotation, typeRef, local.type);
+ if(scope.environment().usesNullTypeAnnotations()) {
+ local.tagBits &= ~(se8nullBits);
+ }
}
break;
case Binding.FIELD:
@@ -998,6 +1003,9 @@
fieldDeclaration.bits |= HasTypeAnnotations;
fieldDeclaration.type.bits |= HasTypeAnnotations;
field.type = mergeAnnotationsIntoType(scope, se8Annotations, se8nullBits, se8NullAnnotation, fieldDeclaration.type, field.type);
+ if(scope.environment().usesNullTypeAnnotations()) {
+ field.tagBits &= ~(se8nullBits);
+ }
}
break;
case Binding.METHOD:
@@ -1009,6 +1017,9 @@
methodDecl.bits |= HasTypeAnnotations;
methodDecl.returnType.bits |= HasTypeAnnotations;
method.returnType = mergeAnnotationsIntoType(scope, se8Annotations, se8nullBits, se8NullAnnotation, methodDecl.returnType, method.returnType);
+ if(scope.environment().usesNullTypeAnnotations()) {
+ method.tagBits &= ~(se8nullBits);
+ }
}
}
break;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
index 47cfc81..3cb59b1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
@@ -42,6 +42,7 @@
}
targetContext.recordAbruptExit();
+ targetContext.expireNullCheckedFieldInfo();
this.initStateIndex =
currentScope.methodScope().recordInitializationStates(flowInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
index c42960c..df99b84 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -447,7 +447,7 @@
if (valueRequired || needRuntimeCheckcast || annotatedCast) { // Added for: 1F1W9IG: IVJCOM:WINNT - Compiler omits casting check
codeStream.generateConstant(this.constant, this.implicitConversion);
if (needRuntimeCheckcast || annotatedCast) {
- codeStream.checkcast(this.type, this.resolvedType);
+ codeStream.checkcast(this.type, this.resolvedType, pc);
}
if (!valueRequired) {
// the resolveType cannot be double or long
@@ -459,7 +459,7 @@
}
this.expression.generateCode(currentScope, codeStream, annotatedCast || valueRequired || needRuntimeCheckcast);
if (annotatedCast || (needRuntimeCheckcast && TypeBinding.notEquals(this.expression.postConversionType(currentScope), this.resolvedType.erasure()))) { // no need to issue a checkcast if already done as genericCast
- codeStream.checkcast(this.type, this.resolvedType);
+ codeStream.checkcast(this.type, this.resolvedType, pc);
}
if (valueRequired) {
codeStream.generateImplicitConversion(this.implicitConversion);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java
index a6f946d..30b7d4c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java
@@ -42,6 +42,7 @@
}
targetContext.recordAbruptExit();
+ targetContext.expireNullCheckedFieldInfo();
if (targetContext == FlowContext.NotContinuableContext) {
currentScope.problemReporter().invalidContinue(this);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
index a9b9c86..bf90d3a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
@@ -16,6 +16,8 @@
* Bug 458396 - NPE in CodeStream.invoke()
* Jesper S Moller - Contributions for
* Bug 378674 - "The method can be declared as static" is wrong
+ * Robert Roth <robert.roth.off@gmail.com> - Contributions for
+ * Bug 361039 - NPE in FieldReference.optimizedBooleanConstant
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -552,6 +554,8 @@
}
public Constant optimizedBooleanConstant() {
+ if (this.resolvedType == null)
+ return Constant.NotAConstant;
switch (this.resolvedType.id) {
case T_boolean :
case T_JavaLangBoolean :
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
index 936c293..f1145cd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
@@ -103,6 +103,8 @@
}
}
thenFlowInfo = this.thenStatement.analyseCode(currentScope, flowContext, thenFlowInfo);
+ if (!(this.thenStatement instanceof Block))
+ flowContext.expireNullCheckedFieldInfo();
}
// any null check from the condition is now expired
flowContext.expireNullCheckedFieldInfo();
@@ -131,6 +133,8 @@
}
}
elseFlowInfo = this.elseStatement.analyseCode(currentScope, flowContext, elseFlowInfo);
+ if (!(this.elseStatement instanceof Block))
+ flowContext.expireNullCheckedFieldInfo();
}
// process AutoCloseable resources closed in only one branch:
currentScope.correlateTrackingVarsIfElse(thenFlowInfo, elseFlowInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
index 877114a..a615681 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
@@ -425,6 +425,8 @@
if (this.body instanceof Expression) {
Expression expression = (Expression) this.body;
new ReturnStatement(expression, expression.sourceStart, expression.sourceEnd, true).resolve(this.scope); // :-) ;-)
+ if (expression.resolvedType == TypeBinding.VOID && !expression.statementExpression())
+ this.scope.problemReporter().invalidExpressionAsStatement(expression);
} else {
this.body.resolve(this.scope);
/* At this point, shape analysis is complete for ((see returnsExpression(...))
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index ad77677..845d662 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -66,6 +66,7 @@
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.ImplicitNullAnnotationVerifier;
import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18;
import org.eclipse.jdt.internal.compiler.lookup.IntersectionTypeBinding18;
import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
@@ -741,8 +742,14 @@
}
protected void checkNullAnnotations(BlockScope scope) {
- if (scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
+ CompilerOptions compilerOptions = scope.compilerOptions();
+ if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
if (this.expectedType == null || !NullAnnotationMatching.hasContradictions(this.expectedType)) { // otherwise assume it has been reported and we can do nothing here
+ if ((this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
+ // not interested in reporting problems against this.binding:
+ new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
+ .checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
+ }
// TODO: simplify by using this.freeParameters?
int len;
int expectedlen = this.binding.parameters.length;
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 cb1f37b..25d348d 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
@@ -171,6 +171,7 @@
currentScope.checkUnclosedCloseables(flowInfo, flowContext, this, currentScope);
// inside conditional structure respect that a finally-block may conditionally be entered directly from here
flowContext.recordAbruptExit();
+ flowContext.expireNullCheckedFieldInfo();
return FlowInfo.DEAD_END;
}
@Override
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
index ce13931..5f6e111 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
@@ -123,6 +123,7 @@
if (caseInits == FlowInfo.DEAD_END) {
fallThroughState = ESCAPING;
}
+ switchContext.expireNullCheckedFieldInfo();
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java
index aafe24b..9fa7cbf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java
@@ -116,14 +116,14 @@
@Override
public ITypeAnnotationWalker toMethodParameter(short index) {
- // don't set nextIsDefaultLocation, because signature-level nullness is handled by ImplicitNullAnnotationVerifier
+ // don't set nextIsDefaultLocation, because signature-level nullness is handled by ImplicitNullAnnotationVerifier (triggered per invocation via MessageSend.resolveType() et al)
if (this.isEmpty) return restrict(this.matches, this.pathPtr);
return super.toMethodParameter(index);
}
@Override
public ITypeAnnotationWalker toMethodReturn() {
- // don't set nextIsDefaultLocation, because signature-level nullness is handled by ImplicitNullAnnotationVerifier
+ // don't set nextIsDefaultLocation, because signature-level nullness is handled by ImplicitNullAnnotationVerifier (triggered per invocation via MessageSend.resolveType() et al)
if (this.isEmpty) return restrict(this.matches, this.pathPtr);
return super.toMethodReturn();
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index 85da064..045f8d4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -656,10 +656,10 @@
}
public void checkcast(TypeBinding typeBinding) {
- this.checkcast(null, typeBinding);
+ this.checkcast(null, typeBinding, -1);
}
-public void checkcast(TypeReference typeReference, TypeBinding typeBinding) {
+public void checkcast(TypeReference typeReference, TypeBinding typeBinding, int currentPosition) {
this.countLabels = 0;
if (this.classFileOffset + 2 >= this.bCodeStream.length) {
resizeByteArray();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java
index 66cfc2d..2be341c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2014 IBM Corporation and others.
+ * Copyright (c) 2012, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -81,7 +81,7 @@
super.newArray(typeReference, allocationExpression, arrayBinding);
}
- public void checkcast(TypeReference typeReference, TypeBinding typeBinding) {
+ public void checkcast(TypeReference typeReference, TypeBinding typeBinding, int currentPosition) {
/* We use a slightly sub-optimal generation for intersection casts by resorting to a runtime cast for every intersecting type, but in
reality this should not matter. In its intended use form such as (I & Serializable) () -> {}, no cast is emitted at all. Also note
intersection cast type references cannot nest i.e ((X & I) & J) is not valid syntax.
@@ -91,13 +91,21 @@
for (int i = typeReferences.length - 1; i >= 0; i--) { // need to emit right to left.
typeReference = typeReferences[i];
if (typeReference != null) {
- if ((typeReference.bits & ASTNode.HasTypeAnnotations) != 0)
- addAnnotationContext(typeReference, this.position, i, AnnotationTargetTypeConstants.CAST);
- super.checkcast(typeReference, typeReference.resolvedType);
+ if ((typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
+ if (!typeReference.resolvedType.isBaseType()) {
+ addAnnotationContext(typeReference, this.position, i, AnnotationTargetTypeConstants.CAST);
+ } else {
+ // for base type record it against the start position of the expression
+ addAnnotationContext(typeReference, currentPosition, i, AnnotationTargetTypeConstants.CAST);
+ }
+ }
+ if (!typeReference.resolvedType.isBaseType()) {
+ super.checkcast(typeReference, typeReference.resolvedType, currentPosition);
+ }
}
}
} else {
- super.checkcast(null, typeBinding);
+ super.checkcast(null, typeBinding, currentPosition);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
index 61d54b5..9e3b20f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
@@ -9,6 +9,7 @@
* Stephan Herrmann - initial API and implementation
* Lars Vogel <Lars.Vogel@vogella.com> - Contributions for
* Bug 473178
+ * IBM Corporation - Bug fixes
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -182,7 +183,21 @@
return copy;
}
public TypeBinding findSingleWrapperType() {
- TypeBinding wrapperBound = null;
+ if (this.instantiation != null) {
+ if (this.instantiation.isProperType(true)) {
+ switch (this.instantiation.id) {
+ case TypeIds.T_JavaLangByte:
+ case TypeIds.T_JavaLangShort:
+ case TypeIds.T_JavaLangCharacter:
+ case TypeIds.T_JavaLangInteger:
+ case TypeIds.T_JavaLangLong:
+ case TypeIds.T_JavaLangFloat:
+ case TypeIds.T_JavaLangDouble:
+ case TypeIds.T_JavaLangBoolean:
+ return this.instantiation;
+ }
+ }
+ }
if (this.subBounds != null) {
Iterator<TypeBound> it = this.subBounds.iterator();
while(it.hasNext()) {
@@ -197,9 +212,7 @@
case TypeIds.T_JavaLangFloat:
case TypeIds.T_JavaLangDouble:
case TypeIds.T_JavaLangBoolean:
- if (wrapperBound != null)
- return null;
- wrapperBound = boundType;
+ return boundType;
}
}
}
@@ -218,14 +231,12 @@
case TypeIds.T_JavaLangFloat:
case TypeIds.T_JavaLangDouble:
case TypeIds.T_JavaLangBoolean:
- if (wrapperBound != null)
- return null;
- wrapperBound = boundType;
+ return boundType;
}
}
}
}
- return wrapperBound;
+ return null;
}
/**
* Not per JLS: enhance the given type bounds using the nullHints, if useful.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
index 9b4b32e..c51a617 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
@@ -110,11 +110,7 @@
return ConstraintTypeFormula.create(exprType, this.right, COMPATIBLE, this.isSoft);
}
if (innerCtx.stepCompleted >= InferenceContext18.APPLICABILITY_INFERRED) {
- inferenceContext.currentBounds.addBounds(innerCtx.b2, inferenceContext.environment);
- inferenceContext.inferenceVariables = innerCtx.inferenceVariables;
- inferenceContext.inferenceKind = innerCtx.inferenceKind;
- innerCtx.outerContext = inferenceContext;
- inferenceContext.usesUncheckedConversion = innerCtx.usesUncheckedConversion;
+ inferenceContext.integrateInnerInferenceB2(innerCtx);
} else {
return FALSE; // should not reach here.
}
@@ -362,11 +358,7 @@
// spec says erasure, but we don't really have compatibility rules for erasure, use raw type instead:
TypeBinding erasure = inferenceContext.environment.convertToRawType(returnType, false);
ConstraintTypeFormula newConstraint = ConstraintTypeFormula.create(erasure, targetType, COMPATIBLE);
- if (!inferenceContext.reduceAndIncorporate(newConstraint))
- return false;
- // continuing at true is not spec'd but needed for javac-compatibility,
- // see org.eclipse.jdt.core.tests.compiler.regression.GenericsRegressionTest_1_8.testBug428198()
- // and org.eclipse.jdt.core.tests.compiler.regression.GenericsRegressionTest_1_8.testBug428264()
+ return inferenceContext.reduceAndIncorporate(newConstraint);
}
TypeBinding rTheta = inferenceContext.substitute(returnType);
ParameterizedTypeBinding parameterizedType = InferenceContext18.parameterizedWithWildcard(rTheta);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
index 1d3415d..7c6d065 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
@@ -15,6 +15,8 @@
* Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
* Bug 458396 - NPE in CodeStream.invoke()
* Bug 446217 - [null] @NonNullByDefault in package-info.java causes bogus "null type safety" warning
+ * Till Brychcy - Contribution for
+ * bug 467094 - [1.8][null] TYPE_USE NullAnnotations of array contents are applied to field.
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -245,21 +247,23 @@
}
public void fillInDefaultNonNullness(FieldDeclaration sourceField, Scope scope) {
+ if (this.type == null || this.type.isBaseType())
+ return;
LookupEnvironment environment = scope.environment();
- if (this.type == null)
- return;
- if (environment.usesNullTypeAnnotations() && !this.type.acceptsNonNullDefault())
- return;
- if ( !this.type.isBaseType()
- && (this.tagBits & TagBits.AnnotationNullMASK) == 0 // declaration annotation?
- && (this.type.tagBits & TagBits.AnnotationNullMASK) == 0) // type annotation? (java.lang.@Nullable String)
- {
- if (environment.usesNullTypeAnnotations())
+ if (environment.usesNullTypeAnnotations()) {
+ if (!this.type.acceptsNonNullDefault())
+ return;
+ if ( (this.type.tagBits & TagBits.AnnotationNullMASK) == 0) {
this.type = environment.createAnnotatedType(this.type, new AnnotationBinding[]{environment.getNonNullAnnotation()});
- else
+ } else if ((this.type.tagBits & TagBits.AnnotationNonNull) != 0) {
+ scope.problemReporter().nullAnnotationIsRedundant(sourceField);
+ }
+ } else {
+ if ( (this.tagBits & TagBits.AnnotationNullMASK) == 0 ) {
this.tagBits |= TagBits.AnnotationNonNull;
- } else if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
- scope.problemReporter().nullAnnotationIsRedundant(sourceField);
+ } else if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
+ scope.problemReporter().nullAnnotationIsRedundant(sourceField);
+ }
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
index 2da3f5c..ea1e31c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
@@ -128,6 +128,7 @@
/** The inference variables for which as solution is sought. */
InferenceVariable[] inferenceVariables;
+ int nextVarId;
/** Constraints that have not yet been reduced and incorporated. */
ConstraintFormula[] initialConstraints;
@@ -179,7 +180,7 @@
if (i >= len)
System.arraycopy(interned, 0, outermostContext.internedVariables = new InferenceVariable[len+10], 0, len);
}
- return outermostContext.internedVariables[i] = new InferenceVariable(typeParameter, rank, i, site, this.environment, this.object);
+ return outermostContext.internedVariables[i] = new InferenceVariable(typeParameter, rank, this.nextVarId++, site, this.environment, this.object);
}
public static final int CHECK_UNKNOWN = 0;
@@ -1399,6 +1400,16 @@
return record;
}
+ public void integrateInnerInferenceB2(InferenceContext18 innerCtx) {
+ this.currentBounds.addBounds(innerCtx.b2, this.environment);
+ this.inferenceVariables = innerCtx.inferenceVariables;
+ this.inferenceKind = innerCtx.inferenceKind;
+ innerCtx.outerContext = this;
+ this.usesUncheckedConversion = innerCtx.usesUncheckedConversion;
+ for (InferenceVariable variable : this.inferenceVariables)
+ variable.updateSourceName(this.nextVarId++);
+ }
+
public void resumeSuspendedInference(SuspendedInferenceRecord record) {
// merge inference variables:
if (this.inferenceVariables == null) { // no new ones, assume we aborted prematurely
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java
index 060e4cf..b999b85 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java
@@ -23,11 +23,13 @@
TypeBinding typeParameter;
long nullHints; // one of TagBits.{AnnotationNonNull,AnnotationNullable} may steer inference into inferring nullness as well; set both bits to request avoidance.
private InferenceVariable prototype;
+ int varId; // this is used for constructing a source name like T#0. NB: varId and sourceName are mutable, to be updated when two InferenceContext18 are integrated.
public InferenceVariable(TypeBinding typeParameter, int parameterRank, int iVarId, InvocationSite site, LookupEnvironment environment, ReferenceBinding object) {
this(typeParameter, parameterRank, site,
CharOperation.concat(typeParameter.shortReadableName(), Integer.toString(iVarId).toCharArray(), '#'),
environment, object);
+ this.varId = iVarId;
}
private InferenceVariable(TypeBinding typeParameter, int parameterRank, InvocationSite site, char[] sourceName, LookupEnvironment environment, ReferenceBinding object) {
super(sourceName, null/*declaringElement*/, parameterRank, environment);
@@ -47,12 +49,21 @@
this.superclass = object;
this.prototype = this;
}
+ void updateSourceName(int newId) {
+ int hashPos = CharOperation.indexOf('#', this.sourceName);
+ this.varId = newId;
+ this.sourceName = CharOperation.concat(
+ CharOperation.subarray(this.sourceName, 0, hashPos),
+ Integer.toString(this.varId).toCharArray(),
+ '#');
+ }
@Override
public TypeBinding clone(TypeBinding enclosingType) {
InferenceVariable clone = new InferenceVariable(this.typeParameter, this.rank, this.site, this.sourceName, this.environment, this.superclass);
clone.tagBits = this.tagBits;
clone.nullHints = this.nullHints;
+ clone.varId = this.varId;
clone.prototype = this;
return clone;
}
@@ -119,16 +130,19 @@
}
public int hashCode() {
- if (this.sourceName != null)
- return this.sourceName.hashCode();
- return super.hashCode();
+ int code = this.typeParameter.hashCode() + 17 * this.rank;
+ if (this.site != null)
+ return 31 * code + this.site.hashCode();
+ else
+ return code;
}
public boolean equals(Object obj) {
if (!(obj instanceof InferenceVariable))
return false;
- if (this.sourceName != null)
- return this.sourceName.equals(((InferenceVariable)obj).sourceName);
- return super.equals(obj);
+ InferenceVariable other = (InferenceVariable) obj;
+ return this.rank == other.rank
+ && this.site == other.site
+ && TypeBinding.equalsEquals(this.typeParameter, other.typeParameter);
}
public TypeBinding erasure() {
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 3b5083d..8882848 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
@@ -810,6 +810,11 @@
}
public ParameterizedGenericMethodBinding createParameterizedGenericMethod(MethodBinding genericMethod, TypeBinding[] typeArguments) {
+ return createParameterizedGenericMethod(genericMethod, typeArguments, false, false);
+}
+public ParameterizedGenericMethodBinding createParameterizedGenericMethod(MethodBinding genericMethod, TypeBinding[] typeArguments,
+ boolean inferredWithUncheckedConversion, boolean hasReturnProblem)
+{
// cached info is array of already created parameterized types for this type
ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[])this.uniqueParameterizedGenericMethodBindings.get(genericMethod);
int argLength = typeArguments == null ? 0: typeArguments.length;
@@ -828,6 +833,12 @@
for (int j = 0; j < cachedArgLength; j++){
if (typeArguments[j] != cachedArguments[j]) continue nextCachedMethod; //$IDENTITY-COMPARISON$
}
+ if (inferredWithUncheckedConversion) { // JSL 18.5.2: "If unchecked conversion was necessary..."
+ // don't tolerate remaining parameterized types / type variables, should have been eliminated by erasure:
+ if (cachedMethod.returnType.isParameterizedType() || cachedMethod.returnType.isTypeVariable()) continue;
+ for (TypeBinding exc : cachedMethod.thrownExceptions)
+ if (exc.isParameterizedType() || exc.isTypeVariable()) continue nextCachedMethod;
+ }
// all arguments match, reuse current
return cachedMethod;
}
@@ -843,7 +854,8 @@
this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo);
}
// add new binding
- ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(genericMethod, typeArguments, this);
+ ParameterizedGenericMethodBinding parameterizedGenericMethod =
+ new ParameterizedGenericMethodBinding(genericMethod, typeArguments, this, inferredWithUncheckedConversion, hasReturnProblem);
cachedInfo[index] = parameterizedGenericMethod;
return parameterizedGenericMethod;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
index 1789afe..1f0446b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -188,7 +188,8 @@
}
}
}
- checkForBridgeMethod(currentMethod, inheritedMethod, allInheritedMethods);
+ if (!inheritedMethod.isStatic() && !inheritedMethod.isFinal())
+ checkForBridgeMethod(currentMethod, inheritedMethod, allInheritedMethods);
}
}
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 905fdf8..2fa02c9 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -338,7 +338,7 @@
} else {
if (concreteMethod != null && concreteMethod.isDefaultMethod()) {
if (this.environment.globalOptions.complianceLevel >= ClassFileConstants.JDK1_8) {
- if (!checkInheritedDefaultMethods(methods, length))
+ if (!checkInheritedDefaultMethods(methods, isOverridden, length))
return;
}
}
@@ -346,21 +346,21 @@
super.checkInheritedMethods(methods, length, isOverridden, isInherited);
}
}
-boolean checkInheritedDefaultMethods(MethodBinding[] methods, int length) {
- // JLS8 9.4.1 (interface) and 8.4.8.4 (class):
+boolean checkInheritedDefaultMethods(MethodBinding[] methods, boolean[] isOverridden, int length) {
+ // JLS8 9.4.1.3 (interface) and 8.4.8.4 (class):
// default method clashes with other inherited method which is override-equivalent
if (length < 2) return true;
boolean ok = true;
findDefaultMethod: for (int i=0; i<length; i++) {
- if (methods[i].isDefaultMethod()) {
+ if (methods[i].isDefaultMethod() && !isOverridden[i]) {
findEquivalent: for (int j=0; j<length; j++) {
- if (j == i) continue findEquivalent;
+ if (j == i || isOverridden[j]) continue findEquivalent;
if (isMethodSubsignature(methods[i], methods[j])) {
if (!doesMethodOverride(methods[i], methods[j]) && !doesMethodOverride(methods[j], methods[i])) {
problemReporter().inheritedDefaultMethodConflictsWithOtherInherited(this.type, methods[i], methods[j]);
ok = false;
+ continue findDefaultMethod;
}
- continue findDefaultMethod;
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
index 6c22117..f7ab036 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
@@ -263,7 +263,7 @@
// assemble the solution etc:
TypeBinding[] solutions = infCtx18.getSolutions(typeVariables, invocationSite, result);
if (solutions != null) {
- methodSubstitute = scope.environment().createParameterizedGenericMethod(originalMethod, solutions);
+ methodSubstitute = scope.environment().createParameterizedGenericMethod(originalMethod, solutions, infCtx18.usesUncheckedConversion, hasReturnProblem);
if (invocationSite instanceof Invocation)
infCtx18.forwardResults(result, (Invocation) invocationSite, methodSubstitute, expectedType);
if (hasReturnProblem) { // illegally working from the provisional result?
@@ -529,7 +529,7 @@
/**
* Create method of parameterized type, substituting original parameters with type arguments.
*/
- public ParameterizedGenericMethodBinding(MethodBinding originalMethod, TypeBinding[] typeArguments, LookupEnvironment environment) {
+ public ParameterizedGenericMethodBinding(MethodBinding originalMethod, TypeBinding[] typeArguments, LookupEnvironment environment, boolean inferredWithUncheckConversion, boolean hasReturnProblem) {
this.environment = environment;
this.modifiers = originalMethod.modifiers;
this.selector = originalMethod.selector;
@@ -541,8 +541,16 @@
this.originalMethod = originalMethod;
this.parameters = Scope.substitute(this, originalMethod.parameters);
// error case where exception type variable would have been substituted by a non-reference type (207573)
- this.returnType = Scope.substitute(this, originalMethod.returnType);
- this.thrownExceptions = Scope.substitute(this, originalMethod.thrownExceptions);
+ if (inferredWithUncheckConversion) { // JSL 18.5.2: "If unchecked conversion was necessary..."
+ this.returnType = getErasure18_5_2(originalMethod.returnType, environment, hasReturnProblem); // propagate simulation of Bug JDK_8026527
+ this.thrownExceptions = new ReferenceBinding[originalMethod.thrownExceptions.length];
+ for (int i = 0; i < originalMethod.thrownExceptions.length; i++) {
+ this.thrownExceptions[i] = (ReferenceBinding) getErasure18_5_2(originalMethod.thrownExceptions[i], environment, false); // no excuse for exceptions
+ }
+ } else {
+ this.returnType = Scope.substitute(this, originalMethod.returnType);
+ this.thrownExceptions = Scope.substitute(this, originalMethod.thrownExceptions);
+ }
if (this.thrownExceptions == null) this.thrownExceptions = Binding.NO_EXCEPTIONS;
checkMissingType: {
if ((this.tagBits & TagBits.HasMissingType) != 0)
@@ -582,6 +590,16 @@
}
}
+ TypeBinding getErasure18_5_2(TypeBinding type, LookupEnvironment env, boolean substitute) {
+ // opportunistic interpretation of (JLS 18.5.2):
+ // "If unchecked conversion was necessary ..., then ...
+ // the return type and thrown types of the invocation type of m are given by
+ // the erasure of the return type and thrown types of m's type."
+ if (substitute)
+ type = Scope.substitute(this, type);
+ return env.convertToRawType(type, true);
+ }
+
/*
* parameterizedDeclaringUniqueKey dot selector originalMethodGenericSignature percent typeArguments
* p.X<U> { <T> void bar(T t, U u) { new X<String>().bar(this, "") } } --> Lp/X<Ljava/lang/String;>;.bar<T:Ljava/lang/Object;>(TT;Ljava/lang/String;)V%<Lp/X;>
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyParameterizedGenericMethodBinding.java
index 3a5f6c4..29ed92b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyParameterizedGenericMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyParameterizedGenericMethodBinding.java
@@ -14,7 +14,7 @@
private ParameterizedGenericMethodBinding wrappedBinding;
public PolyParameterizedGenericMethodBinding(ParameterizedGenericMethodBinding applicableMethod) {
- super(applicableMethod.originalMethod, applicableMethod.typeArguments, applicableMethod.environment);
+ super(applicableMethod.originalMethod, applicableMethod.typeArguments, applicableMethod.environment, false, false);
this.wrappedBinding = applicableMethod;
}
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 582cb19..33ded17 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
@@ -757,8 +757,13 @@
} else if (!method.isOverriding() || !isOverriddenMethodGeneric(method)) {
return new ProblemMethodBinding(method, method.selector, genericTypeArguments, ProblemReasons.TypeParameterArityMismatch);
}
- } else if (typeVariables == Binding.NO_TYPE_VARIABLES && method instanceof PolyParameterizedGenericMethodBinding) {
- return method;
+ } else if (typeVariables == Binding.NO_TYPE_VARIABLES && method instanceof ParameterizedGenericMethodBinding) {
+ if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 && invocationSite instanceof Invocation) {
+ Invocation invocation = (Invocation) invocationSite;
+ InferenceContext18 infCtx = invocation.getInferenceContext((ParameterizedGenericMethodBinding) method);
+ if (infCtx != null)
+ return method; // inference is responsible, no need to recheck.
+ }
}
if (tiebreakingVarargsMethods) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
index 32b1b07..55374ca 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
@@ -244,13 +244,11 @@
}
public int boundsCount() {
- if (this.firstBound == null) {
+ if (this.firstBound == null)
return 0;
- } else if (TypeBinding.equalsEquals(this.firstBound, this.superclass)) {
- return this.superInterfaces.length + 1;
- } else {
- return this.superInterfaces.length;
- }
+ if (this.firstBound.isInterface())
+ return this.superInterfaces.length; // only interface bounds
+ return this.superInterfaces.length + 1; // class or array type isn't contained in superInterfaces
}
/**
@@ -421,10 +419,11 @@
if (n == 0)
return NO_TYPE_BOUNDS;
TypeBound[] bounds = new TypeBound[n];
- bounds[0] = TypeBound.createBoundOrDependency(theta, this.firstBound, variable);
- int ifcOffset = TypeBinding.equalsEquals(this.firstBound, this.superclass) ? -1 : 0;
- for (int i = 1; i < n; i++)
- bounds[i] = TypeBound.createBoundOrDependency(theta, this.superInterfaces[i+ifcOffset], variable);
+ int idx = 0;
+ if (!this.firstBound.isInterface())
+ bounds[idx++] = TypeBound.createBoundOrDependency(theta, this.firstBound, variable);
+ for (int i = 0; i < this.superInterfaces.length; i++)
+ bounds[idx++] = TypeBound.createBoundOrDependency(theta, this.superInterfaces[i], variable);
return bounds;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index 1893d20..f7bac96 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -9727,11 +9727,14 @@
CompilationUnitDeclaration parsedUnit;
boolean old = this.diet;
+ int oldInt = this.dietInt;
try {
+ this.dietInt = 0;
this.diet = true;
parsedUnit = parse(sourceUnit, compilationResult);
} finally {
this.diet = old;
+ this.dietInt = oldInt;
}
return parsedUnit;
}
@@ -11498,6 +11501,7 @@
}
public ASTNode[] parseClassBodyDeclarations(char[] source, int offset, int length, CompilationUnitDeclaration unit) {
boolean oldDiet = this.diet;
+ int oldInt = this.dietInt;
boolean oldTolerateDefaultClassMethods = this.tolerateDefaultClassMethods;
/* automaton initialization */
initialize();
@@ -11525,12 +11529,14 @@
/* run automaton */
try {
this.diet = true;
+ this.dietInt = 0;
this.tolerateDefaultClassMethods = this.parsingJava8Plus;
parse();
} catch (AbortCompilation ex) {
this.lastAct = ERROR_ACTION;
} finally {
this.diet = oldDiet;
+ this.dietInt = oldInt;
this.tolerateDefaultClassMethods = oldTolerateDefaultClassMethods;
}
@@ -12339,6 +12345,7 @@
if (this.referenceContext instanceof CompilationUnitDeclaration){
goForHeaders();
this.diet = true; // passed this point, will not consider method bodies
+ this.dietInt = 0;
return RESTART;
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationBinding.java
index 0e8f6db..5475581 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2011 BEA Systems, Inc.
+ * Copyright (c) 2005, 2015 BEA Systems, Inc.
* 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
@@ -28,6 +28,7 @@
*/
class AnnotationBinding implements IAnnotationBinding {
static final AnnotationBinding[] NoAnnotations = new AnnotationBinding[0];
+ static final AnnotationBinding[][] NoAnnotationsOnDimensions = new AnnotationBinding[0][];
private org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding binding;
private BindingResolver bindingResolver;
private String key;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
index 4786097..c3f8699 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
@@ -562,6 +562,23 @@
public IAnnotationBinding[] getTypeAnnotations();
/**
+ * Returns the type use annotations on dimensions, or the empty array if there
+ * are no annotations on dimensions.
+ *
+ * <p>
+ * Since JLS8, (Section 9.7.4) type annotations can appear at array dimensions. These annotations
+ * are returned in a 2-d array with each row containing annotations for that dimension. If only some
+ * of the dimensions have type annotations, the rows corresponding to the dimensions without
+ * annotations will have an empty single dimensional array.
+ * </p>
+ *
+ * @return type annotations specified on the dimensions of this type reference, or an empty array if
+ * either there is no dimension or no type use annotation is found on the dimensions.
+ * @since 3.12
+ */
+ public IAnnotationBinding[][] getTypeAnnotationsOnDimensions();
+
+ /**
* Returns the type arguments of this generic type instance, or the
* empty list for other type bindings.
* <p>
@@ -584,8 +601,8 @@
public ITypeBinding[] getTypeArguments();
/**
- * Returns the upper type bounds of this type variable, wildcard, or capture. If the
- * variable, wildcard, or capture had no explicit bound, then it returns an empty list.
+ * Returns the upper type bounds of this type variable, wildcard, capture, or intersectionType.
+ * If the variable, wildcard, or capture had no explicit bound, then it returns an empty list.
* <p>
* Note that per construction, it can only contain one class or array type,
* at most, and then it is located in first position.
@@ -595,11 +612,12 @@
* binding, e.g. <code>capture-of ? extends Object[]</code>
* </p>
*
- * @return the list of upper bounds for this type variable, wildcard, or capture,
+ * @return the list of upper bounds for this type variable, wildcard, capture, or intersection type
* or otherwise the empty list
* @see #isTypeVariable()
* @see #isWildcardType()
* @see #isCapture()
+ * @see #isIntersectionType()
* @since 3.1
*/
public ITypeBinding[] getTypeBounds();
@@ -819,6 +837,28 @@
public boolean isInterface();
/**
+ * Returns whether this type binding represents an intersection binding.
+ * <p>
+ * Intersection types can be derived from type parameter bounds and cast
+ * expressions; they also arise in the processes of capture conversion
+ * and least upper bound computation as specified in section 4.9 of
+ * <em>The Java Language Specification, Java SE 8 Edition</em> (JLS8).
+ * </p>
+ * <p>
+ * All the types in the intersection type can be accessed using
+ * {@link #getTypeBounds()}. Wildcard types with more than one
+ * bound will also be reported as intersection type. To check whether this
+ * is a wildcard type, use {@link #isWildcardType()}.
+ * </p>
+ * @return <code>true</code> if this type binding is an intersecting type,
+ * and <code>false</code> otherwise
+ * @see #getTypeBounds()
+ * @see ITypeBinding#isWildcardType()
+ * @since 3.12
+ */
+ public boolean isIntersectionType();
+
+ /**
* Returns whether this type binding represents a local class.
* <p>
* A local class is any nested class or enum type not declared as a member
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
index 23cba7b..f4a55b1 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
@@ -39,16 +39,16 @@
private static final ITypeBinding[] NO_TYPE_BINDINGS = new ITypeBinding[0];
protected org.eclipse.jdt.internal.compiler.lookup.MethodBinding binding;
protected BindingResolver resolver;
- private ITypeBinding[] parameterTypes;
- private ITypeBinding[] exceptionTypes;
- private String name;
- private ITypeBinding declaringClass;
- private ITypeBinding returnType;
- private String key;
- private ITypeBinding[] typeParameters;
- private ITypeBinding[] typeArguments;
- private IAnnotationBinding[] annotations;
- private IAnnotationBinding[][] parameterAnnotations;
+ private volatile ITypeBinding[] parameterTypes;
+ private volatile ITypeBinding[] exceptionTypes;
+ private volatile String name;
+ private volatile ITypeBinding declaringClass;
+ private volatile ITypeBinding returnType;
+ private volatile String key;
+ private volatile ITypeBinding[] typeParameters;
+ private volatile ITypeBinding[] typeArguments;
+ private volatile IAnnotationBinding[] annotations;
+ private volatile IAnnotationBinding[][] parameterAnnotations;
MethodBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.MethodBinding binding) {
this.resolver = resolver;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
index c126584..97bc4e5 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
@@ -467,6 +467,13 @@
}
/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.dom.ITypeBinding#isIntersectionType18()
+ */
+ public boolean isIntersectionType() {
+ return false;
+ }
+
+ /* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ITypeBinding#isLocal()
*/
public boolean isLocal() {
@@ -728,4 +735,9 @@
public IAnnotationBinding[] getTypeAnnotations() {
return AnnotationBinding.NoAnnotations;
}
+
+ @Override
+ public IAnnotationBinding[][] getTypeAnnotationsOnDimensions() {
+ return AnnotationBinding.NoAnnotationsOnDimensions;
+ }
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index 1fdc509..e163e5f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -14,6 +14,8 @@
package org.eclipse.jdt.core.dom;
+import java.util.ArrayList;
+import java.util.List;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CharOperation;
@@ -64,6 +66,7 @@
private IVariableBinding[] fields;
private IAnnotationBinding[] annotations;
private IAnnotationBinding[] typeAnnotations;
+ private IAnnotationBinding[][] typeAnnotationsOnDimensions;
private IMethodBinding[] methods;
private ITypeBinding[] members;
private ITypeBinding[] interfaces;
@@ -144,6 +147,34 @@
return AnnotationBinding.NoAnnotations;
}
+ private IAnnotationBinding[][] resolveAnnotationBindingsOnDimensions(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] internalAnnotations) {
+ int length = internalAnnotations == null ? 0 : internalAnnotations.length;
+ if (length != 0) {
+ IAnnotationBinding[][] dimAnnotations = new IAnnotationBinding[length][];
+ int row = 0;
+ List <IAnnotationBinding> tmpList = new ArrayList<>();
+ for (int i = 0; i < length; i++) {
+ org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalAnnotation = internalAnnotations[i];
+ if (internalAnnotation == null) {
+ if (tmpList.size() > 0) {
+ dimAnnotations[row] = tmpList.toArray(new AnnotationBinding[0]);
+ tmpList.clear();
+ } else {
+ dimAnnotations[row] = AnnotationBinding.NoAnnotations;
+ }
+ ++row;
+ }
+ IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(internalAnnotation);
+ if (annotationInstance == null) {
+ continue;
+ }
+ tmpList.add(annotationInstance);
+ }
+ System.arraycopy(dimAnnotations, 0, (dimAnnotations = new IAnnotationBinding[row][]), 0, row);
+ return dimAnnotations;
+ }
+ return AnnotationBinding.NoAnnotationsOnDimensions;
+ }
/*
* @see ITypeBinding#getBinaryName()
* @since 3.0
@@ -554,6 +585,19 @@
return this.interfaces = NO_TYPE_BINDINGS;
}
+ private ITypeBinding[] getIntersectingTypes() {
+ ITypeBinding[] intersectionBindings = TypeBinding.NO_TYPE_BINDINGS;
+ if (this.binding instanceof IntersectionTypeBinding18) {
+ ReferenceBinding[] intersectingTypes = this.binding.getIntersectingTypes();
+ int l = intersectingTypes.length;
+ intersectionBindings = new ITypeBinding[l];
+ for (int i = 0; i < l; ++i) {
+ intersectionBindings[i] = this.resolver.getTypeBinding(intersectingTypes[i]);
+ }
+ }
+ return intersectionBindings;
+ }
+
public IJavaElement getJavaElement() {
JavaElement element = getUnresolvedJavaElement();
if (element != null)
@@ -926,6 +970,8 @@
} else if (this.binding instanceof WildcardBinding) {
WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
typeVariableBinding = wildcardBinding.typeVariable();
+ } else if (this.binding instanceof IntersectionTypeBinding18) {
+ return this.bounds = getIntersectingTypes();
}
if (typeVariableBinding != null) {
ReferenceBinding varSuperclass = typeVariableBinding.superclass();
@@ -1214,6 +1260,14 @@
}
/*
+ * @see ITypeBinding#isIntersectionType18
+ */
+ public boolean isIntersectionType() {
+ int kind = this.binding.kind();
+ return kind == Binding.INTERSECTION_TYPE18 || kind == Binding.INTERSECTION_TYPE;
+ }
+
+ /*
* @see ITypeBinding#isLocal()
*/
public boolean isLocal() {
@@ -1363,6 +1417,17 @@
return this.typeAnnotations;
}
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeAnnotationsOnDimensions()
+ */
+ public IAnnotationBinding[][] getTypeAnnotationsOnDimensions() {
+ if (this.typeAnnotationsOnDimensions == null) {
+ this.typeAnnotationsOnDimensions = resolveAnnotationBindingsOnDimensions(this.binding.getTypeAnnotations());
+ }
+ return this.typeAnnotationsOnDimensions;
+ }
+
static class LocalTypeBinding extends TypeBinding {
private IBinding declaringMember;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java
index 0541f2a..55023d2 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java
@@ -1391,7 +1391,7 @@
} else {
normalizedBinding= normalizeTypeBinding(binding);
if (normalizedBinding == null) {
- type = ast.newSimpleType(ast.newSimpleName("invalid")); //$NON-NLS-1$
+ return ast.newSimpleType(ast.newSimpleName("invalid")); //$NON-NLS-1$
} else if (normalizedBinding.isTypeVariable()) {
// no import
type = ast.newSimpleType(ast.newSimpleName(binding.getName()));
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java
index 1e2c529..7233476 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java
@@ -57,16 +57,17 @@
private final static Pattern HTML_TAG_PATTERN;
private final static Pattern HTML_ATTRIBUTE_PATTERN;
static {
- String formatCodeTags = "(pre)?"; //$NON-NLS-1$
- String separateLineTags = "(dl|hr|nl|p|ul|ol|table|tr)?"; //$NON-NLS-1$
- String breakBeforeTags = "(dd|dt|li|td|th|h1|h2|h3|h4|h5|h6|q)?"; //$NON-NLS-1$
- String breakAfterTags = "(br)?"; //$NON-NLS-1$
- String noFormatTags = "(code|em|tt)?"; //$NON-NLS-1$
- String otherTags = "([^<>&&\\S]+)??"; //$NON-NLS-1$
- String ws = "(?:[ \\t]+|[\\r\\n]+[ \\t]*\\*?)"; // whitespace or line break with optional asterisk //$NON-NLS-1$
- String attribute = "(?:" + ws + "+[^=&&\\S]+" + ws + "*(=)" + ws + "*\"?[^\"]*\"?)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- HTML_TAG_PATTERN = Pattern.compile("<(/)?" //$NON-NLS-1$
- + formatCodeTags + separateLineTags + breakBeforeTags + breakAfterTags + noFormatTags + otherTags
+ String formatCodeTags = "(pre)"; //$NON-NLS-1$
+ String separateLineTags = "(dl|hr|nl|p|ul|ol|table|tr)"; //$NON-NLS-1$
+ String breakBeforeTags = "(dd|dt|li|td|th|h1|h2|h3|h4|h5|h6|q)"; //$NON-NLS-1$
+ String breakAfterTags = "(br)"; //$NON-NLS-1$
+ String noFormatTags = "(code|em|tt)"; //$NON-NLS-1$
+ String otherTags = "([^<>&&\\S]++)"; //$NON-NLS-1$
+ String ws = "(?>[ \\t]++|[\\r\\n]++[ \\t]*+\\*?)"; // whitespace or line break with optional asterisk //$NON-NLS-1$
+ String attributeValue = "(?>\"[^\"]*\")|(?>\'[^\']*\')|[^/>\"\'&&\\S]++"; //$NON-NLS-1$
+ String attribute = "(?>" + ws + "+[^=&&\\S]+" + ws + "*(=)" + ws + "*(?>" + attributeValue + "))"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ HTML_TAG_PATTERN = Pattern.compile("<(/)?+(?:" //$NON-NLS-1$
+ + formatCodeTags + '|' + separateLineTags + '|' + breakBeforeTags + '|' + breakAfterTags + '|' + noFormatTags + '|' + otherTags + ')'
+ "(" + attribute + "*)" + ws + "*/?>", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
HTML_ATTRIBUTE_PATTERN = Pattern.compile(attribute);
}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
index ae1ef58..92b756b 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
@@ -361,27 +361,28 @@
@Override
public boolean visit(ArrayInitializer node) {
int openBraceIndex = this.tm.firstIndexIn(node, TokenNameLBRACE);
- Token afterOpenBraceToken = this.tm.get(openBraceIndex + 1);
- boolean isEmpty = afterOpenBraceToken.tokenType == TokenNameRBRACE;
- if (isEmpty && this.options.keep_empty_array_initializer_on_one_line)
- return true;
+ boolean isEmpty = handleEmptyLinesIndentation(openBraceIndex);
- Token openBraceToken = this.tm.get(openBraceIndex);
int closeBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
- handleBracePosition(openBraceToken, closeBraceIndex, this.options.brace_position_for_array_initializer);
+ Token openBraceToken = this.tm.get(openBraceIndex);
+ Token closeBraceToken = this.tm.get(closeBraceIndex);
+
+ if (!(node.getParent() instanceof ArrayInitializer)) {
+ Token afterOpenBraceToken = this.tm.get(openBraceIndex + 1);
+ for (int i = 0; i < this.options.continuation_indentation_for_array_initializer; i++) {
+ afterOpenBraceToken.indent();
+ closeBraceToken.unindent();
+ }
+ }
+
+ if (!isEmpty || !this.options.keep_empty_array_initializer_on_one_line)
+ handleBracePosition(openBraceToken, closeBraceIndex, this.options.brace_position_for_array_initializer);
if (!isEmpty) {
- Token closeBraceToken = this.tm.get(closeBraceIndex);
if (this.options.insert_new_line_after_opening_brace_in_array_initializer)
openBraceToken.breakAfter();
if (this.options.insert_new_line_before_closing_brace_in_array_initializer)
closeBraceToken.breakBefore();
- if (!(node.getParent() instanceof ArrayInitializer)) {
- for (int i = 0; i < this.options.continuation_indentation_for_array_initializer; i++) {
- afterOpenBraceToken.indent();
- closeBraceToken.unindent();
- }
- }
}
return true;
}
@@ -550,6 +551,7 @@
: this.tm.firstIndexAfter(nodeBeforeOpenBrace, TokenNameLBRACE);
int closeBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
Token openBraceToken = this.tm.get(openBraceIndex);
+ Token closeBraceToken = this.tm.get(closeBraceIndex);
handleBracePosition(openBraceToken, closeBraceIndex, bracePosition);
boolean isEmpty = true;
@@ -559,13 +561,16 @@
break;
}
}
+
+ handleEmptyLinesIndentation(openBraceIndex);
+
if (!isEmpty || newLineInEmpty) {
openBraceToken.breakAfter();
- this.tm.get(closeBraceIndex).breakBefore();
+ closeBraceToken.breakBefore();
}
if (indentBody) {
this.tm.get(openBraceIndex + 1).indent();
- this.tm.get(closeBraceIndex).unindent();
+ closeBraceToken.unindent();
}
}
@@ -582,6 +587,31 @@
}
}
+ private boolean handleEmptyLinesIndentation(int openBraceIndex) {
+ Token open = this.tm.get(openBraceIndex);
+ Token next = this.tm.get(openBraceIndex + 1);
+ boolean isEmpty = next.tokenType == TokenNameRBRACE;
+ if (!isEmpty || this.tm.countLineBreaksBetween(open, next) < 2 || !this.options.indent_empty_lines)
+ return isEmpty;
+
+ // find a line break and make a token out of it
+ for (int i = open.originalEnd + 1; i < next.originalStart; i++) {
+ char c = this.tm.charAt(i);
+ char c2 = this.tm.charAt(i + 1);
+ int lineBreakStart = (c == '\r' || c == '\n') ? i : -1;
+ int lineBreakEnd = ((c2 == '\r' || c2 == '\n') && c2 != c) ? i + 1 : lineBreakStart;
+ if (lineBreakStart >= 0) {
+ Token emptyLineToken = new Token(lineBreakStart, lineBreakEnd, Token.TokenNameEMPTY_LINE);
+ emptyLineToken.breakBefore();
+ emptyLineToken.breakAfter();
+ emptyLineToken.setToEscape(true); // force text builder to use toString()
+ this.tm.insert(openBraceIndex + 1, emptyLineToken);
+ return true;
+ }
+ }
+ return true;
+ }
+
private void indent(ASTNode node) {
int startIndex = this.tm.firstIndexIn(node, -1);
while (startIndex > 0 && this.tm.get(startIndex - 1).isComment())
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
index 9ecfdc8..2377567 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
@@ -191,9 +191,10 @@
} else {
handleToken(node.getName(), TokenNameLPAREN, spaceBeforeOpenParen, spaceAfterOpenParen);
- if (node.isConstructor() ? this.options.insert_space_before_closing_paren_in_constructor_declaration
- : this.options.insert_space_before_closing_paren_in_method_declaration)
- handleToken(node.getName(), TokenNameRPAREN, true, false);
+ boolean spaceBeforeCloseParen = node.isConstructor()
+ ? this.options.insert_space_before_closing_paren_in_constructor_declaration
+ : this.options.insert_space_before_closing_paren_in_method_declaration;
+ handleTokenBefore(node.getBody(), TokenNameRPAREN, spaceBeforeCloseParen, false);
}
if ((node.isConstructor() ? this.options.insert_space_before_opening_brace_in_constructor_declaration
@@ -464,7 +465,8 @@
if (handleParenthesis) {
handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_annotation,
this.options.insert_space_after_opening_paren_in_annotation);
- handleToken(node, TokenNameRPAREN, this.options.insert_space_before_closing_paren_in_annotation, false);
+ if (this.options.insert_space_before_closing_paren_in_annotation)
+ this.tm.lastTokenIn(node, TokenNameRPAREN).spaceBefore();
}
ASTNode parent = node.getParent();
@@ -486,7 +488,7 @@
this.options.insert_space_before_opening_paren_in_method_declaration,
this.options.insert_space_after_opening_paren_in_method_declaration);
- handleToken(node, TokenNameRPAREN,
+ handleTokenBefore(node.getBody(), TokenNameRPAREN,
this.options.insert_space_before_closing_paren_in_method_declaration, false);
}
handleCommas(parameters, this.options.insert_space_before_comma_in_method_declaration_parameters,
@@ -497,19 +499,17 @@
@Override
public boolean visit(Block node) {
- if (node.getParent().getLength() == 0)
+ ASTNode parent = node.getParent();
+ if (parent.getLength() == 0)
return true; // this is a fake block created by parsing in statements mode
- if (node.getParent() instanceof MethodDeclaration)
+ if (parent instanceof MethodDeclaration)
return true; // spaces handled in #visit(MethodDeclaration)
handleToken(node, TokenNameLBRACE, this.options.insert_space_before_opening_brace_in_block, false);
- if (this.options.insert_space_after_closing_brace_in_block) {
+ if (this.options.insert_space_after_closing_brace_in_block
+ && (parent instanceof Statement || parent instanceof CatchClause)) {
int closeBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
- if (closeBraceIndex + 1 < this.tm.size()) {
- int nextToken = this.tm.get(closeBraceIndex + 1).tokenType;
- if (nextToken != TokenNameSEMICOLON && nextToken != TokenNameRPAREN)
- this.tm.get(closeBraceIndex).spaceAfter();
- }
+ this.tm.get(closeBraceIndex).spaceAfter();
}
return true;
}
@@ -601,7 +601,7 @@
public boolean visit(ClassInstanceCreation node) {
List<Type> typeArguments = node.typeArguments();
handleTypeArguments(typeArguments);
- handleInvocation(node, node.getType());
+ handleInvocation(node, node.getType(), node.getAnonymousClassDeclaration());
if (!typeArguments.isEmpty()) {
handleTokenBefore(typeArguments.get(0), TokenNamenew, false, true); // fix for: new<Integer>A<String>()
}
@@ -631,6 +631,11 @@
}
private void handleInvocation(ASTNode invocationNode, ASTNode nodeBeforeOpeningParen) {
+ handleInvocation(invocationNode, nodeBeforeOpeningParen, null);
+ }
+
+ private void handleInvocation(ASTNode invocationNode, ASTNode nodeBeforeOpeningParen,
+ ASTNode nodeAfterClosingParen) {
if (handleEmptyParens(nodeBeforeOpeningParen,
this.options.insert_space_between_empty_parens_in_method_invocation)) {
handleToken(nodeBeforeOpeningParen, TokenNameLPAREN,
@@ -640,7 +645,10 @@
this.options.insert_space_before_opening_paren_in_method_invocation,
this.options.insert_space_after_opening_paren_in_method_invocation);
if (this.options.insert_space_before_closing_paren_in_method_invocation) {
- this.tm.lastTokenIn(invocationNode, TokenNameRPAREN).spaceBefore();
+ Token closingParen = nodeAfterClosingParen == null
+ ? this.tm.lastTokenIn(invocationNode, TokenNameRPAREN)
+ : this.tm.firstTokenBefore(nodeAfterClosingParen, TokenNameRPAREN);
+ closingParen.spaceBefore();
}
}
}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java
index f1b92e1..8e725a9 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java
@@ -153,7 +153,7 @@
if (getLineBreaksBefore() > 1) {
Token indentToken = null;
if (this.options.indent_empty_lines && token.tokenType != TokenNameNotAToken)
- indentToken = token.getIndent() > getPrevious().getIndent() ? token : getPrevious();
+ indentToken = (index == 0 || token.getIndent() > getPrevious().getIndent()) ? token : getPrevious();
for (int i = 1; i < getLineBreaksBefore(); i++) {
bufferLineSeparator(token, true);
if (indentToken != null)
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Token.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Token.java
index 66dfafb..762edd0 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Token.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Token.java
@@ -70,6 +70,9 @@
}
}
+ /** Special token type used to mark tokens that store empty line indentation */
+ public static final int TokenNameEMPTY_LINE = 10000;
+
/** Position in source of the first character. */
public final int originalStart;
/** Position in source of the last character (this position is included in the token). */
@@ -276,6 +279,8 @@
}
public String toString(String source) {
+ if (this.tokenType == TokenNameEMPTY_LINE)
+ return ""; //$NON-NLS-1$
return source.substring(this.originalStart, this.originalEnd + 1);
}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
index aff5ee5..76f74e1 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
@@ -432,6 +432,8 @@
for (Token[] pair : this.formatOffTagPairs) {
int index1 = findIndex(pair[0].originalStart, -1, false);
int index2 = findIndex(pair[1].originalEnd, -1, false);
+ pair[0] = get(index1);
+ pair[1] = get(index2);
Token unformatted = new Token(pair[0].originalStart, pair[1].originalEnd, TokenNameWHITESPACE);
unformatted.setIndent(Math.min(pair[0].getIndent(), findSourcePositionInLine(pair[0].originalStart)));
unformatted.putLineBreaksBefore(pair[0].getLineBreaksBefore());
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/CommentWrapExecutor.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/CommentWrapExecutor.java
index dd89f53..b24658a 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/CommentWrapExecutor.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/CommentWrapExecutor.java
@@ -227,6 +227,7 @@
if (prefix.tokenType == TokenNameWHITESPACE) {
whitespace = new Token(prefix);
whitespace.breakBefore();
+ whitespace.setIndent(indent);
whitespace.setWrapPolicy(new WrapPolicy(0, commentIndex, false));
prefix = structure.get(1);
assert prefix.tokenType == TokenNameCOMMENT_LINE;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/FieldAligner.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/FieldAligner.java
index a548f48..9c15869 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/FieldAligner.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/FieldAligner.java
@@ -23,7 +23,6 @@
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.internal.formatter.Token;
import org.eclipse.jdt.internal.formatter.TokenManager;
@@ -71,21 +70,14 @@
this.tm = tokenManager;
}
- public void prepareAlign(TypeDeclaration node) {
- List<FieldDeclaration> bodyDeclarations = node.bodyDeclarations();
+ public void prepareAlign(List<FieldDeclaration> bodyDeclarations) {
ArrayList<FieldDeclaration> alignGroup = new ArrayList<>();
for (BodyDeclaration declaration : bodyDeclarations) {
- if (!alignGroup.isEmpty()) {
- if ((declaration instanceof FieldDeclaration)) {
- alignGroup.add((FieldDeclaration) declaration);
- } else {
- alignFields(alignGroup);
- alignGroup = new ArrayList<>();
- }
- }
- if (alignGroup.isEmpty()) {
- if (declaration instanceof FieldDeclaration)
- alignGroup.add((FieldDeclaration) declaration);
+ if ((declaration instanceof FieldDeclaration)) {
+ alignGroup.add((FieldDeclaration) declaration);
+ } else {
+ alignFields(alignGroup);
+ alignGroup = new ArrayList<>();
}
}
alignFields(alignGroup);
@@ -104,7 +96,7 @@
int positionInLine = this.tm.getPositionInLine(nameIndex);
maxNameAlign = Math.max(maxNameAlign, positionInLine);
}
- maxNameAlign = this.tm.toIndent(maxNameAlign, true);
+ maxNameAlign = this.tm.toIndent(maxNameAlign, false);
int maxAssignAlign = 0;
for (FieldDeclaration declaration : alignGroup) {
@@ -121,7 +113,7 @@
maxAssignAlign = Math.max(maxAssignAlign, positionInLine);
}
}
- maxAssignAlign = this.tm.toIndent(maxAssignAlign, true);
+ maxAssignAlign = this.tm.toIndent(maxAssignAlign, false);
for (FieldDeclaration declaration : alignGroup) {
List<VariableDeclarationFragment> fragments = declaration.fragments();
@@ -155,7 +147,7 @@
maxCommentAlign = Math.max(maxCommentAlign,
positionCounter.findMaxPosition(firstIndexInLine, lastIndex));
}
- maxCommentAlign = this.tm.toIndent(maxCommentAlign, true);
+ maxCommentAlign = this.tm.toIndent(maxCommentAlign, false);
for (FieldDeclaration declaration : alignGroup) {
int typeIndex = this.tm.firstIndexIn(declaration.getType(), -1);
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java
index 791c385..a25a29b 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java
@@ -320,6 +320,7 @@
findWrapsCached(index, currentIndent);
break;
}
+ currentIndent = Math.max(currentIndent, token.getAlign());
token.setIndent(currentIndent);
}
token = this.tm.get(index);
@@ -346,6 +347,7 @@
break;
if (shouldForceWrap(token, currentIndent))
currentIndent = token.getIndent();
+ currentIndent = Math.max(currentIndent, token.getAlign());
token.setIndent(currentIndent);
}
}
@@ -634,8 +636,8 @@
int getWrapIndent(Token token) {
WrapPolicy policy = token.getWrapPolicy();
- if (policy == null || (token.getLineBreaksBefore() > 1 && !policy.isForced && !policy.isTopPriority()))
- return token.getIndent(); // no additional indentation after an empty line
+ if (policy == null)
+ return token.getIndent();
if (this.options.never_indent_line_comments_on_first_column && token.tokenType == TokenNameCOMMENT_LINE
&& token.getIndent() == 0)
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
index 39bcda7..3ac9ad2 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
@@ -38,6 +38,7 @@
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.Assignment;
@@ -106,7 +107,7 @@
final DefaultCodeFormatterOptions options;
final int kind;
- FieldAligner fieldAligner;
+ final FieldAligner fieldAligner;
int importsStart = -1, importsEnd = -1;
@@ -125,11 +126,17 @@
this.tm = tokenManager;
this.options = options;
this.kind = kind;
+
+ this.fieldAligner = new FieldAligner(this.tm);
}
@Override
public boolean preVisit2(ASTNode node) {
this.currentDepth++;
+
+ assert this.wrapIndexes.isEmpty() && this.wrapPenalties.isEmpty();
+ assert this.wrapParentIndex == -1 && this.wrapGroupEnd == -1;
+
boolean isMalformed = (node.getFlags() & ASTNode.MALFORMED) != 0;
if (isMalformed) {
this.tm.addDisableFormatTokenPair(this.tm.firstTokenIn(node, -1), this.tm.lastTokenIn(node, -1));
@@ -180,12 +187,23 @@
handleWrap(this.options.alignment_for_superinterfaces_in_type_declaration, PREFERRED);
}
- if (this.options.align_type_members_on_columns) {
- if (this.fieldAligner == null) {
- this.fieldAligner = new FieldAligner(this.tm);
- }
- this.fieldAligner.prepareAlign(node);
- }
+ if (this.options.align_type_members_on_columns)
+ this.fieldAligner.prepareAlign(node.bodyDeclarations());
+
+ return true;
+ }
+
+ @Override
+ public boolean visit(AnnotationTypeDeclaration node) {
+ if (this.options.align_type_members_on_columns)
+ this.fieldAligner.prepareAlign(node.bodyDeclarations());
+ return true;
+ }
+
+ @Override
+ public boolean visit(AnonymousClassDeclaration node) {
+ if (this.options.align_type_members_on_columns)
+ this.fieldAligner.prepareAlign(node.bodyDeclarations());
return true;
}
@@ -218,13 +236,16 @@
}
if (!node.isConstructor()) {
+ this.wrapParentIndex = this.tm.findFirstTokenInLine(this.tm.firstIndexIn(node.getName(), -1));
List<TypeParameter> typeParameters = node.typeParameters();
if (!typeParameters.isEmpty())
this.wrapIndexes.add(this.tm.firstIndexIn(typeParameters.get(0), -1));
- if (node.getReturnType2() != null && !node.modifiers().isEmpty())
- this.wrapIndexes.add(this.tm.firstIndexIn(node.getReturnType2(), -1));
+ if (node.getReturnType2() != null) {
+ int returTypeIndex = this.tm.firstIndexIn(node.getReturnType2(), -1);
+ if (returTypeIndex != this.wrapParentIndex)
+ this.wrapIndexes.add(returTypeIndex);
+ }
this.wrapIndexes.add(this.tm.firstIndexIn(node.getName(), -1));
- this.wrapParentIndex = this.tm.findFirstTokenInLine(this.tm.firstIndexIn(node.getName(), -1));
this.wrapGroupEnd = this.tm.lastIndexIn(node.getName(), -1);
handleWrap(this.options.alignment_for_method_declaration);
}
@@ -252,6 +273,10 @@
this.wrapPenalties.add(PREFERRED);
handleWrap(this.options.alignment_for_superinterfaces_in_enum_declaration, node);
}
+
+ if (this.options.align_type_members_on_columns)
+ this.fieldAligner.prepareAlign(node.bodyDeclarations());
+
return true;
}
@@ -333,7 +358,8 @@
findTokensToWrap(node, 0);
this.wrapParentIndex = this.wrapIndexes.remove(0);
this.wrapGroupEnd = this.tm.lastIndexIn(node, -1);
- if ((this.options.alignment_for_binary_expression & Alignment.M_INDENT_ON_COLUMN) != 0)
+ if ((this.options.alignment_for_binary_expression & Alignment.M_INDENT_ON_COLUMN) != 0
+ && this.wrapParentIndex > 0)
this.wrapParentIndex--;
for (int i = this.wrapParentIndex; i >= 0; i--) {
if (!this.tm.get(i).isComment()) {
@@ -562,7 +588,6 @@
this.wrapParentIndex = this.tm.findIndex(firstToken.originalStart - 1, TokenNameLPAREN, false);
if (!arguments.isEmpty() && this.wrapGroupEnd < 0)
this.wrapGroupEnd = this.tm.lastIndexIn(arguments.get(arguments.size() - 1), -1);
- assert this.wrapGroupEnd >= 0;
handleWrap(wrappingOption, 1 / PREFERRED);
}
}
@@ -577,17 +602,22 @@
}
private void handleWrap(int wrappingOption, ASTNode parentNode) {
+ doHandleWrap(wrappingOption, parentNode);
+ this.wrapIndexes.clear();
+ this.wrapPenalties.clear();
+ this.wrapParentIndex = this.wrapGroupEnd = -1;
+ }
+
+ private void doHandleWrap(int wrappingOption, ASTNode parentNode) {
if (this.wrapIndexes.isEmpty())
return;
- assert this.wrapParentIndex >= 0;
+ assert this.wrapParentIndex >= 0 && this.wrapParentIndex < this.wrapIndexes.get(0);
+ assert this.wrapGroupEnd >= this.wrapIndexes.get(this.wrapIndexes.size() - 1);
float penalty = this.wrapPenalties.isEmpty() ? 1 : this.wrapPenalties.get(0);
WrapPolicy policy = getWrapPolicy(wrappingOption, penalty, true, parentNode);
- if (policy == null) {
- this.wrapIndexes.clear();
- this.wrapPenalties.clear();
- this.wrapParentIndex = this.wrapGroupEnd = -1;
+ if (policy == null)
return;
- }
+
setTokenWrapPolicy(this.wrapIndexes.get(0), policy, true);
boolean wrapPreceedingComments = !(parentNode instanceof InfixExpression)
@@ -615,9 +645,6 @@
this.tm.get(this.wrapIndexes.get(0)).breakBefore();
}
}
- this.wrapIndexes.clear();
- this.wrapPenalties.clear();
- this.wrapParentIndex = this.wrapGroupEnd = -1;
}
private void setTokenWrapPolicy(int index, WrapPolicy policy, boolean wrapPreceedingComments) {
@@ -704,8 +731,7 @@
public void finishUp(ASTNode astRoot) {
preserveExistingLineBreaks();
new WrapExecutor(this.tm, this.options).executeWraps();
- if (this.fieldAligner != null)
- this.fieldAligner.alignComments();
+ this.fieldAligner.alignComments();
wrapComments();
fixEnumConstantIndents(astRoot);
}
@@ -722,45 +748,25 @@
@Override
protected boolean token(Token token, int index) {
- int lineBreaks = getLineBreaksBetween(getPrevious(), token);
- if (index > WrapPreparator.this.importsStart && index < WrapPreparator.this.importsEnd) {
- lineBreaks = lineBreaks > 1 ? (this.options2.blank_lines_between_import_groups + 1) : 0;
- } else {
- lineBreaks = Math.min(lineBreaks, this.options2.number_of_empty_lines_to_preserve + 1);
- }
+ boolean isBetweenImports = index > WrapPreparator.this.importsStart && index < WrapPreparator.this.importsEnd;
+ int lineBreaks = getLineBreaksToPreserve(getPrevious(), token, isBetweenImports);
if (lineBreaks <= getLineBreaksBefore())
return true;
- if (!this.options2.join_wrapped_lines && token.isWrappable() && lineBreaks == 1) {
- token.breakBefore();
+ if (lineBreaks == 1) {
+ if ((!this.options2.join_wrapped_lines && token.isWrappable()) || index == 0)
+ token.breakBefore();
} else if (lineBreaks > 1) {
- if (index == 0)
- lineBreaks--;
token.putLineBreaksBefore(lineBreaks);
}
return true;
}
- private int getLineBreaksBetween(Token token1, Token token2) {
- if (token1 != null) {
- List<Token> structure1 = token1.getInternalStructure();
- if (structure1 != null && !structure1.isEmpty())
- token1 = structure1.get(structure1.size() - 1);
- }
- List<Token> structure2 = token2.getInternalStructure();
- if (structure2 != null && !structure2.isEmpty())
- token2 = structure2.get(0);
- int lineBreaks = WrapPreparator.this.tm.countLineBreaksBetween(token1, token2);
- if (token1 == null)
- lineBreaks++;
- return lineBreaks;
- }
});
Token last = this.tm.get(this.tm.size() - 1);
last.clearLineBreaksAfter();
- int endingBreaks = this.tm.countLineBreaksBetween(last, null);
- endingBreaks = Math.min(endingBreaks, this.options.number_of_empty_lines_to_preserve);
+ int endingBreaks = getLineBreaksToPreserve(last, null, false);
if (endingBreaks > 0) {
last.putLineBreaksAfter(endingBreaks);
} else if ((this.kind & CodeFormatter.K_COMPILATION_UNIT) != 0
@@ -769,6 +775,29 @@
}
}
+ int getLineBreaksToPreserve(Token token1, Token token2, boolean isBetweenImports) {
+ if (token1 != null) {
+ List<Token> structure = token1.getInternalStructure();
+ if (structure != null && !structure.isEmpty())
+ token1 = structure.get(structure.size() - 1);
+ }
+ if (token2 != null) {
+ List<Token> structure = token2.getInternalStructure();
+ if (structure != null && !structure.isEmpty())
+ token2 = structure.get(0);
+ }
+ int lineBreaks = WrapPreparator.this.tm.countLineBreaksBetween(token1, token2);
+ if (isBetweenImports)
+ return lineBreaks > 1 ? (this.options.blank_lines_between_import_groups + 1) : 0;
+
+ int toPreserve = this.options.number_of_empty_lines_to_preserve;
+ if (token1 != null && token2 != null)
+ toPreserve++; // n empty lines = n+1 line breaks, except for file start and end
+ if (token1 != null && token1.tokenType == Token.TokenNameEMPTY_LINE)
+ toPreserve--;
+ return Math.min(lineBreaks, toPreserve);
+ }
+
private void wrapComments() {
CommentWrapExecutor commentWrapper = new CommentWrapExecutor(this.tm, this.options);
boolean isNLSTagInLine = false;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
index 5f893e7..0ea74b9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
@@ -1308,6 +1308,7 @@
}
protected void parse() {
this.diet = true;
+ this.dietInt = 0;
super.parse();
}
/*
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
index faa6d04..c21ab1f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
@@ -946,9 +946,11 @@
IProgressMonitor pm) {
boolean old = this.diet;
+ int oldInt = this.dietInt;
CompilationUnitDeclaration parsedUnit = null;
try {
this.diet = true;
+ this.dietInt = 0;
this.reportReferenceInfo = fullParse;
CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit);
parsedUnit = parse(unit, compilationUnitResult);
@@ -976,6 +978,7 @@
// ignore this exception
} finally {
this.diet = old;
+ this.dietInt = oldInt;
reset();
}
return parsedUnit;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
index aff2184..85e8139 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
@@ -1321,7 +1321,7 @@
} else if (this.binaryType.getElementName().equals(typeName))
return this.binaryType;
else
- return this.binaryType.getType(typeName);
+ return ((this.typeDepth <= 1) ? this.binaryType : this.types[this.typeDepth - 1]).getType(typeName);
}
/**
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
index dc0177b..fa43a28 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -1359,7 +1359,9 @@
if (qualificationLength > 0) {
System.arraycopy(record.qualification, 0, path, pos, qualificationLength - 1);
CharOperation.replace(path, '.', '/');
- path[qualificationLength-1] = '/';
+
+ // Do not use '/'. Access rules work on package level and should not discriminate on enclosing types.
+ path[qualificationLength-1] = '$';
pos += qualificationLength;
}
if (nameLength > 0) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index fef7832..5b5634c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -1047,11 +1047,10 @@
* Selects the most applicable method (though similar but not to be confused with its namesake in jls)
* All this machinery for that elusive uncommon case referred in bug 431357.
*/
-private MethodBinding getMostApplicableMethod(List<MethodBinding> possibleMethods) {
+private MethodBinding getMostApplicableMethod(List<MethodBinding> possibleMethods, MethodPattern methodPattern) {
int size = possibleMethods.size();
MethodBinding result = size != 0 ? possibleMethods.get(0) : null;
if (size > 1) {
- MethodPattern methodPattern = ((MethodPattern) this.pattern);
// can cache but may not be worth since this is not a common case
Map<Integer, List<String>> methodPatternReverseNames = getSplitNames(methodPattern.parameterQualifications, methodPattern.parameterSimpleNames);
int len = possibleMethods.size();
@@ -1133,7 +1132,7 @@
possibleMethods.add(methods[i]);
}
}
- result = getMostApplicableMethod(possibleMethods);
+ result = getMostApplicableMethod(possibleMethods, methodPattern);
}
}
this.bindings.put(methodPattern, result != null ? result : new ProblemMethodBinding(methodPattern.selector, null, ProblemReasons.NotFound));