Updated to dd3bff4d99a5193497eb7e3c0e1bc46a32b7c36a from jdt.core
- previous are master commits, next is grammar redesign
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 12883dc..47c619a 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
@@ -11,8 +11,10 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 335093 - [compiler][null] minimal hook for future null annotation support
* Technical University Berlin - adapted for Object Teams
+ * Stephan Herrmann - Contribution for
+ * bug 335093 - [compiler][null] minimal hook for future null annotation support
+ * bug 388800 - [1.8] adjust tests to 1.8 JRE
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -69,6 +71,199 @@
import org.eclipse.jdt.internal.core.search.indexing.BinaryIndexer;
public abstract class AbstractRegressionTest extends AbstractCompilerTest implements StopableTestCase {
+
+ // for compiling against JRE 8:
+ static final boolean IS_JRE_8;
+ static final String COMPARATOR_IMPL_JRE8;
+ static final String COMPARATOR_RAW_IMPL_JRE8;
+ static final String COLLECTION_IMPL_JRE8;
+ static final String COLLECTION_RAW_IMPL_JRE8;
+ static final String LIST_IMPL_JRE8;
+ static final String LIST_RAW_IMPL_JRE8;
+ static final String ITERABLE_IMPL_JRE8;
+ static final String ITERABLE_RAW_IMPL_JRE8;
+ static final String ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8;
+ static final String MAP_IMPL_JRE8;
+ static final String MAP_RAW_IMPL_JRE8;
+ static final String MAP_STREAM_IMPL_JRE8;
+ static final String MAP_STREAM_RAW_IMPL_JRE8;
+
+ static {
+ String javaVersion = System.getProperty("java.specification.version");
+ IS_JRE_8 = "1.8".equals(javaVersion);
+ if (IS_JRE_8) { // TODO(stephan) accommodate future versions ...
+ COMPARATOR_IMPL_JRE8 =
+ " public java.util.Comparator<*> compose(java.util.Comparator<? super *> other) { return null; }\n" +
+ " public java.util.Comparator<*> reverse() { return null; }\n";
+ COMPARATOR_RAW_IMPL_JRE8 =
+ " public java.util.Comparator compose(java.util.Comparator other) { return null; }\n" +
+ " public java.util.Comparator reverse() { return null; }\n";
+ COLLECTION_IMPL_JRE8 =
+ " public boolean retainAll(java.util.functions.Predicate<? super *> filter) { return false; }\n" +
+ " public boolean removeAll(java.util.functions.Predicate<? super *> filter) { return false; }\n" +
+ " public void addAll(Iterable<? extends *> source) { }\n";
+ COLLECTION_RAW_IMPL_JRE8 =
+ " public @SuppressWarnings(\"rawtypes\") boolean retainAll(java.util.functions.Predicate filter) { return false; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") boolean removeAll(java.util.functions.Predicate filter) { return false; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") void addAll(Iterable source) { }\n";
+ LIST_IMPL_JRE8 =// replace '*' with your concrete type argument
+ " public void sort(java.util.Comparator<? super *> comparator) {}\n" +
+ " public void parallelSort(java.util.Comparator<? super *> comparator) {}\n";
+ LIST_RAW_IMPL_JRE8 =
+ " public @SuppressWarnings(\"rawtypes\") void sort(java.util.Comparator comparator) {}\n" +
+ " public @SuppressWarnings(\"rawtypes\") void parallelSort(java.util.Comparator comparator) {}\n";
+ ITERABLE_IMPL_JRE8 = // replace '*' with your concrete type argument
+ " public boolean isEmpty() { return false; }\n" +
+ " public long count() { return 0L; }\n" +
+ " public * getOnly() { return null; }\n" +
+ " public * getFirst() { return null; }\n" +
+ " public * getAny() { return null; }\n" +
+ " public * reduce(* base, java.util.functions.BinaryOperator<*> reducer) { return null; }\n" +
+ " public <A extends java.util.Fillable<? super *>> A into(A target) { return null; }\n" +
+ " public void forEach(java.util.functions.Block<? super *> block) {}\n" +
+ " public Iterable<*> sorted(java.util.Comparator<? super *> comparator) { return null; }\n" +
+ " public boolean anyMatch(java.util.functions.Predicate<? super *> filter) { return false; }\n" +
+ " public boolean allMatch(java.util.functions.Predicate<? super *> filter) { return false; }\n" +
+ " public boolean noneMatch(java.util.functions.Predicate<? super *> filter) { return false; }\n" +
+ " public Iterable<*> cumulate(java.util.functions.BinaryOperator<*> op) { return null; }\n" +
+ " public <U> MapStream<*,U> mapped(java.util.functions.Mapper<? super *, ? extends U> mapper) { return null; }\n" +
+ " public Iterable<*> filter(java.util.functions.Predicate<? super *> predicate) { return null; }\n" +
+ " public <U> Iterable<U> map(java.util.functions.Mapper<? super *, ? extends U> mapper) { return null; }\n" +
+ " public double mapReduce(java.util.functions.DoubleMapper<? super *> mapper, double base, java.util.functions.DoubleBinaryOperator reducer) { return 0; }\n" +
+ " public long mapReduce(java.util.functions.LongMapper<? super *> mapper, long base, java.util.functions.LongBinaryOperator reducer) { return 0; }\n" +
+ " public int mapReduce(java.util.functions.IntMapper<? super *> mapper, int base, java.util.functions.IntBinaryOperator reducer) { return 0; }\n" +
+ " public <U> U mapReduce(java.util.functions.Mapper<? super *, ? extends U> mapper, U base, java.util.functions.BinaryOperator<U> reducer) { return null; }\n" +
+ " public <U> Iterable<U> flatMap(java.util.functions.Mapper<? super *, ? extends Iterable<U>> mapper) { return null; }\n" +
+ " public <U> MapStream<U, Iterable<*>> groupBy(java.util.functions.Mapper<? super *, ? extends U> mapper) { return null; }\n" +
+ " public <U> MapStream<U, Iterable<*>> groupByMulti(java.util.functions.Mapper<? super *, ? extends Iterable<U>> mapper) { return null; }\n" +
+ " public Iterable<*> uniqueElements() { return null; }\n";
+ ITERABLE_RAW_IMPL_JRE8 =
+ " public boolean isEmpty() { return false; }\n" +
+ " public long count() { return 0L; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object getOnly() { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object getFirst() { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object getAny() { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object reduce(Object base, java.util.functions.BinaryOperator reducer) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") java.util.Fillable into(java.util.Fillable target) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") void forEach(java.util.functions.Block block) {}\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable sorted(java.util.Comparator comparator) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") boolean anyMatch(java.util.functions.Predicate filter) { return false; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") boolean allMatch(java.util.functions.Predicate filter) { return false; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") boolean noneMatch(java.util.functions.Predicate filter) { return false; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable cumulate(java.util.functions.BinaryOperator op) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") MapStream mapped(java.util.functions.Mapper mapper) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable filter(java.util.functions.Predicate predicate) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable map(java.util.functions.Mapper mapper) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") double mapReduce(java.util.functions.DoubleMapper mapper, double base, java.util.functions.DoubleBinaryOperator reducer) { return 0; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") long mapReduce(java.util.functions.LongMapper mapper, long base, java.util.functions.LongBinaryOperator reducer) { return 0; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") int mapReduce(java.util.functions.IntMapper mapper, int base, java.util.functions.IntBinaryOperator reducer) { return 0; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object mapReduce(java.util.functions.Mapper mapper, Object base, java.util.functions.BinaryOperator reducer) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable flatMap(java.util.functions.Mapper mapper) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") MapStream groupBy(java.util.functions.Mapper mapper) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") MapStream groupByMulti(java.util.functions.Mapper mapper) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable uniqueElements() { return null; }\n";
+ ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 =
+ " public long count() { return 0L; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object getOnly() { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object getFirst() { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object getAny() { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object reduce(Object base, java.util.functions.BinaryOperator reducer) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") java.util.Fillable into(java.util.Fillable target) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") void forEach(java.util.functions.Block block) {}\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable sorted(java.util.Comparator comparator) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") boolean anyMatch(java.util.functions.Predicate filter) { return false; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") boolean allMatch(java.util.functions.Predicate filter) { return false; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") boolean noneMatch(java.util.functions.Predicate filter) { return false; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable cumulate(java.util.functions.BinaryOperator op) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") MapStream mapped(java.util.functions.Mapper mapper) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable filter(java.util.functions.Predicate predicate) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable map(java.util.functions.Mapper mapper) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") double mapReduce(java.util.functions.DoubleMapper mapper, double base, java.util.functions.DoubleBinaryOperator reducer) { return 0; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") long mapReduce(java.util.functions.LongMapper mapper, long base, java.util.functions.LongBinaryOperator reducer) { return 0; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") int mapReduce(java.util.functions.IntMapper mapper, int base, java.util.functions.IntBinaryOperator reducer) { return 0; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object mapReduce(java.util.functions.Mapper mapper, Object base, java.util.functions.BinaryOperator reducer) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable flatMap(java.util.functions.Mapper mapper) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") MapStream groupBy(java.util.functions.Mapper mapper) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") MapStream groupByMulti(java.util.functions.Mapper mapper) { return null; }\n" +
+ " public @SuppressWarnings(\"rawtypes\") Iterable uniqueElements() { return null; }\n";
+ MAP_IMPL_JRE8 = // '!' stands for 'K,V', '*' for 'K'
+ " public Iterable<BiValue<!>> asIterable() { return null; }\n" +
+ " public Iterable<*> inputs() { return null; }\n";
+ MAP_RAW_IMPL_JRE8 =
+ " public Iterable asIterable() { return null; }\n" +
+ " public Iterable inputs() { return null; }\n";
+ MAP_STREAM_IMPL_JRE8 = // '*' stands for 'K', '%' for 'V'
+ " public BiValue<*,%> getOnly() { return null; }\n" +
+ " public <A extends Map<? super *, ? super %>> A into(A destination) { return null; }\n" +
+ " public void forEach(java.util.functions.BiBlock<? super *, ? super %> block) {}\n" +
+ " public MapStream<*, Iterable<%>> asMultiStream() { return null; }\n" +
+ " public <W> MapStream<*, Iterable<W>> mapValuesMulti(final java.util.functions.BiMapper<? super *, ? super %, Iterable<W>> mapper) { return null; }\n" +
+ " public MapStream<*,%> sorted(java.util.Comparator<? super *> comparator) { return null; }\n" +
+ " public boolean anyMatch(java.util.functions.BiPredicate<? super *, ? super %> predicate) { return false; }\n" +
+ " public boolean allMatch(java.util.functions.BiPredicate<? super *, ? super %> predicate) { return false; }\n" +
+ " public boolean noneMatch(java.util.functions.BiPredicate<? super *, ? super %> predicate) { return false; }\n" +
+ " public MapStream<*,%> merge(MapStream<*,%> other) { return null; }\n" +
+ " public MapStream<*,%> filter(final java.util.functions.BiPredicate<? super *, ? super %> predicate) { return null; }\n" +
+ " public MapStream<%,*> swap() { return null; }\n" +
+ " public BiValue<*,%> getAny() { return null; }\n" +
+ " public MapStream<*,%> filterKeys(final java.util.functions.Predicate<*> filter) { return null; }\n" +
+ " public MapStream<*,%> filterValues(final java.util.functions.Predicate<%> filter) { return null; }\n" +
+ " public <A extends Map<? super *, C>,C extends Collection<? super %>> A intoMulti(A destination, java.util.functions.Factory<C> factory) { return null; }\n" +
+ " public <W> MapStream<*,W> mapValues(final java.util.functions.Mapper<%,W> mapper) { return null; }\n" +
+ " public BiValue<*,%> getFirst() { return null; }\n" +
+ " public <W> MapStream<*, W> map(final java.util.functions.BiMapper<*, %, W> mapper) { return null; }\n";
+ MAP_STREAM_RAW_IMPL_JRE8 =
+ " public BiValue getOnly() { return null; }\n" +
+ " public Map into(Map destination) { return null; }\n" +
+ " public void forEach(java.util.functions.BiBlock block) {}\n" +
+ " public MapStream asMultiStream() { return null; }\n" +
+ " public MapStream mapValuesMulti(final java.util.functions.BiMapper mapper) { return null; }\n" +
+ " public MapStream sorted(java.util.Comparator comparator) { return null; }\n" +
+ " public boolean anyMatch(java.util.functions.BiPredicate predicate) { return false; }\n" +
+ " public boolean allMatch(java.util.functions.BiPredicate predicate) { return false; }\n" +
+ " public boolean noneMatch(java.util.functions.BiPredicate predicate) { return false; }\n" +
+ " public MapStream merge(MapStream other) { return null; }\n" +
+ " public MapStream filter(final java.util.functions.BiPredicate predicate) { return null; }\n" +
+ " public MapStream swap() { return null; }\n" +
+ " public BiValue getAny() { return null; }\n" +
+ " public MapStream filterKeys(final java.util.functions.Predicate filter) { return null; }\n" +
+ " public MapStream filterValues(final java.util.functions.Predicate filter) { return null; }\n" +
+ " public Map intoMulti(Map destination, java.util.functions.Factory factory) { return null; }\n" +
+ " public MapStream mapValues(final java.util.functions.Mapper mapper) { return null; }\n" +
+ " public BiValue getFirst() { return null; }\n" +
+ " public MapStream map(final java.util.functions.BiMapper mapper) { return null; }\n";
+ } else {
+ COMPARATOR_IMPL_JRE8 = "";
+ COMPARATOR_RAW_IMPL_JRE8 = "";
+ COLLECTION_IMPL_JRE8 = "";
+ COLLECTION_RAW_IMPL_JRE8 = "";
+ LIST_IMPL_JRE8 = "";
+ LIST_RAW_IMPL_JRE8 = "";
+ ITERABLE_IMPL_JRE8 = "";
+ ITERABLE_RAW_IMPL_JRE8 = "";
+ ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 = "";
+ MAP_IMPL_JRE8 = "";
+ MAP_RAW_IMPL_JRE8 = "";
+ MAP_STREAM_IMPL_JRE8 = "";
+ MAP_STREAM_RAW_IMPL_JRE8 = "";
+ }
+ }
+ String getListRawImplJRE8() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5)
+ return LIST_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
+ return LIST_RAW_IMPL_JRE8;
+ }
+ String getIterableRawImplJRE8() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5)
+ return ITERABLE_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
+ return ITERABLE_RAW_IMPL_JRE8;
+ }
+ String getCollectionRawImplJRE8() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5)
+ return COLLECTION_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
+ return COLLECTION_RAW_IMPL_JRE8;
+ }
+
// javac comparison related types, fields and methods - see runJavac for
// details
static class JavacCompiler {
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 fcf0e9d..fbc6f69 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
@@ -1027,6 +1027,30 @@
"----------\n");
}
+ // check annotation member modifiers (validity unchanged despite grammar change from JSR 335 - default methods)
+ // and https://bugs.eclipse.org/bugs/show_bug.cgi?id=3383968
+ public void test039a() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public @interface X {\n" +
+ " strictfp double val() default 0.1;\n" +
+ " synchronized String id() default \"zero\";\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 2)\n" +
+ " strictfp double val() default 0.1;\n" +
+ " ^^^^^\n" +
+ "Illegal modifier for the annotation attribute X.val; only public & abstract are permitted\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 3)\n" +
+ " synchronized String id() default \"zero\";\n" +
+ " ^^^^\n" +
+ "Illegal modifier for the annotation attribute X.id; only public & abstract are permitted\n" +
+ "----------\n");
+ }
+
// check annotation array field initializer
public void test040() {
this.runNegativeTest(
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index 9103e2b..7652a87 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -17,6 +17,7 @@
* bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
* bug 374605 - Unreasonable warning for enum-based switch statements
* bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
+ * bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
*
* This is an implementation of an early-draft specification developed under the Java
* Community Process (JCP) and is made available for testing and evaluation purposes
@@ -418,6 +419,7 @@
expectedProblemAttributes.put("CorruptedSignature", new ProblemAttributes(CategorizedProblem.CAT_BUILDPATH));
expectedProblemAttributes.put("DeadCode", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("DefaultMethodNotBelow18", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
+ expectedProblemAttributes.put("DefaultMethodOverridesObjectMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("DiamondNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("DirectInvocationOfAbstractMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("DisallowedTargetForAnnotation", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
@@ -569,6 +571,7 @@
expectedProblemAttributes.put("IndirectAccessToStaticField", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
expectedProblemAttributes.put("IndirectAccessToStaticMethod", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
expectedProblemAttributes.put("IndirectAccessToStaticType", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
+ expectedProblemAttributes.put("InheritedDefaultMethodConflictsWithOtherInherited", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("InheritedFieldHidesEnclosingName", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("InheritedIncompatibleReturnType", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("InheritedMethodHidesEnclosingName", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
@@ -1222,6 +1225,7 @@
expectedProblemAttributes.put("CorruptedSignature", SKIP);
expectedProblemAttributes.put("DeadCode", new ProblemAttributes(JavaCore.COMPILER_PB_DEAD_CODE));
expectedProblemAttributes.put("DefaultMethodNotBelow18", SKIP);
+ expectedProblemAttributes.put("DefaultMethodOverridesObjectMethod", SKIP);
expectedProblemAttributes.put("DiamondNotBelow17", SKIP);
expectedProblemAttributes.put("DirectInvocationOfAbstractMethod", SKIP);
expectedProblemAttributes.put("DisallowedTargetForAnnotation", SKIP);
@@ -1372,6 +1376,7 @@
expectedProblemAttributes.put("IndirectAccessToStaticField", new ProblemAttributes(JavaCore.COMPILER_PB_INDIRECT_STATIC_ACCESS));
expectedProblemAttributes.put("IndirectAccessToStaticMethod", new ProblemAttributes(JavaCore.COMPILER_PB_INDIRECT_STATIC_ACCESS));
expectedProblemAttributes.put("IndirectAccessToStaticType", new ProblemAttributes(JavaCore.COMPILER_PB_INDIRECT_STATIC_ACCESS));
+ expectedProblemAttributes.put("InheritedDefaultMethodConflictsWithOtherInherited", SKIP);
expectedProblemAttributes.put("InheritedFieldHidesEnclosingName", SKIP);
expectedProblemAttributes.put("InheritedIncompatibleReturnType", SKIP);
expectedProblemAttributes.put("InheritedMethodHidesEnclosingName", SKIP);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_5.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_5.java
index 4a2bab6..38436e0 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_5.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_5.java
@@ -2966,7 +2966,7 @@
"The argument of type null should explicitly be cast to Class[] for the invocation of the varargs method getMethod(String, Class...) from type Class. It could alternatively be cast to Class for a varargs invocation\n" +
"----------\n";
String javaVersion = System.getProperty("java.version");
- if (isJRELevel(AbstractCompilerTest.F_1_6|AbstractCompilerTest.F_1_7)
+ if (isJRELevel(AbstractCompilerTest.F_1_6|AbstractCompilerTest.F_1_7|AbstractCompilerTest.F_1_8)
|| (AbstractCompilerTest.getPossibleComplianceLevels() == AbstractCompilerTest.F_1_5
&& javaVersion.indexOf("1.5") == -1)) {
errorMessage =
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DefaultMethodsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DefaultMethodsTest.java
index 5a4e83b..50733d1 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DefaultMethodsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DefaultMethodsTest.java
@@ -23,7 +23,7 @@
// Static initializer to specify tests subset using TESTS_* static variables
// All specified tests which do not belong to the class are skipped...
static {
-// TESTS_NAMES = new String[] { "testModifiers1" };
+// TESTS_NAMES = new String[] { "testInheritedDefaultOverrides" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
@@ -43,6 +43,7 @@
// default methods with various modifiers, positive cases
public void testModifiers1() {
// Inject an unrelated compile error to prevent class file verification. TODO revert
+// (even lambda-enabled JRE doesn't accept now-legal modifier combinations)
// runConformTest(
runNegativeTest(
new String[] {
@@ -198,25 +199,23 @@
// class implements interface with default method.
// - no need to implement this interface method as it is not abstract
public void testModifiers5() {
-// Inject an unrelated compile error to prevent class file verification. TODO revert
-// runConformTest(
- runNegativeTest(
+ runConformTest(
new String[] {
+ "C.java",
+ "public class C implements I {\n" +
+ " public static void main(String[] args) {\n" +
+ " new C().foo();\n" +
+ " }\n" +
+ "}\n",
"I.java",
"public interface I {\n" +
- " void foo() default {}\n" +
- "}\n",
- "C.java",
- "public class C implements I {}\n" +
-// TODO remove me:
- "public class Wrong{}\n"
+ " void foo() default {\n" +
+ " System.out.println(\"default\");\n" +
+ " }\n" +
+ "}\n"
},
- "----------\n" +
- "1. ERROR in C.java (at line 2)\n" +
- " public class Wrong{}\n" +
- " ^^^^^\n" +
- "The public type Wrong must be defined in its own file\n" +
- "----------\n");
+ "default"
+ );
}
// class implements interface with default method.
@@ -239,4 +238,186 @@
"The type C must implement the inherited abstract method I.bar()\n" +
"----------\n");
}
+
+ // JLS 9.4.2 - default method cannot override method from Object
+ // Bug 382355 - [1.8][compiler] Compiler accepts erroneous default method
+ // new error message
+ public void testObjectMethod1() {
+ runNegativeTest(
+ new String[] {
+ "I.java",
+ "public interface I {\n" +
+ " public String toString () default { return \"\";}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in I.java (at line 2)\n" +
+ " public String toString () default { return \"\";}\n" +
+ " ^^^^^^^^^^^\n" +
+ "A default method cannot override a method from java.lang.Object \n" +
+ "----------\n");
+ }
+
+ // JLS 9.4.2 - default method cannot override method from Object
+ // Bug 382355 - [1.8][compiler] Compiler accepts erroneous default method
+ // when using a type variable this is already reported as a name clash
+ public void testObjectMethod2() {
+ runNegativeTest(
+ new String[] {
+ "I.java",
+ "public interface I<T> {\n" +
+ " public boolean equals (T other) default { return false;}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in I.java (at line 2)\n" +
+ " public boolean equals (T other) default { return false;}\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "Name clash: The method equals(T) of type I<T> has the same erasure as equals(Object) of type Object but does not override it\n" +
+ "----------\n");
+ }
+
+ // JLS 9.4.2 - default method cannot override method from Object
+ // Bug 382355 - [1.8][compiler] Compiler accepts erroneous default method
+ // one error for final method is enough
+ public void testObjectMethod3() {
+ runNegativeTest(
+ new String[] {
+ "I.java",
+ "public interface I<T> {\n" +
+ " @Override\n" +
+ " public Class<?> getClass() default { return null;}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in I.java (at line 3)\n" +
+ " public Class<?> getClass() default { return null;}\n" +
+ " ^^^^^^^^^^\n" +
+ "Cannot override the final method from Object\n" +
+ "----------\n");
+ }
+
+ // JLS 9.4.1
+ // Bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
+ // an inherited default methods clashes with another inherited method
+ // simple case
+ public void testInheritedDefaultOverrides01() {
+ runNegativeTest(
+ new String[] {
+ "I1.java",
+ "public interface I1 {\n" +
+ " String foo();\n" +
+ "}\n",
+ "I2.java",
+ "public interface I2 {\n" +
+ " String foo() default { return \"\"; }\n" +
+ "}\n",
+ "I3.java",
+ "public interface I3 extends I1, I2 {\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in I3.java (at line 1)\n" +
+ " public interface I3 extends I1, I2 {\n" +
+ " ^^\n" +
+ "The default method foo() inherited from I2 conflicts with another method inherited from I1\n" +
+ "----------\n");
+ }
+
+ // JLS 9.4.1
+ // Bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
+ // an inherited default methods clashes with another inherited method
+ // indirect inheritance
+ public void testInheritedDefaultOverrides02() {
+ runNegativeTest(
+ new String[] {
+ "I1.java",
+ "public interface I1 {\n" +
+ " String foo();\n" +
+ "}\n",
+ "I2.java",
+ "public interface I2 {\n" +
+ " String foo() default { return \"\"; }\n" +
+ "}\n",
+ "I1A.java",
+ "public interface I1A extends I1 {\n" +
+ "}\n",
+ "I2A.java",
+ "public interface I2A extends I2 {\n" +
+ "}\n",
+ "I3.java",
+ "public interface I3 extends I1A, I2A {\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in I3.java (at line 1)\n" +
+ " public interface I3 extends I1A, I2A {\n" +
+ " ^^\n" +
+ "The default method foo() inherited from I2 conflicts with another method inherited from I1\n" +
+ "----------\n");
+ }
+
+ // JLS 9.4.1
+ // Bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
+ // Parameterized case is already reported as a clash
+ public void testInheritedDefaultOverrides03() {
+ runNegativeTest(
+ new String[] {
+ "I1.java",
+ "import java.util.List;\n" +
+ "public interface I1 {\n" +
+ " String foo(List<String> l);\n" +
+ "}\n",
+ "I2.java",
+ "import java.util.List;\n" +
+ "public interface I2 {\n" +
+ " @SuppressWarnings(\"rawtypes\")\n" +
+ " String foo(List l) default { return \"\"; }\n" +
+ "}\n",
+ "I3.java",
+ "import java.util.List;\n" +
+ "public interface I3 extends I1, I2 {\n" +
+ " @Override\n" +
+ " String foo(List<String> l);\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in I3.java (at line 4)\n" +
+ " String foo(List<String> l);\n" +
+ " ^^^^^^^^^^^^^^^^^^^\n" +
+ "Name clash: The method foo(List<String>) of type I3 has the same erasure as foo(List) of type I2 but does not override it\n" +
+ "----------\n");
+ }
+
+ // JLS 9.4.1
+ // Bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
+ // Parameterized case is already reported as a clash - inverse case of previous
+ public void testInheritedDefaultOverrides04() {
+ runNegativeTest(
+ new String[] {
+ "I1.java",
+ "import java.util.List;\n" +
+ "public interface I1 {\n" +
+ " String foo(List<String> l) default { return \"\"; }\n" +
+ "}\n",
+ "I2.java",
+ "import java.util.List;\n" +
+ "public interface I2 {\n" +
+ " @SuppressWarnings(\"rawtypes\")\n" +
+ " String foo(List l);\n" +
+ "}\n",
+ "I3.java",
+ "import java.util.List;\n" +
+ "public interface I3 extends I1, I2 {\n" +
+ " @Override\n" +
+ " String foo(List<String> l);\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in I3.java (at line 4)\n" +
+ " String foo(List<String> l);\n" +
+ " ^^^^^^^^^^^^^^^^^^^\n" +
+ "Name clash: The method foo(List<String>) of type I3 has the same erasure as foo(List) of type I2 but does not override it\n" +
+ "----------\n");
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
index 13f6920..575a113 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
@@ -1,12 +1,18 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 388800 - [1.8] adjust tests to 1.8 JRE
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -1101,6 +1107,7 @@
" public Iterator<String> iterator() {\n" +
" return null;\n" +
" }\n" +
+ ITERABLE_IMPL_JRE8.replaceAll("\\*", "String") +
"}\n",
},
"----------\n" +
@@ -1628,6 +1635,7 @@
" public Iterator<String> iterator() {\n" +
" return new ArrayIterator<String>(new String[]{\"a\",\"b\"});\n" +
" }\n" +
+ ITERABLE_IMPL_JRE8.replaceAll("\\*", "String") +
"}\n",
},
"ab");
@@ -1723,6 +1731,7 @@
" public Iterator<String> iterator() {\n" +
" return new ArrayIterator<String>(new String[]{\"a\",\"b\"});\n" +
" }\n" +
+ ITERABLE_IMPL_JRE8.replaceAll("\\*", "String") +
"}\n",
},
"ab");
@@ -1798,6 +1807,7 @@
" X x = new X();\n" +
" x.foo(x);\n" +
" }\n" +
+ ITERABLE_IMPL_JRE8.replaceAll("\\*", "String") +
"}",
},
"ab");
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 113e80c..45a1a80 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
@@ -13,6 +13,9 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Technical University Berlin - adapted for Object Teams
+ * Stephan Herrmann - Contribution for
+ * bug 383690 - [compiler] location of error re uninitialized final field should be aligned
+ * bug 388800 - [1.8] adjust tests to 1.8 JRE
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -4437,6 +4440,9 @@
" }\n" +
" public int size() { return 0; }\n" +
" public Object get(int index) { return null; }\n" +
+ ITERABLE_RAW_IMPL_JRE8 +
+ COLLECTION_RAW_IMPL_JRE8 +
+ LIST_RAW_IMPL_JRE8 +
"}\n"
},
"SUCCESS");
@@ -6146,6 +6152,7 @@
" public int compare(X x1, X x2) {\n" +
" return comparator.compare(function.eval(x1),function.eval(x2));\n" +
" }\n" +
+ COMPARATOR_RAW_IMPL_JRE8 +
"}\n",
},
"");
@@ -8846,6 +8853,8 @@
" public Set<Map.Entry<String, V>> entrySet() {\n" +
" return this.backingMap.entrySet();\n" +
" }\n" +
+ MAP_STREAM_IMPL_JRE8.replaceAll("\\*", "String").replace('%', 'V') +
+ MAP_IMPL_JRE8.replaceAll("!", "String,V").replaceAll("\\*", "String")+
"}\n",
},
"----------\n" +
@@ -10808,6 +10817,8 @@
" };\n" +
" }\n" +
" public int size() {return 0;}\n" +
+ COLLECTION_RAW_IMPL_JRE8 +
+ ITERABLE_IMPL_JRE8.replaceAll("\\*", "Entry<String,Integer>") +
"}"
}
);
@@ -11379,6 +11390,8 @@
" }\n" +
" public Iterator<Runnable> iterator() {return null;}\n" +
" public int size() {return 0;}\n" +
+ COLLECTION_RAW_IMPL_JRE8 +
+ ITERABLE_IMPL_JRE8.replaceAll("\\*", "Runnable") +
"}"
}
);
@@ -24905,6 +24918,9 @@
" List<String> list = new AbstractList<String>() {\n" +
" @Override public int size() { return 0; }\n" +
" @Override public String get(int i) { return args.get(i); }\n" +
+ COLLECTION_IMPL_JRE8.replaceAll("\\*", "String") +
+ ITERABLE_IMPL_JRE8.replaceAll("\\*", "String") +
+ LIST_IMPL_JRE8.replaceAll("\\*", "String") +
" };\n" +
" }\n" +
" }\n" +
@@ -24916,13 +24932,14 @@
},
"SUCCESS");
+ String constantPoolIdx = IS_JRE_8 ? "149" : "36"; // depends on whether or not stubs for JRE8 default methods are included
String expectedOutput =
" // Method descriptor #31 (I)Ljava/lang/Object;\n" +
" // Stack: 2, Locals: 2\n" +
" public bridge synthetic java.lang.Object get(int arg0);\n" +
" 0 aload_0 [this]\n" +
" 1 iload_1 [arg0]\n" +
- " 2 invokevirtual X$Entry$1.get(int) : java.lang.String [36]\n" +
+ " 2 invokevirtual X$Entry$1.get(int) : java.lang.String ["+constantPoolIdx+"]\n" +
" 5 areturn\n" +
" Line numbers:\n" +
" [pc: 0, line: 1]\n";
@@ -28024,6 +28041,8 @@
" // TODO Auto-generated method stub\n" +
" \n" +
" }" +
+ COLLECTION_RAW_IMPL_JRE8 +
+ ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 +
"}",
},
"",
@@ -34176,6 +34195,7 @@
" public Iterator<W> iterator() {\n" +
" return theList.iterator();\n" +
" }\n" +
+ ITERABLE_IMPL_JRE8.replace('*', 'W') +
" }\n" +
"\n" +
" private PointList<Waypoint> waypoints = new PointList<Waypoint>();\n" +
@@ -34420,6 +34440,7 @@
"public int compare(T obj1, T obj2) {\n" +
" return obj1.compareTo(obj2);\n" +
"}\n" +
+ COMPARATOR_IMPL_JRE8.replace('*', 'T') +
"}\n" +
"\n" +
"@SuppressWarnings({\"unchecked\", \"rawtypes\"})\n" +
@@ -34470,6 +34491,7 @@
"public int compare(V obj1, V obj2) {\n" +
" return 0;\n" +
"}\n" +
+ COMPARATOR_IMPL_JRE8.replace('*', 'V') +
"}", // =================
},
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest.java
index 7e127d4..85d3cdd 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest.java
@@ -1,12 +1,18 @@
/*******************************************************************************
- * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * Copyright (c) 2006, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 388800 - [1.8] adjust tests to 1.8 JRE
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -6854,6 +6860,7 @@
" compare(yourList != null ? yourList : myList, yourList);\n" +
" return 0;\n" +
" }\n" +
+ COMPARATOR_RAW_IMPL_JRE8 +
" };\n" +
" System.out.println(\"SUCCESS\");\n" +
" }\n" +
@@ -6884,6 +6891,7 @@
" private int foo(int i, int j) {\n" +
" return i - j;\n" +
" }\n" +
+ COMPARATOR_RAW_IMPL_JRE8 +
" };\n" +
" System.out.println(\"SUCCESS\");\n" +
" }\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java
index a53b3e5..53623c9 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java
@@ -1,13 +1,19 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for
+ * bug 185682 - Increment/decrement operators mark local variables as read
+ * bug 388800 - [1.8] adjust tests to 1.8 JRE
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -2561,6 +2567,9 @@
" public int size() {\n" +
" return 0;\n" +
" }\n" +
+ getListRawImplJRE8() +
+ getIterableRawImplJRE8() +
+ getCollectionRawImplJRE8() +
"}", // =================
},
"");
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 53f8c5b..7ae24f6 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
@@ -4,9 +4,15 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * bug 388800 - [1.8] adjust tests to 1.8 JRE
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -1811,8 +1817,11 @@
this.runConformTest(
new String[] {
"X.java",
+ "import java.util.*;\n" +
"public class X extends java.util.AbstractMap {\n" +
" public java.util.Set entrySet() { return null; }\n" +
+ MAP_RAW_IMPL_JRE8 +
+ MAP_STREAM_RAW_IMPL_JRE8 +
"}\n"
},
""
@@ -6873,6 +6882,9 @@
" public boolean hasNext() { return false; }\n" +
" public Object next() { return null; }\n" +
" public void remove() {}\n" +
+ ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 +
+ COLLECTION_RAW_IMPL_JRE8 +
+ LIST_RAW_IMPL_JRE8 +
"}\n", // =================
},
"----------\n" +
@@ -6993,6 +7005,9 @@
" public boolean hasNext() { return false; }\n" +
" public Object next() { return null; }\n" +
" public void remove() {}\n" +
+ ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 +
+ COLLECTION_RAW_IMPL_JRE8 +
+ LIST_RAW_IMPL_JRE8 +
"}\n", // =================
},
"----------\n" +
@@ -7103,6 +7118,9 @@
" public boolean hasNext() { return false; }\n" +
" public Object next() { return null; }\n" +
" public void remove() {}\n" +
+ ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 +
+ COLLECTION_RAW_IMPL_JRE8 +
+ LIST_RAW_IMPL_JRE8 +
"}\n", // =================
},
"----------\n" +
@@ -11388,6 +11406,7 @@
" return compare((I) o1, (I) o2);\n" +
" }\n" +
" public int compare(I o1, I o2) { return 0; }\n" +
+ COMPARATOR_RAW_IMPL_JRE8 +
"}"
},
""
@@ -12300,6 +12319,7 @@
" public int compare(Object o1, Object o2) {\n" +
" return 0;\n" +
" }\n" +
+ COMPARATOR_RAW_IMPL_JRE8 +
" };\n" +
" Test.assertEquals(\"Test\", comparator, new ArrayList(), new ArrayList());\n" +
" }\n" +
@@ -12370,6 +12390,7 @@
" public int compare(Object o1, Object o2) {\n" +
" return 0;\n" +
" }\n" +
+ COMPARATOR_RAW_IMPL_JRE8 +
" };\n" +
" Test.assertEquals(\"Test\", comparator, new ArrayList(), new ArrayList());\n" +
" }\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java
index b391857..d90340b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java
@@ -960,6 +960,47 @@
"The annotation @Marker is disallowed for this location\n" +
"----------\n");
}
+ // JSR 308: "It is not permitted to annotate the type name in an import statement."
+ public void test039() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import @Marker java.lang.String; // Compilation error \n" +
+ "public class X { \n" +
+ "}\n" +
+ "@interface Marker {}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 1)\n" +
+ " import @Marker java.lang.String; // Compilation error \n" +
+ " ^^^^^^\n" +
+ "Syntax error on token(s), misplaced construct(s)\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 1)\n" +
+ " import @Marker java.lang.String; // Compilation error \n" +
+ " ^^^^^^\n" +
+ "Syntax error on token \"Marker\", package expected after this token\n" +
+ "----------\n");
+ }
+ // Test that type name can't be left out in a cast expression with an annotations
+ public void test040() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X { \n" +
+ " public void foo(Object myObject) {\n" +
+ " String myString = (@NonNull) myObject;" +
+ " }\n" +
+ "}\n" +
+ "@interface NonNull {}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " String myString = (@NonNull) myObject; }\n" +
+ " ^^^^^^^\n" +
+ "Syntax error on token \"NonNull\", void expected after this token\n" +
+ "----------\n");
+ }
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=385111
// [1.8][compiler] Compiler fails to flag undefined annotation type.
public void test0385111() {
@@ -1082,9 +1123,9 @@
" InnerMost(Outer.Inner this) {}\n" +
" InnerMost(Outer.Inner Outer.Inner.this, int i, float f) {}\n" +
" InnerMost(Outer Outer.this, float f) {}\n" +
- " InnerMost(Outer.Inner<K,V>.InnerMost<T> Outer.Inner.InnerMost.this) {}\n" +
+ " InnerMost(Outer.Inner<K,V>.InnerMost<T> Outer.Inner.InnerMost.this, Object obj) {}\n" +
" InnerMost(Inner<K,V> Outer.Inner.InnerMost.this, int i) {}\n" +
- " InnerMost(Outer.Inner<K, V> this, float f) {}\n" +
+ " InnerMost(Outer.Inner<K, V> this, float f, int i) {}\n" +
" InnerMost(Outer.Inner<K,V> Inner.this, long l) {}\n" +
" }\n" +
" }\n" +
@@ -1136,12 +1177,12 @@
"The explicit 'this' parameter is expected to be qualified with Outer.Inner\n" +
"----------\n" +
"10. ERROR in Outer.java (at line 9)\n" +
- " InnerMost(Outer.Inner<K,V>.InnerMost<T> Outer.Inner.InnerMost.this) {}\n" +
+ " InnerMost(Outer.Inner<K,V>.InnerMost<T> Outer.Inner.InnerMost.this, Object obj) {}\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"The declared type of the explicit 'this' parameter is expected to be Outer.Inner<K,V>\n" +
"----------\n" +
"11. ERROR in Outer.java (at line 9)\n" +
- " InnerMost(Outer.Inner<K,V>.InnerMost<T> Outer.Inner.InnerMost.this) {}\n" +
+ " InnerMost(Outer.Inner<K,V>.InnerMost<T> Outer.Inner.InnerMost.this, Object obj) {}\n" +
" ^^^^\n" +
"The explicit 'this' parameter is expected to be qualified with Outer.Inner\n" +
"----------\n" +
@@ -1151,7 +1192,7 @@
"The explicit 'this' parameter is expected to be qualified with Outer.Inner\n" +
"----------\n" +
"13. ERROR in Outer.java (at line 11)\n" +
- " InnerMost(Outer.Inner<K, V> this, float f) {}\n" +
+ " InnerMost(Outer.Inner<K, V> this, float f, int i) {}\n" +
" ^^^^\n" +
"The explicit 'this' parameter is expected to be qualified with Outer.Inner\n" +
"----------\n");
@@ -1166,11 +1207,11 @@
" class InnerMost<T> {\n" +
" public void foo(Outer Outer.this) {}\n" +
" public void foo(Inner<K,V> Inner.this, int i) {}\n" +
- " public void foo(InnerMost this) {}\n" +
+ " public void foo(InnerMost this, int i, int j) {}\n" +
" public void foo(Inner.InnerMost<T> this, Object obj) {}\n" +
- " public void foo(InnerMost<T> this, int i) {}\n" +
+ " public void foo(InnerMost<T> this, float f) {}\n" +
" public void foo(Inner<K,V>.InnerMost<T> this, long l) {}\n" +
- " public void foo(Outer.Inner<K,V>.InnerMost<T> this, float f) {}\n" +
+ " public void foo(Outer.Inner<K,V>.InnerMost<T> this, float f, float ff) {}\n" +
" public void foo(InnerMost<T> Outer.Inner.InnerMost.this, int i, float f) {}\n" +
" }\n" +
" }\n" +
@@ -1197,12 +1238,12 @@
"The explicit 'this' parameter is expected to be qualified with Outer.Inner.InnerMost\n" +
"----------\n" +
"5. WARNING in Outer.java (at line 6)\n" +
- " public void foo(InnerMost this) {}\n" +
+ " public void foo(InnerMost this, int i, int j) {}\n" +
" ^^^^^^^^^\n" +
"Outer.Inner.InnerMost is a raw type. References to generic type Outer.Inner<K,V>.InnerMost<T> should be parameterized\n" +
"----------\n" +
"6. ERROR in Outer.java (at line 6)\n" +
- " public void foo(InnerMost this) {}\n" +
+ " public void foo(InnerMost this, int i, int j) {}\n" +
" ^^^^^^^^^\n" +
"The declared type of the explicit 'this' parameter is expected to be Outer.Inner<K,V>.InnerMost<T>\n" +
"----------\n" +
@@ -1222,6 +1263,8 @@
this.runNegativeTest(
new String[] {
"Outer.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
"public class Outer {\n" +
" class Inner<K,V> {\n" +
" public Inner(@Missing Outer Outer.this) {}\n" +
@@ -1233,7 +1276,7 @@
" }\n" +
" void bar(int i) {\n" +
" class Local {\n" +
- " public int hashCode(Local this) { return 0; }\n" +
+ " public int hashCode(Local this, int k) { return 0; }\n" +
" public int hashCode(Outer.Local this) { return 0; }\n" +
" }\n" +
" }\n" +
@@ -1248,37 +1291,78 @@
"interface AnonymousInner {\n" +
" public void foobar(AnonymousInner this);\n" +
"}\n" +
+ "@Target(TYPE_USE)\n" +
"@interface Marker {}"},
"----------\n" +
- "1. ERROR in Outer.java (at line 3)\n" +
+ "1. ERROR in Outer.java (at line 5)\n" +
" public Inner(@Missing Outer Outer.this) {}\n" +
" ^^^^^^^\n" +
"Missing cannot be resolved to a type\n" +
"----------\n" +
- "2. ERROR in Outer.java (at line 7)\n" +
+ "2. ERROR in Outer.java (at line 9)\n" +
" public void foobar(AnonymousInner this) {}\n" +
" ^^^^\n" +
- "Explicit 'this' parameter is allowed only in instance methods of non-anonymous classes and inner class constructors\n" +
+ "Explicit \'this\' parameter is allowed only in instance methods of non-anonymous classes and inner class constructors\n" +
"----------\n" +
- "3. ERROR in Outer.java (at line 13)\n" +
+ "3. ERROR in Outer.java (at line 15)\n" +
" public int hashCode(Outer.Local this) { return 0; }\n" +
" ^^^^^^^^^^^\n" +
"Outer.Local cannot be resolved to a type\n" +
"----------\n" +
- "4. ERROR in Outer.java (at line 19)\n" +
+ "4. ERROR in Outer.java (at line 21)\n" +
" public StaticNested(@Marker Outer.StaticNested Outer.StaticNested.this) {}\n" +
- " ^^^^\n" +
- "Explicit 'this' parameter is allowed only in instance methods of non-anonymous classes and inner class constructors\n" +
+ " ^^^^^^^\n" +
+ "The annotation @Marker is disallowed for this location\n" +
"----------\n" +
"5. ERROR in Outer.java (at line 21)\n" +
+ " public StaticNested(@Marker Outer.StaticNested Outer.StaticNested.this) {}\n" +
+ " ^^^^\n" +
+ "Explicit \'this\' parameter is allowed only in instance methods of non-anonymous classes and inner class constructors\n" +
+ "----------\n" +
+ "6. ERROR in Outer.java (at line 23)\n" +
+ " public static void foo(@Marker Outer this) {}\n" +
+ " ^^^^^^^\n" +
+ "The annotation @Marker is disallowed for this location\n" +
+ "----------\n" +
+ "7. ERROR in Outer.java (at line 23)\n" +
" public static void foo(@Marker Outer this) {}\n" +
" ^^^^\n" +
- "Explicit 'this' parameter is allowed only in instance methods of non-anonymous classes and inner class constructors\n" +
+ "Explicit \'this\' parameter is allowed only in instance methods of non-anonymous classes and inner class constructors\n" +
"----------\n" +
- "6. ERROR in Outer.java (at line 22)\n" +
+ "8. ERROR in Outer.java (at line 24)\n" +
" public void foo(@Missing Outer this, int i) {}\n" +
" ^^^^^^^\n" +
"Missing cannot be resolved to a type\n" +
+ "----------\n" +
+ "9. ERROR in Outer.java (at line 29)\n" +
+ " @Target(TYPE_USE)\n" +
+ " ^^^^^^^^\n" +
+ "TYPE_USE cannot be resolved to a variable\n" +
"----------\n");
}
+ public void test0383908() {
+ this.runNegativeTest(
+ new String[]{"X.java",
+ "public class X { \n" +
+ " void foo(X this) {}\n" +
+ " void foo() {}\n" +
+ "}\n" +
+ "class Y {\n" +
+ " void foo(Y this) {}\n" +
+ " public static void main(String[] args) {\n" +
+ " new Y().foo();\n" +
+ " }\n" +
+ "}"},
+ "----------\n" +
+ "1. ERROR in X.java (at line 2)\n" +
+ " void foo(X this) {}\n" +
+ " ^^^^^^^^^^^\n" +
+ "Duplicate method foo() in type X\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 3)\n" +
+ " void foo() {}\n" +
+ " ^^^^^\n" +
+ "Duplicate method foo() in type X\n" +
+ "----------\n");
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
index aa95982..567be93 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
@@ -4,9 +4,15 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * bug 388800 - [1.8] adjust tests to 1.8 JRE
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -1773,6 +1779,7 @@
" public Iterator<Value_Type> iterator() {\n" +
" return null;\n" +
" }\n" +
+ ITERABLE_IMPL_JRE8.replaceAll("\\*", "Value_Type") +
"}\n" +
"\n" +
"class BirBlock {\n" +
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java
index 316b1c7..f397671 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java
@@ -4464,4 +4464,33 @@
// Should have same types with these 2 searches
assertEquals("Found types sounds not to be correct", requestor.toString(), collector.toString());
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=383908
+public void testBug383908() throws CoreException {
+ try {
+ String fileContent = "package p;\n" +
+ "public class X {\n" +
+ " public void foobar(X this, String str) {\n" +
+ " }\n" +
+ "}";
+ createJavaProject("P", new String[] {"src"}, new String[0], "bin");
+ createFolder("/P/src/p");
+ createFile("/P/src/p/X.java", fileContent);
+
+ IType type = getCompilationUnit("P", "src", "p", "X.java").getType("X");
+ IMethod[] methods = type.getMethods();
+ search(
+ methods[0],
+ DECLARATIONS,
+ SearchEngine.createJavaSearchScope(new IJavaElement[] {type}),
+ this.resultCollector);
+
+ assertSearchResults(
+ "src/p/X.java void p.X.foobar(String) [foobar]",
+ this.resultCollector);
+
+ } finally {
+ deleteProject("P");
+ }
+}
+
}
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 a80db15..ee241db 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
@@ -156,6 +156,7 @@
* UninitializedBlankFinalFieldHintMissingDefault
* ShouldReturnValueHintMissingDefault
* IllegalModifierForInterfaceDefaultMethod
+ * InheritedDefaultMethodConflictsWithOtherInherited
*******************************************************************************/
package org.eclipse.jdt.core.compiler;
@@ -1552,6 +1553,12 @@
/** @since 3.9 */
int IllegalModifierForInterfaceDefaultMethod = MethodRelated + 1050;
+ /** @since 3.9 */
+ int DefaultMethodOverridesObjectMethod = MethodRelated + 1051;
+
+ /** @since 3.9 */
+ int InheritedDefaultMethodConflictsWithOtherInherited = MethodRelated + 1052;
+
/**
* External problems -- These are problems defined by other plugins
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index a0b2882..8ea9695 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -187,6 +187,7 @@
public int modifiersSourceStart;
public Annotation[] annotations;
// jsr 308
+ public Receiver receiver;
public Annotation[] receiverAnnotations;
public Argument[] arguments;
public TypeReference[] thrownExceptions;
@@ -699,6 +700,9 @@
}
printReturnType(0, output).append(this.selector).append('(');
+ if (this.receiver != null) {
+ this.receiver.print(0, output);
+ }
if (this.arguments != null) {
//{ObjectTeams: retrench enhanced callin args:
int firstArg = 0;
@@ -709,7 +713,7 @@
for (int i = 0; i < this.arguments.length; i++) {
:giro */
// SH}
- if (i > 0) output.append(", "); //$NON-NLS-1$
+ if (i > 0 || this.receiver != null) output.append(", "); //$NON-NLS-1$
this.arguments[i].print(0, output);
}
}
@@ -794,40 +798,37 @@
}
public void resolveReceiver() {
- if (this.arguments != null && this.arguments.length > 0) {
- if (this.arguments[0].isReceiver()) {
- Receiver receiver = (Receiver) this.arguments[0];
+ if (this.receiver == null) return;
- TypeBinding resolvedReceiverType = receiver.type.resolvedType;
- if (this.binding == null || resolvedReceiverType == null || !resolvedReceiverType.isValidBinding())
- return;
+ TypeBinding resolvedReceiverType = this.receiver.type.resolvedType;
+ if (this.binding == null || resolvedReceiverType == null || !resolvedReceiverType.isValidBinding()) {
+ return;
+ }
- ReferenceBinding declaringClass = this.binding.declaringClass;
- /* neither static methods nor methods in anonymous types can have explicit 'this' */
- if (this.isStatic() || declaringClass.isAnonymousType()) {
- this.scope.problemReporter().disallowedThisParameter(receiver);
- return; // No need to do further validation
- }
+ ReferenceBinding declaringClass = this.binding.declaringClass;
+ /* neither static methods nor methods in anonymous types can have explicit 'this' */
+ if (this.isStatic() || declaringClass.isAnonymousType()) {
+ this.scope.problemReporter().disallowedThisParameter(this.receiver);
+ return; // No need to do further validation
+ }
- ReferenceBinding enclosingReceiver = this.scope.enclosingReceiverType();
- if (this.isConstructor()) {
- /* Only non static member types or local types can declare explicit 'this' params in constructors */
- if (declaringClass.isStatic()
- || (declaringClass.tagBits & (TagBits.IsLocalType | TagBits.IsMemberType)) == 0) { /* neither member nor local type */
- this.scope.problemReporter().disallowedThisParameter(receiver);
- return; // No need to do further validation
- }
- enclosingReceiver = enclosingReceiver.enclosingType();
- }
-
- if (enclosingReceiver != resolvedReceiverType) {
- this.scope.problemReporter().illegalTypeForExplicitThis(receiver, enclosingReceiver);
- }
-
- if ((receiver.qualifyingName == null) ? this.isConstructor() : !isQualifierValidForType(receiver.qualifyingName.getName(), enclosingReceiver)) {
- this.scope.problemReporter().illegalQualifierForExplicitThis(receiver, enclosingReceiver);
- }
+ ReferenceBinding enclosingReceiver = this.scope.enclosingReceiverType();
+ if (this.isConstructor()) {
+ /* Only non static member types or local types can declare explicit 'this' params in constructors */
+ if (declaringClass.isStatic()
+ || (declaringClass.tagBits & (TagBits.IsLocalType | TagBits.IsMemberType)) == 0) { /* neither member nor local type */
+ this.scope.problemReporter().disallowedThisParameter(this.receiver);
+ return; // No need to do further validation
}
+ enclosingReceiver = enclosingReceiver.enclosingType();
+ }
+
+ if (enclosingReceiver != resolvedReceiverType) {
+ this.scope.problemReporter().illegalTypeForExplicitThis(this.receiver, enclosingReceiver);
+ }
+
+ if ((this.receiver.qualifyingName == null) ? this.isConstructor() : !isQualifierValidForType(this.receiver.qualifyingName.getName(), enclosingReceiver)) {
+ this.scope.problemReporter().illegalQualifierForExplicitThis(this.receiver, enclosingReceiver);
}
}
private boolean isQualifierValidForType(char[][] tokens, TypeBinding enclosingType) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index 2e10aa9..da3ad1a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -4,6 +4,10 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
@@ -16,6 +20,7 @@
* bug 365387 - [compiler][null] bug 186342: Issues to follow up post review and verification.
* bug 358903 - Filter practically unimportant resource leak warnings
* bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ * bug 388800 - [1.8][compiler] detect default methods in class files
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -686,6 +691,13 @@
int methodModifiers = method.getModifiers() | ExtraCompilerModifiers.AccUnresolved;
if (sourceLevel < ClassFileConstants.JDK1_5)
methodModifiers &= ~ClassFileConstants.AccVarargs; // vararg methods are not recognized until 1.5
+ if (isInterface() && (methodModifiers & ClassFileConstants.AccAbstract) == 0) {
+ // see https://bugs.eclipse.org/388954
+ if (sourceLevel >= ClassFileConstants.JDK1_8)
+ methodModifiers |= ExtraCompilerModifiers.AccDefaultMethod;
+ else
+ methodModifiers |= ClassFileConstants.AccAbstract;
+ }
ReferenceBinding[] exceptions = Binding.NO_EXCEPTIONS;
TypeBinding[] parameters = Binding.NO_PARAMETERS;
TypeVariableBinding[] typeVars = Binding.NO_TYPE_VARIABLES;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
index a4c1c30..48a4c89 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
@@ -95,6 +95,7 @@
public char[] selector;
public TypeBinding returnType;
public TypeBinding[] parameters;
+ public TypeBinding receiver; // JSR308 - explicit this parameter
public ReferenceBinding[] thrownExceptions;
public ReferenceBinding declaringClass;
public TypeVariableBinding[] typeVariables = Binding.NO_TYPE_VARIABLES;
@@ -1128,6 +1129,11 @@
return (this.modifiers & ExtraCompilerModifiers.AccDefaultAbstract) != 0;
}
+/* Answer true if the receiver is a default method (Java 8 feature) */
+public boolean isDefaultMethod() {
+ return (this.modifiers & ExtraCompilerModifiers.AccDefaultMethod) != 0;
+}
+
/* Answer true if the receiver is a deprecated method
*/
public final boolean isDeprecated() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
index b771982..fc0a736 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
@@ -220,11 +220,12 @@
if (declaringClass.isRegularInterface()) {
// SH}
int expectedModifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract;
- // 9.4 got updated for JSR 335 (default methods):
- boolean isDefaultMethod = (modifiers & ExtraCompilerModifiers.AccDefaultMethod) != 0; // no need to check validity, is done by the parser
- if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8 && isDefaultMethod) {
+ // 9.4 got updated for JSR 335 (default methods), more permissive grammar plus:
+ // "It is a compile-time error if an abstract method declaration contains either of the keywords strictfp or synchronized."
+ if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8 && !methodBinding.isAbstract()) {
expectedModifiers |= (ClassFileConstants.AccSynchronized | ClassFileConstants.AccStrictfp);
}
+ boolean isDefaultMethod = (modifiers & ExtraCompilerModifiers.AccDefaultMethod) != 0; // no need to check validity, is done by the parser
if ((realModifiers & ~expectedModifiers) != 0) {
if ((declaringClass.modifiers & ClassFileConstants.AccAnnotation) != 0)
problemReporter().illegalModifierForAnnotationMember((AbstractMethodDeclaration) this.referenceContext);
@@ -451,27 +452,24 @@
if (argument.isVarArgs() && sourceLevel >= ClassFileConstants.JDK1_5)
method.binding.modifiers |= ClassFileConstants.AccVarargs;
if (CharOperation.equals(argument.name, ConstantPool.This)) {
- if (argLength != 0 || sourceLevel <= ClassFileConstants.JDK1_7) {
- problemReporter().illegalThis(argument, method, sourceLevel);
- }
- if (argument.annotations != null) {
- method.receiverAnnotations = argument.annotations;
- method.bits |= ASTNode.HasTypeAnnotations;
- }
+ problemReporter().illegalThisDeclaration(argument);
}
while (--argLength >= 0) {
argument = argTypes[argLength];
if (argument.isVarArgs() && sourceLevel >= ClassFileConstants.JDK1_5)
problemReporter().illegalVararg(argument, method);
if (CharOperation.equals(argument.name, ConstantPool.This)) {
- if (argLength != 0 || sourceLevel <= ClassFileConstants.JDK1_7) {
- problemReporter().illegalThis(argument, method, sourceLevel);
- }
- if (argument.annotations != null) {
- method.receiverAnnotations = argument.annotations;
- method.bits |= ASTNode.HasTypeAnnotations;
- }
- }
+ problemReporter().illegalThisDeclaration(argument);
+ }
+ }
+ }
+ if (method.receiver != null) {
+ if (sourceLevel <= ClassFileConstants.JDK1_7) {
+ problemReporter().illegalSourceLevelForThis(method.receiver);
+ }
+ if (method.receiver.annotations != null) {
+ method.receiverAnnotations = method.receiver.annotations;
+ method.bits |= ASTNode.HasTypeAnnotations;
}
}
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 3bdb27c..ec3ded4 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,16 +1,22 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- * $Id: MethodVerifier.java 23405 2010-02-03 17:02:18Z stephan $
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
* Benjamin Muskalla - Contribution for bug 239066
* Fraunhofer FIRST - extended API and implementation
* Technical University Berlin - extended API and implementation
+ * Stephan Herrmann - Contribution for
+ * bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
+ * bug 388954 - [1.8][compiler] detect default methods in class files
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -267,7 +273,21 @@
// currentMethod.modifiers |= CompilerModifiers.AccImplementing;
} else if (inheritedMethod.isPublic() || !this.type.isInterface()) {
// interface I { @Override Object clone(); } does not override Object#clone()
- currentMethod.modifiers |= ExtraCompilerModifiers.AccOverriding;
+ if (currentMethod.isDefaultMethod()
+ && !inheritedMethod.isFinal() // overriding final is already reported, that's enough
+ && inheritedMethod.declaringClass.id == TypeIds.T_JavaLangObject)
+ {
+ // JLS 9.4.3 (Java8): default method cannot override method from j.l.Object
+ problemReporter(currentMethod).defaultMethodOverridesObjectMethod(currentMethod);
+ } else {
+ // TODO (stephan) using AccImplementing for overrides of a default method works well
+ // for OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation
+ // but we should check if it has bad side effects elsewhere.
+ if (inheritedMethod.isDefaultMethod())
+ currentMethod.modifiers |= ExtraCompilerModifiers.AccImplementing;
+ else
+ currentMethod.modifiers |= ExtraCompilerModifiers.AccOverriding;
+ }
}
if (!areReturnTypesCompatible(currentMethod, inheritedMethod)
@@ -611,6 +631,8 @@
}
} else if (noMatch) {
problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length);
+ } else if (this.environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
+ checkInheritedDefaultMethods(methods, length);
}
return;
}
@@ -638,7 +660,21 @@
System.arraycopy(abstractMethods, 0, abstractMethods = new MethodBinding[index], 0, index);
checkConcreteInheritedMethod(concreteMethod, abstractMethods);
}
-
+private void checkInheritedDefaultMethods(MethodBinding[] methods, int length) {
+ // JSL 9.4.1 (Java 8): default method clashes with other inherited method which is override-equivalent
+ if (length < 2) return;
+ findDefaultMethod: for (int i=0; i<length; i++) {
+ if (methods[i].isDefaultMethod()) {
+ findEquivalent: for (int j=0; j<length; j++) {
+ if (j == i) continue findEquivalent;
+ if (isMethodSubsignature(methods[i], methods[j])) {
+ problemReporter().inheritedDefaultMethodConflictsWithOtherInherited(this.type, methods[i], methods[j]);
+ continue findDefaultMethod;
+ }
+ }
+ }
+ }
+}
boolean checkInheritedReturnTypes(MethodBinding method, MethodBinding otherMethod) {
if (areReturnTypesCompatible(method, otherMethod)) return true;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 9fa5312..e206428 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -2125,6 +2125,10 @@
if (count < size)
System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions = new ReferenceBinding[count], 0, count);
}
+
+ if (methodDecl.receiver != null) {
+ method.receiver = methodDecl.receiver.type.resolveType(methodDecl.scope, true /* check bounds*/);
+ }
final boolean reportUnavoidableGenericTypeProblems = this.scope.compilerOptions().reportUnavoidableGenericTypeProblems;
boolean foundArgProblem = false;
Argument[] arguments = methodDecl.arguments;
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 0a43e78..ee9bc7f 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
@@ -6204,12 +6204,25 @@
md.sourceEnd = this.rParenPos;
//arguments
if (length != 0) {
- System.arraycopy(
- this.astStack,
- this.astPtr + 1,
- md.arguments = new Argument[length],
- 0,
- length);
+ Argument arg = (Argument) this.astStack[this.astPtr + 1];
+ if (arg.isReceiver()) {
+ md.receiver = (Receiver) arg;
+ if (length > 1) {
+ System.arraycopy(
+ this.astStack,
+ this.astPtr + 2,
+ md.arguments = new Argument[length - 1],
+ 0,
+ length - 1);
+ }
+ } else {
+ System.arraycopy(
+ this.astStack,
+ this.astPtr + 1,
+ md.arguments = new Argument[length],
+ 0,
+ length);
+ }
}
//{ObjectTeams: enhance callin method:
if (md.isCallin()) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 388052f..e27211e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -25,6 +25,7 @@
* bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
* bug 374605 - Unreasonable warning for enum-based switch statements
* bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
+ * bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.problem;
@@ -1651,6 +1652,21 @@
0,
0);
}
+public void defaultMethodOverridesObjectMethod(MethodBinding currentMethod) {
+ // Java 8 feature
+ AbstractMethodDeclaration method = currentMethod.sourceMethod();
+ int sourceStart = 0;
+ int sourceEnd = 0;
+ if (method != null) {
+ sourceStart = method.sourceStart;
+ sourceEnd = method.sourceEnd;
+ }
+ this.handle(
+ IProblem.DefaultMethodOverridesObjectMethod,
+ NoArgument, NoArgument,
+ sourceStart, sourceEnd);
+}
+
public void deprecatedField(FieldBinding field, ASTNode location) {
int severity = computeSeverity(IProblem.UsingDeprecatedField);
if (severity == ProblemSeverities.Ignore) return;
@@ -2953,10 +2969,19 @@
argType.sourceStart,
argType.sourceEnd);
}
-public void illegalThis(Argument argument, AbstractMethodDeclaration method, long sourceLevel) {
+public void illegalThisDeclaration(Argument argument) {
String[] arguments = NoArgument;
this.handle(
- sourceLevel <= ClassFileConstants.JDK1_7 ? IProblem.ExplicitThisParameterNotBelow18 : IProblem.IllegalDeclarationOfThisParameter,
+ IProblem.IllegalDeclarationOfThisParameter,
+ arguments,
+ arguments,
+ argument.sourceStart,
+ argument.sourceEnd);
+}
+public void illegalSourceLevelForThis(Argument argument) {
+ String[] arguments = NoArgument;
+ this.handle(
+ IProblem.ExplicitThisParameterNotBelow18,
arguments,
arguments,
argument.sourceStart,
@@ -3372,6 +3397,22 @@
location.sourceStart,
location.sourceEnd);
}
+public void inheritedDefaultMethodConflictsWithOtherInherited(SourceTypeBinding type, MethodBinding defaultMethod, MethodBinding otherMethod) {
+ TypeDeclaration typeDecl = type.scope.referenceContext;
+ String[] problemArguments = new String[] {
+ String.valueOf(defaultMethod.readableName()),
+ String.valueOf(defaultMethod.declaringClass.readableName()),
+ String.valueOf(otherMethod.declaringClass.readableName()) };
+ String[] messageArguments = new String[] {
+ String.valueOf(defaultMethod.shortReadableName()),
+ String.valueOf(defaultMethod.declaringClass.shortReadableName()),
+ String.valueOf(otherMethod.declaringClass.shortReadableName()) };
+ this.handle(IProblem.InheritedDefaultMethodConflictsWithOtherInherited,
+ problemArguments,
+ messageArguments,
+ typeDecl.sourceStart,
+ typeDecl.sourceEnd);
+}
private void inheritedMethodReducesVisibility(int sourceStart, int sourceEnd, MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
StringBuffer concreteSignature = new StringBuffer();
concreteSignature
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index 01e504d..d9ba1ea 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -24,6 +24,7 @@
# bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
# bug 374605 - Unreasonable warning for enum-based switch statements
# bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
+# bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
###############################################################################
0 = {0}
1 = super cannot be used in java.lang.Object
@@ -720,7 +721,8 @@
# Default methods:
# variant of 359:
1050 = Illegal modifier for the interface method {0}; only public, abstract, strictfp & synchronized are permitted
-
+1051 = A default method cannot override a method from java.lang.Object
+1052 = The default method {0} inherited from {1} conflicts with another method inherited from {2}
### ELABORATIONS
## Access restrictions