diff options
author | Stephan Herrmann | 2013-05-01 18:08:26 +0000 |
---|---|---|
committer | Stephan Herrmann | 2013-05-01 19:49:15 +0000 |
commit | 63010decdc2159ffc02f4c5de41c7013312d0748 (patch) | |
tree | 52034f5d1c2b997232b7ba03fe281b028a01267c | |
parent | 0b62c4ba651c88b312a6ac404a598938ab9d8927 (diff) | |
download | org.eclipse.objectteams-63010decdc2159ffc02f4c5de41c7013312d0748.tar.gz org.eclipse.objectteams-63010decdc2159ffc02f4c5de41c7013312d0748.tar.xz org.eclipse.objectteams-63010decdc2159ffc02f4c5de41c7013312d0748.zip |
Update jdt.core and tests to 5138a70372af4817aefdd3da44dfadf7f7557bf3
+ plus some merge-related fixes
85 files changed, 4846 insertions, 1568 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TypeAnnotationSyntaxTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TypeAnnotationSyntaxTest.java index fa545bb2f..d93fe2142 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TypeAnnotationSyntaxTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TypeAnnotationSyntaxTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2012 IBM Corporation and others. + * Copyright (c) 2009, 2013 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 @@ -3790,4 +3790,48 @@ public void test0137() throws IOException { "}\n"; checkParse(CHECK_PARSER, source.toCharArray(), null, "test0137", expectedUnitToString); } +public void test0138() throws IOException { + String source = + "import java.lang.annotation.Target;\n" + + "import static java.lang.annotation.ElementType.*;\n" + + "public class X {\n" + + " public void foo() {\n" + + " int @Marker [][][] i = new @Marker2 int @Marker @Marker2 [2] @Marker @Marker2 [bar()] @Marker @Marker2 [];\n" + + " int @Marker [][][] j = new @Marker2 int @Marker @Marker2 [2] @Marker @Marker2 [X.bar2(2)] @Marker @Marker2 [];\n" + + " }\n" + + " public int bar() {\n" + + " return 2;\n" + + " }\n" + + " public static int bar2(int k) {\n" + + " return k;\n" + + " }\n" + + "}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker {}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker2 {}\n"; + String expectedUnitToString = + "import java.lang.annotation.Target;\n" + + "import static java.lang.annotation.ElementType.*;\n" + + "public class X {\n" + + " public X() {\n" + + " super();\n" + + " }\n" + + " public void foo() {\n" + + " int @Marker [][][] i = new @Marker2 int @Marker @Marker2 [2] @Marker @Marker2 [bar()] @Marker @Marker2 [];\n" + + " int @Marker [][][] j = new @Marker2 int @Marker @Marker2 [2] @Marker @Marker2 [X.bar2(2)] @Marker @Marker2 [];\n" + + " }\n" + + " public int bar() {\n" + + " return 2;\n" + + " }\n" + + " public static int bar2(int k) {\n" + + " return k;\n" + + " }\n" + + "}\n" + + "@Target(java.lang.annotation.ElementType.TYPE_USE) @interface Marker {\n" + + "}\n" + + "@Target(java.lang.annotation.ElementType.TYPE_USE) @interface Marker2 {\n" + + "}\n"; + checkParse(CHECK_PARSER, source.toCharArray(), null, "test0137", expectedUnitToString); +} } 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 138c8fa91..dfccffd46 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -82,156 +82,75 @@ public abstract class AbstractRegressionTest extends AbstractCompilerTest implem 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 ITERATOR_IMPL_JRE8; + static final String ITERATOR_RAW_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_IMPL_JRE8 = // replace '*' with T, '%' with U + " public java.util.Comparator<*> reverseOrder() { return null;}\n" + + " public java.util.Comparator<*> thenComparing(java.util.Comparator<? super *> other) { return null;}\n" + + " public <% extends java.lang.Comparable<? super %>> java.util.Comparator<*> thenComparing(java.util.function.Function<? super *, ? extends %> keyExtractor) { return null;}\n" + + " public java.util.Comparator<*> thenComparing(java.util.function.IntFunction<? super *> keyExtractor) { return null;}\n" + + " public java.util.Comparator<*> thenComparing(java.util.function.LongFunction<? super *> keyExtractor) { return null;}\n" + + " public java.util.Comparator<*> thenComparing(java.util.function.DoubleFunction<? super *> keyExtractor) { 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"; + " public java.util.Comparator reverseOrder() { return null;}\n" + + " public java.util.Comparator thenComparing(java.util.Comparator other) { return null;}\n" + + " public java.util.Comparator thenComparing(java.util.function.Function keyExtractor) { return null;}\n" + + " public java.util.Comparator thenComparing(java.util.function.IntFunction keyExtractor) { return null;}\n" + + " public java.util.Comparator thenComparing(java.util.function.LongFunction keyExtractor) { return null;}\n" + + " public java.util.Comparator thenComparing(java.util.function.DoubleFunction keyExtractor) { 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"; + " public boolean removeAll(java.util.function.Predicate<? super *> filter) { return false;}\n" + + " public java.util.stream.Stream<*> stream() { return null;}\n" + + " public java.util.stream.Stream<*> parallelStream() { return null;}\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"; + " public @SuppressWarnings(\"rawtypes\") boolean removeAll(java.util.function.Predicate filter) { return false;}\n" + + " public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream stream() { return null;}\n" + + " public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream parallelStream() { return null;}\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"; + " public void sort(java.util.Comparator<? super *> comparator) {}\n" + + " public void parallelSort(java.util.Comparator<? super *> comparator) {}\n" + + " public void replaceAll(java.util.function.UnaryOperator<*> operator) {}\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"; + " public @SuppressWarnings(\"rawtypes\") void parallelSort(java.util.Comparator comparator) {}\n" + + " public @SuppressWarnings(\"rawtypes\") void replaceAll(java.util.function.UnaryOperator operator) {}\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"; + " public void forEach(java.util.function.Block<? super *> block){}\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"; + " public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.Block block) {}\n"; + ITERATOR_IMPL_JRE8 = // replace '*' with your concrete type argument + " public void forEach(java.util.function.Block<? super *> block){}\n"; + ITERATOR_RAW_IMPL_JRE8 = + " public void forEach(java.util.function.Block block){}\n"; + MAP_IMPL_JRE8 = // '*' for 'K', '%' for 'V' + " public boolean remove(Object key, Object value) { return false;}\n" + + " public void forEach(java.util.function.BiBlock<? super *, ? super %> block) {}\n" + + " public void replaceAll(java.util.function.BiFunction<*, %, %> function) {}\n" + + " public % putIfAbsent(* key, % value) { return null;}\n" + + " public boolean replace(* key, % oldValue, % newValue) { return false;}\n" + + " public % replace(* key, % value) { return null;}\n" + + " public % computeIfAbsent(* key, java.util.function.Function<? super *, ? extends %> mappingFunction) { return null;}\n" + + " public % computeIfPresent(* key, java.util.function.BiFunction<? super *, ? super %, ? extends %> remappingFunction) { return null;}\n" + + " public % compute(* key, java.util.function.BiFunction<? super *, ? super %, ? extends %> remappingFunction) { return null;}\n" + + " public % merge(* key, % value, java.util.function.BiFunction<? super %, ? super %, ? extends %> remappingFunction) { 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"; + " public boolean remove(Object key, Object value) { return false;}\n" + + " public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.BiBlock block) {}\n" + + " public @SuppressWarnings(\"rawtypes\") void replaceAll(java.util.function.BiFunction function) {}\n" + + " public Object putIfAbsent(Object key, Object value) { return null;}\n" + + " public boolean replace(Object key, Object oldValue, Object newValue) { return false;}\n" + + " public Object replace(Object key, Object value) { return null;}\n" + + " public @SuppressWarnings(\"rawtypes\") Object computeIfAbsent(Object key, java.util.function.Function mappingFunction) { return null;}\n" + + " public @SuppressWarnings(\"rawtypes\") Object computeIfPresent(Object key, java.util.function.BiFunction remappingFunction) { return null;}\n" + + " public @SuppressWarnings(\"rawtypes\") Object compute(Object key, java.util.function.BiFunction remappingFunction) { return null;}\n" + + " public @SuppressWarnings(\"rawtypes\") Object merge(Object key, Object value, java.util.function.BiFunction remappingFunction) { return null;}\n"; } else { COMPARATOR_IMPL_JRE8 = ""; COMPARATOR_RAW_IMPL_JRE8 = ""; @@ -241,11 +160,10 @@ public abstract class AbstractRegressionTest extends AbstractCompilerTest implem LIST_RAW_IMPL_JRE8 = ""; ITERABLE_IMPL_JRE8 = ""; ITERABLE_RAW_IMPL_JRE8 = ""; - ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 = ""; + ITERATOR_IMPL_JRE8 = "\n"; + ITERATOR_RAW_IMPL_JRE8 = "\n"; MAP_IMPL_JRE8 = ""; MAP_RAW_IMPL_JRE8 = ""; - MAP_STREAM_IMPL_JRE8 = ""; - MAP_STREAM_RAW_IMPL_JRE8 = ""; } } String getListRawImplJRE8() { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java index 0c6446f88..d2c356a71 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java @@ -1,12 +1,18 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 388739 - [1.8][compiler] consider default methods when detecting whether a class needs to be declared abstract *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -115,7 +121,7 @@ public class AmbiguousMethodTest extends AbstractComparableTest { "1. ERROR in X.java (at line 4)\n" + " static interface I3<E3, E4> extends I1<E3>, I2<E4> {}\n" + " ^^\n" + - "Name clash: The method method(E1) of type X.I1<E1> has the same erasure as method(E2) of type X.I2<E2> but does not override it\n" + + "Name clash: The method method(E2) of type X.I2<E2> has the same erasure as method(E1) of type X.I1<E1> but does not override it\n" + "----------\n"); } } @@ -492,7 +498,7 @@ sure, yet neither overrides the other ); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=123943 - case 2 - public void test009() { + public void _test009() { this.runConformTest( new String[] { "T.java", @@ -2485,7 +2491,7 @@ public void test047() { "1. ERROR in X.java (at line 1)\n" + " public class X<T extends I & J> {\n" + " ^\n" + - "The return types are incompatible for the inherited methods J.method(), I.method()\n" + + "The return types are incompatible for the inherited methods I.method(), J.method()\n" + "----------\n", // javac options JavacTestOptions.JavacHasABug.JavacBug5061359 /* javac test options */); @@ -2517,7 +2523,7 @@ public void test048() { "1. ERROR in X.java (at line 1)\n" + " public class X<T extends I & J> {\n" + " ^\n" + - "The return types are incompatible for the inherited methods J.method(), I.method()\n" + + "The return types are incompatible for the inherited methods I.method(), J.method()\n" + "----------\n" + "2. ERROR in X.java (at line 3)\n" + " t.method();\n" + @@ -3176,12 +3182,12 @@ public void test070() { "1. ERROR in X.java (at line 3)\n" + " interface C extends B, A {}\n" + " ^\n" + - "The return types are incompatible for the inherited methods A.foo(), B.foo()\n" + + "The return types are incompatible for the inherited methods B.foo(), A.foo()\n" + "----------\n" + "2. ERROR in X.java (at line 4)\n" + " interface D extends A, B {}\n" + " ^\n" + - "The return types are incompatible for the inherited methods B.foo(), A.foo()\n" + + "The return types are incompatible for the inherited methods A.foo(), B.foo()\n" + "----------\n" + "3. ERROR in X.java (at line 8)\n" + " X<? extends B> c_b = c.foo();\n" + @@ -3307,7 +3313,7 @@ public void test073() { "3. ERROR in Y.java (at line 13)\n" + " abstract class Y extends X implements I, J {\n" + " ^\n" + - "The return types are incompatible for the inherited methods J.a(), I.a()\n" + + "The return types are incompatible for the inherited methods I.a(), J.a()\n" + "----------\n" + "4. ERROR in Y.java (at line 20)\n" + " abstract class Y2 extends X implements J, I {\n" + @@ -3322,7 +3328,7 @@ public void test073() { "6. ERROR in Y.java (at line 20)\n" + " abstract class Y2 extends X implements J, I {\n" + " ^^\n" + - "The return types are incompatible for the inherited methods I.a(), J.a()\n" + + "The return types are incompatible for the inherited methods J.a(), I.a()\n" + "----------\n" ); } 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 c5b0b6ae9..5836c0d23 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 @@ -9939,35 +9939,46 @@ public void testBug366003() { "----------\n" + "8. ERROR in snippet\\Bug366003.java (at line 13)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + - " ^^^^\n" + - "Syntax error, insert \")\" to complete MethodDeclaration\n" + + " ^^^^\n" + +//{ObjectTeams: starting from here the OT/J grammar produces different errors: +// different: + "Syntax error, insert \")\" to complete MethodSpecLong\n" + "----------\n" + "9. ERROR in snippet\\Bug366003.java (at line 13)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^\n" + - "Syntax error, insert \";\" to complete MethodDeclaration\n" + + "Syntax error, insert \"<-\" to complete CallinBindingLeft\n" + +// "----------\n" + "10. ERROR in snippet\\Bug366003.java (at line 13)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^\n" + +// new + "Syntax error, insert \"MethodSpecsLong EmptyParameterMappings\" to complete InvalidCallinBinding\n" + + "----------\n" + +// number changes beyond this point + "11. ERROR in snippet\\Bug366003.java (at line 13)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^\n" + "Syntax error, insert \"}\" to complete ClassBody\n" + "----------\n" + - "11. ERROR in snippet\\Bug366003.java (at line 13)\n" + + "12. ERROR in snippet\\Bug366003.java (at line 13)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Return type for the method is missing\n" + "----------\n" + - "12. ERROR in snippet\\Bug366003.java (at line 13)\n" + + "13. ERROR in snippet\\Bug366003.java (at line 13)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^^^^\n" + "NonNull cannot be resolved to a type\n" + "----------\n" + - "13. ERROR in snippet\\Bug366003.java (at line 13)\n" + + "14. ERROR in snippet\\Bug366003.java (at line 13)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^^^^^\n" + "Nullable cannot be resolved to a type\n" + "----------\n" + - "14. ERROR in snippet\\Bug366003.java (at line 13)\n" + + "15. ERROR in snippet\\Bug366003.java (at line 13)\n" + +// SH} " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^\n" + "Syntax error, insert \";\" to complete ConstructorDeclaration\n" + @@ -10026,34 +10037,45 @@ public void testBug366003b() { "7. ERROR in snippet\\Bug366003.java (at line 11)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^\n" + - "Syntax error, insert \")\" to complete MethodDeclaration\n" + +//{ObjectTeams: starting from here the OT/J grammar produces different errors: +// different: + "Syntax error, insert \")\" to complete MethodSpecLong\n" + "----------\n" + "8. ERROR in snippet\\Bug366003.java (at line 11)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^\n" + - "Syntax error, insert \";\" to complete MethodDeclaration\n" + + "Syntax error, insert \"<-\" to complete CallinBindingLeft\n" + +// "----------\n" + +// new "9. ERROR in snippet\\Bug366003.java (at line 11)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^\n" + - "Syntax error, insert \"}\" to complete ClassBody\n" + + "Syntax error, insert \"MethodSpecsLong EmptyParameterMappings\" to complete InvalidCallinBinding\n" + +// number changes beyond this point "----------\n" + "10. ERROR in snippet\\Bug366003.java (at line 11)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^\n" + + "Syntax error, insert \"}\" to complete ClassBody\n" + + "----------\n" + + "11. ERROR in snippet\\Bug366003.java (at line 11)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Return type for the method is missing\n" + "----------\n" + - "11. ERROR in snippet\\Bug366003.java (at line 11)\n" + + "12. ERROR in snippet\\Bug366003.java (at line 11)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^^^^\n" + "NonNull cannot be resolved to a type\n" + "----------\n" + - "12. ERROR in snippet\\Bug366003.java (at line 11)\n" + + "13. ERROR in snippet\\Bug366003.java (at line 11)\n" + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^^^^^^^^\n" + "Nullable cannot be resolved to a type\n" + "----------\n" + - "13. ERROR in snippet\\Bug366003.java (at line 11)\n" + + "14. ERROR in snippet\\Bug366003.java (at line 11)\n" + +// SH} " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + " ^\n" + "Syntax error, insert \";\" to complete ConstructorDeclaration\n" + @@ -10079,30 +10101,41 @@ public void testBug366003c() { "----------\n" + "2. ERROR in snippet\\Bug366003.java (at line 5)\n" + " org.User(@Bla String a)\n" + - " ^^^\n" + - "Syntax error, insert \")\" to complete MethodDeclaration\n" + + " ^^^\n" + +//{ObjectTeams: starting from here the OT/J grammar produces different errors: +// different: + "Syntax error, insert \")\" to complete MethodSpecLong\n" + "----------\n" + "3. ERROR in snippet\\Bug366003.java (at line 5)\n" + " org.User(@Bla String a)\n" + " ^^^\n" + - "Syntax error, insert \";\" to complete MethodDeclaration\n" + - "----------\n" + + "Syntax error, insert \"<-\" to complete CallinBindingLeft\n" + +// + "----------\n" + +// new "4. ERROR in snippet\\Bug366003.java (at line 5)\n" + " org.User(@Bla String a)\n" + " ^^^\n" + - "Syntax error, insert \"}\" to complete ClassBody\n" + + "Syntax error, insert \"MethodSpecsLong EmptyParameterMappings\" to complete InvalidCallinBinding\n" + +// number changes beyond this point "----------\n" + "5. ERROR in snippet\\Bug366003.java (at line 5)\n" + " org.User(@Bla String a)\n" + + " ^^^\n" + + "Syntax error, insert \"}\" to complete ClassBody\n" + + "----------\n" + + "6. ERROR in snippet\\Bug366003.java (at line 5)\n" + + " org.User(@Bla String a)\n" + " ^^^^^^^^^^^^^^^^^^^\n" + "Return type for the method is missing\n" + "----------\n" + - "6. ERROR in snippet\\Bug366003.java (at line 5)\n" + + "7. ERROR in snippet\\Bug366003.java (at line 5)\n" + " org.User(@Bla String a)\n" + " ^^^\n" + "Bla cannot be resolved to a type\n" + - "----------\n" + - "7. ERROR in snippet\\Bug366003.java (at line 5)\n" + + "----------\n" + +// SH} + "8. ERROR in snippet\\Bug366003.java (at line 5)\n" + " org.User(@Bla String a)\n" + " ^\n" + "Syntax error, insert \";\" to complete ConstructorDeclaration\n" + 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 78a3e3555..acf06fa1d 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 IBM Corporation and others. + * Copyright (c) 2006, 2013 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 @@ -24,7 +24,9 @@ * bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance * bug 388281 - [compiler][null] inheritance of null annotations as an option * bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types - *******************************************************************************/ + * Jesper S Moller - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression +*******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; import java.lang.reflect.Field; @@ -541,6 +543,7 @@ public void _test011_problem_categories() { expectedProblemAttributes.put("IllegalQualifiedEnumConstantLabel", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); expectedProblemAttributes.put("IllegalQualifiedParameterizedTypeAllocation", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("IllegalQualifierForExplicitThis", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); + expectedProblemAttributes.put("IllegalQualifierForExplicitThis2", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); expectedProblemAttributes.put("IllegalReturnNullityRedefinition", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); expectedProblemAttributes.put("IllegalRedefinitionToNonNullParameter", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); expectedProblemAttributes.put("IllegalStaticModifierForMemberType", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); @@ -551,6 +554,7 @@ public void _test011_problem_categories() { expectedProblemAttributes.put("IllegalUsageOfQualifiedTypeReference", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); expectedProblemAttributes.put("IllegalUsageOfTypeAnnotations", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); expectedProblemAttributes.put("IllegalVararg", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); + expectedProblemAttributes.put("IllegalVarargInLambda", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("IllegalVisibilityModifierCombinationForField", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); expectedProblemAttributes.put("IllegalVisibilityModifierCombinationForMemberType", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("IllegalVisibilityModifierCombinationForMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); @@ -880,6 +884,7 @@ public void _test011_problem_categories() { expectedProblemAttributes.put("SuperfluousSemicolon", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); expectedProblemAttributes.put("SwitchOnEnumNotBelow15", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("SwitchOnStringsNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); + expectedProblemAttributes.put("TargetTypeNotAFunctionalInterface", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("Task", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); expectedProblemAttributes.put("ThisInStaticContext", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); expectedProblemAttributes.put("ThisSuperDuringConstructorInvocation", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); @@ -1355,6 +1360,7 @@ public void test012_compiler_problems_tuning() { expectedProblemAttributes.put("IllegalQualifiedEnumConstantLabel", SKIP); expectedProblemAttributes.put("IllegalQualifiedParameterizedTypeAllocation", SKIP); expectedProblemAttributes.put("IllegalQualifierForExplicitThis", SKIP); + expectedProblemAttributes.put("IllegalQualifierForExplicitThis2", SKIP); expectedProblemAttributes.put("IllegalRedefinitionToNonNullParameter", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION)); expectedProblemAttributes.put("IllegalReturnNullityRedefinition", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION)); expectedProblemAttributes.put("IllegalStaticModifierForMemberType", SKIP); @@ -1365,6 +1371,7 @@ public void test012_compiler_problems_tuning() { expectedProblemAttributes.put("IllegalUsageOfQualifiedTypeReference", SKIP); expectedProblemAttributes.put("IllegalUsageOfTypeAnnotations", SKIP); expectedProblemAttributes.put("IllegalVararg", SKIP); + expectedProblemAttributes.put("IllegalVarargInLambda", SKIP); expectedProblemAttributes.put("IllegalVisibilityModifierCombinationForField", SKIP); expectedProblemAttributes.put("IllegalVisibilityModifierCombinationForMemberType", SKIP); expectedProblemAttributes.put("IllegalVisibilityModifierCombinationForMethod", SKIP); @@ -1695,6 +1702,7 @@ public void test012_compiler_problems_tuning() { expectedProblemAttributes.put("SuperfluousSemicolon", new ProblemAttributes(JavaCore.COMPILER_PB_EMPTY_STATEMENT)); expectedProblemAttributes.put("SwitchOnEnumNotBelow15", SKIP); expectedProblemAttributes.put("SwitchOnStringsNotBelow17", SKIP); + expectedProblemAttributes.put("TargetTypeNotAFunctionalInterface", SKIP); expectedProblemAttributes.put("Task", SKIP); expectedProblemAttributes.put("ThisInStaticContext", SKIP); expectedProblemAttributes.put("ThisSuperDuringConstructorInvocation", SKIP); 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 bf2b91302..a41fe887b 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 GK Software AG and others. + * Copyright (c) 2013 GK Software AG, 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 @@ -483,7 +483,7 @@ public class DefaultMethodsTest extends AbstractComparableTest { "----------\n"); } - public void _testDefaultNonclash3() { + public void testDefaultNonclash3() { runNegativeTest( new String[] { "X.java", @@ -573,4 +573,156 @@ public class DefaultMethodsTest extends AbstractComparableTest { }, ""); } + + // JLS 8.1.1.1 abstract Classes + // Default method overrides an abstract method from its super interface + public void testAbstract01() { + runConformTest( + new String[] { + "I2.java", + "public interface I2 {\n" + + " void test();\n" + + "}\n", + "I1.java", + "public interface I1 extends I2 {\n" + + " void test() default {}\n" + + "}\n", + "C.java", + "public class C implements I1 {\n" + + "}\n" + }); + } + + // JLS 8.1.1.1 abstract Classes + // Default method overrides independent abstract method + public void testAbstract02() { + runConformTest( + new String[] { + "I1.java", + "public interface I1 {\n" + + " void test();\n" + + "}\n", + "I2.java", + "public interface I2 {\n" + + " void test() default {}\n" + + "}\n", + "C.java", + "public class C implements I1, I2 {\n" + + "}\n" + }); + } + + // JLS 8.1.1.1 abstract Classes + // Default method overrides independent abstract method + // same as above except for order of implements list + public void testAbstract02a() { + runConformTest( + new String[] { + "I1.java", + "public interface I1 {\n" + + " void test();\n" + + "}\n", + "I2.java", + "public interface I2 {\n" + + " void test() default {}\n" + + "}\n", + "C.java", + "public class C implements I2, I1 {\n" + + "}\n" + }); + } + + // JLS 8.1.1.1 abstract Classes + // Default method overrides an abstract method from its super interface - class implements both + public void testAbstract03() { + runConformTest( + new String[] { + "I1.java", + "public interface I1 {\n" + + " void test();\n" + + "}\n", + "I2.java", + "public interface I2 extends I1 {\n" + + " @Override\n" + + " void test() default {}\n" + + "}\n", + "C.java", + "public class C implements I1, I2 {\n" + + "}\n" + }); + } + + // JLS 8.1.1.1 abstract Classes + // Default method overrides an abstract method from its super interface - class implements both + // same as above except for order of implements list + public void testAbstract03a() { + runConformTest( + new String[] { + "I1.java", + "public interface I1 {\n" + + " void test();\n" + + "}\n", + "I2.java", + "public interface I2 extends I1 {\n" + + " @Override\n" + + " void test() default {}\n" + + "}\n", + "C.java", + "public class C implements I2, I1 {\n" + + "}\n" + }); + } + + // JLS 8.1.1.1 abstract Classes + // default method is not inherited because a more specific abstract method is. + public void testAbstract04() { + runNegativeTest( + new String[] { + "I1.java", + "public interface I1 {\n" + + " void test() default {}\n" + + "}\n", + "I2.java", + "public interface I2 extends I1 {\n" + + " @Override\n" + + " void test();\n" + + "}\n", + "C.java", + "public class C implements I2, I1 {\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in C.java (at line 1)\n" + + " public class C implements I2, I1 {\n" + + " ^\n" + + "The type C must implement the inherited abstract method I2.test()\n" + + "----------\n"); + } + + // JLS 8.1.1.1 abstract Classes + // default method is not inherited because a more specific abstract method is. + // same as above except for order of implements list + public void testAbstract04a() { + runNegativeTest( + new String[] { + "I1.java", + "public interface I1 {\n" + + " void test() default {}\n" + + "}\n", + "I2.java", + "public interface I2 extends I1 {\n" + + " @Override\n" + + " void test();\n" + + "}\n", + "C.java", + "public class C implements I2, I1 {\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in C.java (at line 1)\n" + + " public class C implements I2, I1 {\n" + + " ^\n" + + "The type C must implement the inherited abstract method I2.test()\n" + + "----------\n"); + } } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java index b6cb60cd9..aa2bf5b8a 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java @@ -5,12 +5,17 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contributions for * Bug 365519 - editorial cleanup after bug 186342 and bug 365387 * Bug 265744 - Enum switch should warn about missing default * Bug 374605 - Unreasonable warning for enum-based switch statements + * bug 388739 - [1.8][compiler] consider default methods when detecting whether a class needs to be declared abstract *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -3007,7 +3012,7 @@ public void test095() { // check missing abstract cases from multiple interfaces "1. ERROR in X.java (at line 1)\n" + " public enum X implements I, J { \n" + " ^\n" + - "The type X must implement the inherited abstract method I.foo()\n" + + "The type X must implement the inherited abstract method J.foo()\n" + "----------\n"); this.runNegativeTest( new String[] { 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 575a1134f..e0188b34e 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,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -1630,6 +1630,7 @@ public void test034() throws Exception { " }\n" + " public void remove() {\n" + " }\n" + + ITERATOR_IMPL_JRE8.replaceAll("\\*", "T") + "}\n" + "class Bar implements Iterable<String> {\n" + " public Iterator<String> iterator() {\n" + @@ -1724,6 +1725,7 @@ public void test035() throws Exception { " }\n" + " public void remove() {\n" + " }\n" + + ITERATOR_IMPL_JRE8.replaceAll("\\*", "T") + "}\n" + "interface IFoo extends Iterable<String> {\n" + "}\n" + @@ -2021,6 +2023,7 @@ public void test039() throws Exception { " System.out.println(\"remove\");\n" + " this.iterator.remove();\n" + " }\n" + + ITERATOR_IMPL_JRE8.replaceAll("\\*", "T") + " }\n" + " \n" + " static Set<Object> initForEach() {\n" + @@ -2117,6 +2120,7 @@ public void test040() throws Exception { " System.out.println(\"remove\");\n" + " this.iterator.remove();\n" + " }\n" + + ITERATOR_IMPL_JRE8.replaceAll("\\*", "T") + " }\n" + " \n" + " static Set<Object> initForEach() {\n" + 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 136186eb5..c3005a2ce 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -17,6 +17,7 @@ * bug 383690 - [compiler] location of error re uninitialized final field should be aligned * bug 388800 - [1.8] adjust tests to 1.8 JRE * bug 388795 - [compiler] detection of name clash depends on order of super interfaces + * bug 388739 - [1.8][compiler] consider default methods when detecting whether a class needs to be declared abstract *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -8855,8 +8856,7 @@ public class GenericTypeTest extends AbstractComparableTest { " 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")+ + MAP_IMPL_JRE8.replaceAll("\\*", "String").replaceAll("\\%", "V")+ "}\n", }, "----------\n" + @@ -10816,6 +10816,7 @@ public class GenericTypeTest extends AbstractComparableTest { " public boolean hasNext() {return false;}\n" + " public Entry<String, Integer> next() {return null;}\n" + " public void remove() {} \n" + + ITERATOR_IMPL_JRE8.replaceAll("\\*", "Entry<String,Integer>") + " };\n" + " }\n" + " public int size() {return 0;}\n" + @@ -13573,6 +13574,7 @@ public class GenericTypeTest extends AbstractComparableTest { " public boolean hasNext() { return false; }\n" + " public String next() { return null; }\n" + " public void remove() {}\n" + + ITERATOR_IMPL_JRE8.replaceAll("\\*", "String") + "}\n", }, ""); @@ -19910,6 +19912,7 @@ public void test0617() { " }\n" + " public void remove() {\n" + " }\n" + + ITERATOR_IMPL_JRE8.replaceAll("\\*", "U") + " }\n" + " }\n" + "}\n", @@ -24934,7 +24937,7 @@ public void test0779() throws Exception { }, "SUCCESS"); - String constantPoolIdx = IS_JRE_8 ? "149" : "36"; // depends on whether or not stubs for JRE8 default methods are included + String constantPoolIdx = IS_JRE_8 ? "67" : "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" + @@ -25888,6 +25891,7 @@ public void test0809() { " }\n" + " public void remove() {\n" + " }\n" + + ITERATOR_IMPL_JRE8.replaceAll("\\*", "N") + "}\n" + "interface Set3<N extends Node> extends Iterable<N> {\n" + " SetIterator<N> iterator();\n" + @@ -25919,27 +25923,27 @@ public void test0809() { "}\n", }, "----------\n" + - "1. WARNING in X.java (at line 21)\n" + + "1. WARNING in X.java (at line 22)\n" + " void f1(Set1 s) {\n" + " ^^^^\n" + "Set1 is a raw type. References to generic type Set1<N> should be parameterized\n" + "----------\n" + - "2. ERROR in X.java (at line 22)\n" + + "2. ERROR in X.java (at line 23)\n" + " Node n_ = s.iterator().next();\n" + " ^^^^^^^^^^^^^^^^^^^\n" + "Type mismatch: cannot convert from Object to Node\n" + "----------\n" + - "3. ERROR in X.java (at line 25)\n" + + "3. ERROR in X.java (at line 26)\n" + " for (Node n : s) {\n" + " ^\n" + "Type mismatch: cannot convert from element type Object to Node\n" + "----------\n" + - "4. WARNING in X.java (at line 35)\n" + + "4. WARNING in X.java (at line 36)\n" + " void f3(Set3 s) {\n" + " ^^^^\n" + "Set3 is a raw type. References to generic type Set3<N> should be parameterized\n" + "----------\n" + - "5. ERROR in X.java (at line 38)\n" + + "5. ERROR in X.java (at line 39)\n" + " for (Node n : s) {\n" + " ^\n" + "Type mismatch: cannot convert from element type Object to Node\n" + @@ -28044,7 +28048,7 @@ public void test0868() { " \n" + " }" + COLLECTION_RAW_IMPL_JRE8 + - ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 + + ITERABLE_RAW_IMPL_JRE8 + "}", }, "", @@ -32485,28 +32489,18 @@ public void test0986() { public void test0987() { String expectedOutput = new CompilerOptions(getCompilerOptions()).sourceLevel < ClassFileConstants.JDK1_6 ? "----------\n" + - "1. ERROR in X.java (at line 7)\n" + - " abstract class GLinkElementView<M,CM> extends AbstractLinkView<M> {}\n" + - " ^^^^^^^^^^^^^^^^\n" + - "The return types are incompatible for the inherited methods EditPart.getViewer(), AbstractLinkView<M>.getViewer()\n" + - "----------\n" + - "2. ERROR in X.java (at line 11)\n" + + "1. ERROR in X.java (at line 11)\n" + " public ISheetViewer getViewer() { return null; } \n" + " ^^^^^^^^^^^^\n" + "The return type is incompatible with EditPart.getViewer()\n" + "----------\n" + - "3. ERROR in X.java (at line 11)\n" + + "2. ERROR in X.java (at line 11)\n" + " public ISheetViewer getViewer() { return null; } \n" + " ^^^^^^^^^^^\n" + "The method getViewer() of type AbstractLinkView<M> must override a superclass method\n" + "----------\n" : "----------\n" + - "1. ERROR in X.java (at line 7)\n" + - " abstract class GLinkElementView<M,CM> extends AbstractLinkView<M> {}\n" + - " ^^^^^^^^^^^^^^^^\n" + - "The return types are incompatible for the inherited methods EditPart.getViewer(), AbstractLinkView<M>.getViewer()\n" + - "----------\n" + - "2. ERROR in X.java (at line 11)\n" + + "1. ERROR in X.java (at line 11)\n" + " public ISheetViewer getViewer() { return null; } \n" + " ^^^^^^^^^^^^\n" + "The return type is incompatible with EditPart.getViewer()\n" + @@ -32595,12 +32589,7 @@ public void test0988() { "}", // ================= }, "----------\n" + - "1. ERROR in X.java (at line 7)\n" + - " abstract class GLinkElementView<M,CM> extends AbstractLinkView<M> {}\n" + - " ^^^^^^^^^^^^^^^^\n" + - "The return types are incompatible for the inherited methods EditPart.getViewer(), ILinkViewElement.getViewer(), AbstractLinkView<M>.getViewer()\n" + - "----------\n" + - "2. ERROR in X.java (at line 11)\n" + + "1. ERROR in X.java (at line 11)\n" + " public SheetViewer getViewer() { return null; } \n" + " ^^^^^^^^^^^\n" + "The return type is incompatible with AbstractEditPart.getViewer()\n" + @@ -34442,7 +34431,7 @@ public void test1035() { "public int compare(T obj1, T obj2) {\n" + " return obj1.compareTo(obj2);\n" + "}\n" + - COMPARATOR_IMPL_JRE8.replace('*', 'T') + + COMPARATOR_IMPL_JRE8.replace('*', 'T').replace('%', 'U') + "}\n" + "\n" + "@SuppressWarnings({\"unchecked\", \"rawtypes\"})\n" + @@ -34493,7 +34482,7 @@ public void test1035() { "public int compare(V obj1, V obj2) {\n" + " return 0;\n" + "}\n" + - COMPARATOR_IMPL_JRE8.replace('*', 'V') + + COMPARATOR_IMPL_JRE8.replace('*', 'V').replace('%', 'U') + "}", // ================= }, @@ -42843,7 +42832,7 @@ public void test1239() { "4. ERROR in X.java (at line 13)\n" + " public interface CombinedSubInterface extends SubInterface, OtherSubInterface {}\n" + " ^^^^^^^^^^^^^^^^^^^^\n" + - "The return types are incompatible for the inherited methods X.OtherSubInterface.and(X.SuperInterface), X.SubInterface.and(X.SuperInterface)\n" + + "The return types are incompatible for the inherited methods X.SubInterface.and(X.SuperInterface), X.OtherSubInterface.and(X.SuperInterface)\n" + "----------\n" + "5. WARNING in X.java (at line 15)\n" + " public interface OtherSubInterface extends SuperInterface {\n" + @@ -49757,6 +49746,7 @@ public void test1444() { " public boolean hasNext() {\n" + " return false;\n" + " }\n" + + ITERATOR_RAW_IMPL_JRE8 + " };\n" + " }\n" + " Zork z;\n" + @@ -49788,7 +49778,7 @@ public void test1444() { " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Unnecessary cast from Iterator to Iterator<String>\n" + "----------\n" + - "6. ERROR in X.java (at line 36)\n" + + "6. ERROR in X.java (at line 37)\n" + " Zork z;\n" + " ^^^^\n" + "Zork cannot be resolved to a type\n" + diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java index a7c87e0ef..1e7bf3717 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2012 IBM Corporation and others. + * Copyright (c) 2011, 2013 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 @@ -1447,7 +1447,13 @@ public class GrammarCoverageTests308 extends AbstractRegressionTest { " i = @Marker W<@Marker Integer>::<@Marker String> new;\n" + " ^\n" + "i cannot be resolved to a variable\n" + - "----------\n"); + "----------\n" + + "2. ERROR in X.java (at line 12)\n" + + " i = @Marker W<@Marker Integer>::<@Marker String> new;\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "The target type of this expression must be a functional interface\n" + + "----------\n" + ); } // CastExpression ::= PushLPAREN Name PushRPAREN InsideCastExpressionLL1 UnaryExpressionNotPlusMinus // CastExpression ::= PushLPAREN Name Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus 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 85d3cddf4..bbb9c35a5 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,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 IBM Corporation and others. + * Copyright (c) 2006, 2013 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 diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTestForClass.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTestForClass.java index a815e7646..13375e6e7 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTestForClass.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTestForClass.java @@ -4,10 +4,6 @@ * 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 @@ -1026,29 +1022,17 @@ public class JavadocTestForClass extends JavadocTest { " int i = 0;\n" + "}\n", }, - IS_JRE_8 ? - "----------\n" + - "1. ERROR in X.java (at line 6)\n" + - " * <li> {@link Entry} </li>\n" + - " ^^^^^\n" + - "Javadoc: Invalid member type qualification\n" + - "----------\n" + - "2. ERROR in X.java (at line 9)\n" + - " public interface X extends Map {\n" + - " ^\n" + - "The return types are incompatible for the inherited methods MapStream.values(), Map.values()\n" + - "----------\n" : - "----------\n" + - "1. WARNING in X.java (at line 2)\n"+ - " import java.util.Map.Entry;\n"+ - " ^^^^^^^^^^^^^^^^^^^\n"+ - "The import java.util.Map.Entry is never used\n"+ - "----------\n"+ - "2. ERROR in X.java (at line 6)\n" + - " * <li> {@link Entry} </li>\n" + - " ^^^^^\n" + - "Javadoc: Invalid member type qualification\n" + - "----------\n"); + "----------\n" + + "1. WARNING in X.java (at line 2)\n"+ + " import java.util.Map.Entry;\n"+ + " ^^^^^^^^^^^^^^^^^^^\n"+ + "The import java.util.Map.Entry is never used\n"+ + "----------\n"+ + "2. ERROR in X.java (at line 6)\n" + + " * <li> {@link Entry} </li>\n" + + " ^^^^^\n" + + "Javadoc: Invalid member type qualification\n" + + "----------\n"); return; } runNegativeTest( @@ -1089,24 +1073,12 @@ public class JavadocTestForClass extends JavadocTest { " Entry e = null;\n" + "}\n", }, - !IS_JRE_8 || (IS_JRE_8 && this.complianceLevel >= ClassFileConstants.JDK1_5) ? - "----------\n" + - "1. ERROR in X.java (at line 5)\n" + - " * <li> {@link Entry} </li>\n" + - " ^^^^^\n" + - "Javadoc: Invalid member type qualification\n" + - "----------\n": - "----------\n" + - "1. ERROR in X.java (at line 5)\n" + - " * <li> {@link Entry} </li>\n" + - " ^^^^^\n" + - "Javadoc: Invalid member type qualification\n" + - "----------\n" + - "2. ERROR in X.java (at line 8)\n" + - " public interface X extends Map {\n" + - " ^\n" + - "The return types are incompatible for the inherited methods MapStream.values(), Map.values()\n" + - "----------\n"); + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " * <li> {@link Entry} </li>\n" + + " ^^^^^\n" + + "Javadoc: Invalid member type qualification\n" + + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=253750 @@ -1127,29 +1099,17 @@ public class JavadocTestForClass extends JavadocTest { " Entry e = null;\n" + "}\n", }, - IS_JRE_8 ? - "----------\n" + - "1. ERROR in X.java (at line 6)\n" + - " * <li> {@link Entry} </li>\n" + - " ^^^^^\n" + - "Javadoc: Invalid member type qualification\n" + - "----------\n" + - "2. ERROR in X.java (at line 9)\n" + - " public interface X extends Map {\n" + - " ^\n" + - "The return types are incompatible for the inherited methods MapStream.values(), Map.values()\n" + - "----------\n" : - "----------\n" + - "1. WARNING in X.java (at line 2)\n"+ - " import java.util.Map.Entry;\n"+ - " ^^^^^^^^^^^^^^^^^^^\n"+ - "The import java.util.Map.Entry is never used\n"+ - "----------\n"+ - "2. ERROR in X.java (at line 6)\n" + - " * <li> {@link Entry} </li>\n" + - " ^^^^^\n" + - "Javadoc: Invalid member type qualification\n" + - "----------\n"); + "----------\n" + + "1. WARNING in X.java (at line 2)\n"+ + " import java.util.Map.Entry;\n"+ + " ^^^^^^^^^^^^^^^^^^^\n"+ + "The import java.util.Map.Entry is never used\n"+ + "----------\n"+ + "2. ERROR in X.java (at line 6)\n" + + " * <li> {@link Entry} </li>\n" + + " ^^^^^\n" + + "Javadoc: Invalid member type qualification\n" + + "----------\n"); return; } runNegativeTest( 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 53623c980..fd2d7ae5c 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,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 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 d30c58622..8eb18b2e3 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,8 +12,9 @@ * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for - * bug 388795 - [compiler] detection of name clash depends on order of super interfaces * bug 388800 - [1.8] adjust tests to 1.8 JRE + * bug 388795 - [compiler] detection of name clash depends on order of super interfaces + * bug 388739 - [1.8][compiler] consider default methods when detecting whether a class needs to be declared abstract *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -1822,7 +1823,6 @@ public class MethodVerifyTest extends AbstractComparableTest { "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" }, "" @@ -2041,7 +2041,7 @@ public class MethodVerifyTest extends AbstractComparableTest { "1. ERROR in X.java (at line 3)\n" + " public class X<T extends I&J> {}\n" + " ^\n" + - "The return types are incompatible for the inherited methods J.foo(), I.foo()\n" + + "The return types are incompatible for the inherited methods I.foo(), J.foo()\n" + "----------\n" // types J and I are incompatible; both define foo(), but with unrelated return types ); @@ -2367,7 +2367,7 @@ public class MethodVerifyTest extends AbstractComparableTest { "1. ERROR in Y.java (at line 1)\n" + " abstract class Y implements Equivalent<String>, EqualityComparable<Integer> {\n" + " ^\n" + - "Name clash: The method equalTo(T) of type Equivalent<T> has the same erasure as equalTo(T) of type EqualityComparable<T> but does not override it\n" + + "Name clash: The method equalTo(T) of type EqualityComparable<T> has the same erasure as equalTo(T) of type Equivalent<T> but does not override it\n" + "----------\n"); } } @@ -2387,29 +2387,29 @@ public class MethodVerifyTest extends AbstractComparableTest { "1. ERROR in Y.java (at line 2)\n" + " public abstract boolean equalTo(Object other);\n" + " ^^^^^^^^^^^^^^^^^^^^^\n" + - "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type Equivalent<T> but does not override it\n" + + "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type EqualityComparable<T> but does not override it\n" + "----------\n" + "2. ERROR in Y.java (at line 2)\n" + " public abstract boolean equalTo(Object other);\n" + " ^^^^^^^^^^^^^^^^^^^^^\n" + - "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type EqualityComparable<T> but does not override it\n" + + "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type Equivalent<T> but does not override it\n" + "----------\n" : // name clash: equalTo(java.lang.Object) in Y and equalTo(T) in Equivalent<java.lang.String> have the same erasure, yet neither overrides the other "----------\n" + "1. ERROR in Y.java (at line 1)\n" + " abstract class Y implements Equivalent<String>, EqualityComparable<Integer> {\n" + " ^\n" + - "Name clash: The method equalTo(T) of type Equivalent<T> has the same erasure as equalTo(T) of type EqualityComparable<T> but does not override it\n" + + "Name clash: The method equalTo(T) of type EqualityComparable<T> has the same erasure as equalTo(T) of type Equivalent<T> but does not override it\n" + "----------\n" + "2. ERROR in Y.java (at line 2)\n" + " public abstract boolean equalTo(Object other);\n" + " ^^^^^^^^^^^^^^^^^^^^^\n" + - "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type Equivalent<T> but does not override it\n" + + "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type EqualityComparable<T> but does not override it\n" + "----------\n" + "3. ERROR in Y.java (at line 2)\n" + " public abstract boolean equalTo(Object other);\n" + " ^^^^^^^^^^^^^^^^^^^^^\n" + - "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type EqualityComparable<T> but does not override it\n" + + "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type Equivalent<T> but does not override it\n" + "----------\n" ); } @@ -6878,7 +6878,7 @@ X.java:7: name clash: <T#1>foo2(T#1) in X and <T#2>foo2(A) in Y have the same er " public boolean hasNext() { return false; }\n" + " public Object next() { return null; }\n" + " public void remove() {}\n" + - ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 + + ITERABLE_RAW_IMPL_JRE8 + COLLECTION_RAW_IMPL_JRE8 + LIST_RAW_IMPL_JRE8 + "}\n", // ================= @@ -7001,7 +7001,7 @@ X.java:7: name clash: <T#1>foo2(T#1) in X and <T#2>foo2(A) in Y have the same er " public boolean hasNext() { return false; }\n" + " public Object next() { return null; }\n" + " public void remove() {}\n" + - ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 + + ITERABLE_RAW_IMPL_JRE8 + COLLECTION_RAW_IMPL_JRE8 + LIST_RAW_IMPL_JRE8 + "}\n", // ================= @@ -7114,7 +7114,7 @@ X.java:7: name clash: <T#1>foo2(T#1) in X and <T#2>foo2(A) in Y have the same er " public boolean hasNext() { return false; }\n" + " public Object next() { return null; }\n" + " public void remove() {}\n" + - ITERABLE_RAW_WITHOUT_IS_EMPTY_IMPL_JRE8 + + ITERABLE_RAW_IMPL_JRE8 + COLLECTION_RAW_IMPL_JRE8 + LIST_RAW_IMPL_JRE8 + "}\n", // ================= @@ -9101,7 +9101,7 @@ public void test140() { "1. ERROR in X.java (at line 1)\n" + " public abstract class X implements J, K {}\n" + " ^\n" + - "The return types are incompatible for the inherited methods K.foo(Number), J.foo(Number)\n" + + "The return types are incompatible for the inherited methods J.foo(Number), K.foo(Number)\n" + "----------\n" + "2. WARNING in X.java (at line 6)\n" + " XX foo(Number n);\n" + @@ -9715,7 +9715,7 @@ public void test155() { "1. ERROR in X.java (at line 9)\n" + " public abstract class X implements I, J {\n" + " ^\n" + - "The return types are incompatible for the inherited methods J.foo(), I.foo()\n" + + "The return types are incompatible for the inherited methods I.foo(), J.foo()\n" + "----------\n" ); } @@ -9740,7 +9740,7 @@ public void test156() { "1. ERROR in X.java (at line 10)\n" + " public abstract class X implements I, J {\n" + " ^\n" + - "The return types are incompatible for the inherited methods J.foo(), I.foo()\n" + + "The return types are incompatible for the inherited methods I.foo(), J.foo()\n" + "----------\n" ); } @@ -9767,7 +9767,7 @@ public void test157() { "1. ERROR in X.java (at line 7)\n" + " interface C extends A, B {}\n" + " ^\n" + - "The return types are incompatible for the inherited methods B.foo(), A.foo()\n" + + "The return types are incompatible for the inherited methods A.foo(), B.foo()\n" + "----------\n" ); } @@ -9799,7 +9799,7 @@ public void test158() { "1. ERROR in X.java (at line 17)\n" + " public abstract class X extends Root implements AFoo, BFoo {\n" + " ^\n" + - "The return types are incompatible for the inherited methods BFoo.bar(), AFoo.bar()\n" + + "The return types are incompatible for the inherited methods AFoo.bar(), BFoo.bar()\n" + "----------\n" ); } @@ -9830,17 +9830,17 @@ public void test159() { "1. ERROR in X.java (at line 15)\n" + " public abstract class X extends Root implements AFoo, BFoo {}\n" + " ^\n" + - "The return types are incompatible for the inherited methods BFoo.bar(), AFoo.bar()\n" + + "The return types are incompatible for the inherited methods AFoo.bar(), BFoo.bar()\n" + "----------\n" + "2. ERROR in X.java (at line 16)\n" + " abstract class Y extends X {}\n" + " ^\n" + - "The return types are incompatible for the inherited methods BFoo.bar(), AFoo.bar()\n" + + "The return types are incompatible for the inherited methods AFoo.bar(), BFoo.bar()\n" + "----------\n" + "3. ERROR in X.java (at line 17)\n" + " class Z extends X {}\n" + " ^\n" + - "The type Z must implement the inherited abstract method AFoo.bar()\n" + + "The type Z must implement the inherited abstract method BFoo.bar()\n" + "----------\n"); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=208010 @@ -10810,7 +10810,7 @@ public void test185() { "1. ERROR in A.java (at line 3)\n" + " class A implements I, J {}\n" + " ^\n" + - "The type A must implement the inherited abstract method I.hello()\n" + + "The type A must implement the inherited abstract method J.hello()\n" + "----------\n" ); } @@ -13395,11 +13395,6 @@ public void testBug317719f() throws Exception { " Zork z;\n" + " ^^^^\n" + "Zork cannot be resolved to a type\n" + - "----------\n" + - "5. ERROR in X.java (at line 7)\n" + - " class ChildX<Z> extends X<Z>{}\n" + - " ^^^^^^\n" + - "Duplicate methods named forAccountSet with the parameters (List<R>) and (List) are defined by the type X<Z>\n" + "----------\n": "----------\n" + "1. ERROR in X.java (at line 3)\n" + @@ -13734,7 +13729,7 @@ public void test354229() { "1. ERROR in X.java (at line 8)\n" + " interface C extends A, B { \n" + " ^\n" + - "Name clash: The method get(List<String>) of type A has the same erasure as get(List<Integer>) of type B but does not override it\n" + + "Name clash: The method get(List<Integer>) of type B has the same erasure as get(List<String>) of type A but does not override it\n" + "----------\n" + "2. ERROR in X.java (at line 10)\n" + " Zork z;\n" + @@ -13800,7 +13795,7 @@ public void test354229c() { "1. ERROR in X.java (at line 7)\n" + " interface E extends X, Y {\n" + " ^\n" + - "Name clash: The method e(Action<T>) of type X has the same erasure as e(Action<S>) of type Y but does not override it\n" + + "Name clash: The method e(Action<S>) of type Y has the same erasure as e(Action<T>) of type X but does not override it\n" + "----------\n" + "2. ERROR in X.java (at line 10)\n" + " Zork z;\n" + diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java index 46144a5cd..6ff31fb70 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2012 IBM Corporation and others. + * Copyright (c) 2011, 2013 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 @@ -11,6 +11,8 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Jesper S Moller - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -219,14 +221,14 @@ public void test009() { "}\n" + "public class X {\n" + " public void test1(int x) {\n" + - " ActionListener al = (public xyz) -> System.out.println(e); \n" + + " ActionListener al = (public xyz) -> System.out.println(xyz); \n" + " I f = (abstract final s, @Nullable t) -> System.out.println(s + t); \n" + " }\n" + "}\n", }, "----------\n" + "1. ERROR in X.java (at line 7)\n" + - " ActionListener al = (public xyz) -> System.out.println(e); \n" + + " ActionListener al = (public xyz) -> System.out.println(xyz); \n" + " ^^^\n" + "Syntax error, modifiers and annotations are not allowed for the lambda parameter xyz as its type is elided\n" + "----------\n" + @@ -264,6 +266,148 @@ public void test010() { "Zork cannot be resolved to a type\n" + "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=382701, [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expressions. +public void test011() { + // This test checks that common semantic checks are indeed + this.runNegativeTest( + new String[] { + "X.java", + "interface I {\n" + + " Object foo(int [] ia);\n" + + "}\n" + + "public class X {\n" + + " I i = (int [] ia) -> {\n" + + " Zork z;\n" + // Error: No such type + " unknown = 0;\n;" + // Error: No such variable + " int a = 42 + ia;\n" + // Error: int + int[] is wrong + " return ia.clone();\n" + + " };\n" + + " static void staticLambda() {\n" + + " I i = (int [] ia) -> this;\n" + // 'this' is static + " }\n" + + " I j = array -> {\n" + + " int a = array[2] + 3;\n" + // No error, ia must be correctly identifies as int[] + " int b = 42 + array;\n" + // Error: int + int[] is wrong - yes it is! + " System.out.println(\"i(array) = \" + i.foo(array));\n" + // fields are accessible! + " return;\n" + // Error here, expecting Object, not void + " };\n" + + " Runnable r = () -> { return 42; };\n" + // Runnable.run not expecting return value + " void anotherLambda() {\n" + + " final int beef = 0;\n" + + " I k = (int [] a) -> a.length + beef;\n" + // No error, beef is in scope + " }\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " Zork z;\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n" + + "2. ERROR in X.java (at line 7)\n" + + " unknown = 0;\n" + + " ^^^^^^^\n" + + "unknown cannot be resolved to a variable\n" + + "----------\n" + + "3. ERROR in X.java (at line 8)\n" + + " ; int a = 42 + ia;\n" + + " ^^^^^^^\n" + + "The operator + is undefined for the argument type(s) int, int[]\n" + + "----------\n" + + "4. ERROR in X.java (at line 12)\n" + + " I i = (int [] ia) -> this;\n" + + " ^^^^\n" + + "Cannot use this in a static context\n" + + "----------\n" + + "5. ERROR in X.java (at line 16)\n" + + " int b = 42 + array;\n" + + " ^^^^^^^^^^\n" + + "The operator + is undefined for the argument type(s) int, int[]\n" + + "----------\n" + + "6. ERROR in X.java (at line 18)\n" + + " return;\n" + + " ^^^^^^^\n" + + "This method must return a result of type Object\n" + + "----------\n" + + "7. ERROR in X.java (at line 20)\n" + + " Runnable r = () -> { return 42; };\n" + + " ^^^^^^^^^^\n" + + "Void methods cannot return a value\n" + + "----------\n" +); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=384600, [1.8] 'this' should not be allowed in lambda expressions in contexts that don't allow it +public void test012() { + // This test checks that common semantic checks are indeed + this.runNegativeTest( + new String[] { + "X.java", + "interface I {\n" + + " void doit();\n" + + "}\n" + + "public class X {\n" + + " static void foo() {\n" + + " I i = () -> {\n" + + " System.out.println(this);\n" + + " I j = () -> {\n" + + " System.out.println(this);\n" + + " I k = () -> {\n" + + " System.out.println(this);\n" + + " };\n" + + " };\n" + + " };\n" + + " }\n" + + "}\n" , + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " System.out.println(this);\n" + + " ^^^^\n" + + "Cannot use this in a static context\n" + + "----------\n" + + "2. ERROR in X.java (at line 9)\n" + + " System.out.println(this);\n" + + " ^^^^\n" + + "Cannot use this in a static context\n" + + "----------\n" + + "3. ERROR in X.java (at line 11)\n" + + " System.out.println(this);\n" + + " ^^^^\n" + + "Cannot use this in a static context\n" + + "----------\n" + ); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=384600, [1.8] 'this' should not be allowed in lambda expressions in contexts that don't allow it +public void test013() { + // This test checks that common semantic checks are indeed + this.runNegativeTest( + new String[] { + "X.java", + "interface I {\n" + + " void doit();\n" + + "}\n" + + "public class X {\n" + + " void foo(Zork z) {\n" + + " I i = () -> {\n" + + " System.out.println(this);\n" + + " I j = () -> {\n" + + " System.out.println(this);\n" + + " I k = () -> {\n" + + " System.out.println(this);\n" + + " };\n" + + " };\n" + + " };\n" + + " }\n" + + "}\n" , + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " void foo(Zork z) {\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n" + ); +} public static Class testClass() { return NegativeLambdaExpressionsTest.class; } 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 283bac762..692f21e27 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2012 IBM Corporation and others. + * Copyright (c) 2011, 2013 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 @@ -1120,7 +1120,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest { "5. ERROR in Outer.java (at line 6)\n" + " InnerMost(Outer.Inner this) {}\n" + " ^^^^\n" + - "The explicit 'this' parameter is expected to be qualified with Outer.Inner\n" + + "The explicit 'this' parameter is expected to be qualified with Inner\n" + "----------\n" + "6. WARNING in Outer.java (at line 7)\n" + " InnerMost(Outer.Inner Outer.Inner.this, int i, float f) {}\n" + @@ -1132,35 +1132,40 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest { " ^^^^^^^^^^^\n" + "The declared type of the explicit 'this' parameter is expected to be Outer.Inner<K,V>\n" + "----------\n" + - "8. ERROR in Outer.java (at line 8)\n" + + "8. ERROR in Outer.java (at line 7)\n" + + " InnerMost(Outer.Inner Outer.Inner.this, int i, float f) {}\n" + + " ^^^^^^^^^^^^^^^^\n" + + "The explicit 'this' parameter is expected to be qualified with Inner\n" + + "----------\n" + + "9. ERROR in Outer.java (at line 8)\n" + " InnerMost(Outer Outer.this, float f) {}\n" + " ^^^^^\n" + "The declared type of the explicit 'this' parameter is expected to be Outer.Inner<K,V>\n" + "----------\n" + - "9. ERROR in Outer.java (at line 8)\n" + + "10. ERROR in Outer.java (at line 8)\n" + " InnerMost(Outer Outer.this, float f) {}\n" + - " ^^^^\n" + - "The explicit 'this' parameter is expected to be qualified with Outer.Inner\n" + + " ^^^^^^^^^^\n" + + "The explicit 'this' parameter is expected to be qualified with Inner\n" + "----------\n" + - "10. ERROR in Outer.java (at line 9)\n" + + "11. ERROR in Outer.java (at line 9)\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" + + "12. ERROR in Outer.java (at line 9)\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" + + "The explicit 'this' parameter is expected to be qualified with Inner\n" + "----------\n" + - "12. ERROR in Outer.java (at line 10)\n" + + "13. ERROR in Outer.java (at line 10)\n" + " InnerMost(Inner<K,V> Outer.Inner.InnerMost.this, int i) {}\n" + - " ^^^^\n" + - "The explicit 'this' parameter is expected to be qualified with Outer.Inner\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "The explicit 'this' parameter is expected to be qualified with Inner\n" + "----------\n" + - "13. ERROR in Outer.java (at line 11)\n" + + "14. ERROR in Outer.java (at line 11)\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" + + "The explicit 'this' parameter is expected to be qualified with Inner\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=383913 @@ -1190,8 +1195,8 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest { "----------\n" + "2. ERROR in Outer.java (at line 4)\n" + " public void foo(Outer Outer.this) {}\n" + - " ^^^^\n" + - "The explicit 'this' parameter is expected to be qualified with Outer.Inner.InnerMost\n" + + " ^^^^^^^^^^\n" + + "The explicit 'this' parameter for a method cannot have a qualifying name\n" + "----------\n" + "3. ERROR in Outer.java (at line 5)\n" + " public void foo(Inner<K,V> Inner.this, int i) {}\n" + @@ -1200,8 +1205,8 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest { "----------\n" + "4. ERROR in Outer.java (at line 5)\n" + " public void foo(Inner<K,V> Inner.this, int i) {}\n" + - " ^^^^\n" + - "The explicit 'this' parameter is expected to be qualified with Outer.Inner.InnerMost\n" + + " ^^^^^^^^^^\n" + + "The explicit 'this' parameter for a method cannot have a qualifying name\n" + "----------\n" + "5. WARNING in Outer.java (at line 6)\n" + " public void foo(InnerMost this, int i, int j) {}\n" + @@ -1222,6 +1227,11 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest { " public void foo(Inner.InnerMost<T> this, Object obj) {}\n" + " ^^^^^^^^^^^^^^^\n" + "The declared type of the explicit 'this' parameter is expected to be Outer.Inner<K,V>.InnerMost<T>\n" + + "----------\n" + + "9. ERROR in Outer.java (at line 11)\n" + + " public void foo(InnerMost<T> Outer.Inner.InnerMost.this, int i, float f) {}\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "The explicit 'this' parameter for a method cannot have a qualifying name\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=383913 @@ -1523,7 +1533,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest { "public class X {\n" + " class Y {\n" + " class Z {\n" + - " Z(X. @Marker Y X.Y.this) {\n" + + " Z(X. @Marker Y Y.this) {\n" + " }\n" + " }\n" + " }\n" + @@ -1531,7 +1541,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest { }, "----------\n" + "1. ERROR in X.java (at line 4)\n" + - " Z(X. @Marker Y X.Y.this) {\n" + + " Z(X. @Marker Y Y.this) {\n" + " ^^^^^^\n" + "Marker cannot be resolved to a type\n" + "----------\n"); @@ -3107,4 +3117,40 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest { "The annotation @Marker2 is disallowed for this location\n" + "----------\n"); } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399453 + public void testBug399453() { + this.runNegativeTest( + new String[]{ + "X.java", + "import java.lang.annotation.Target;\n" + + "import static java.lang.annotation.ElementType.*;\n" + + "public class X {\n" + + " public void foo() {\n" + + " int @Marker [][][] i = new @Marker2 int @Marker @Marker2 [2] @Marker @Marker2 [@Marker bar()] @Marker @Marker2 [];\n" + + " int @Marker [][][] j = new @Marker2 int @Marker @Marker2 [2] @Marker @Marker2 [@Marker X.bar2(2)] @Marker @Marker2 [];\n" + + " }\n" + + " public int bar() {\n" + + " return 2;\n" + + " }\n" + + " public static int bar2(int k) {\n" + + " return k;\n" + + " }\n" + + "}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker {}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker2 {}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " int @Marker [][][] i = new @Marker2 int @Marker @Marker2 [2] @Marker @Marker2 [@Marker bar()] @Marker @Marker2 [];\n" + + " ^^^^^^^\n" + + "Syntax error, type annotations are illegal here\n" + + "----------\n" + + "2. ERROR in X.java (at line 6)\n" + + " int @Marker [][][] j = new @Marker2 int @Marker @Marker2 [2] @Marker @Marker2 [@Marker X.bar2(2)] @Marker @Marker2 [];\n" + + " ^^^^^^^\n" + + "Syntax error, type annotations are illegal here\n" + + "----------\n"); + } }
\ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java index 4e0489061..188347fe2 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 IBM Corporation and others. + * Copyright (c) 2006, 2013 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 diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java index e2752d067..347bbe60e 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 IBM Corporation and others. + * Copyright (c) 2005, 2013 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 *******************************************************************************/ @@ -2478,6 +2482,7 @@ public class VarargsTest extends AbstractComparableTest { " public void remove() {\n" + " throw new UnsupportedOperationException();\n" + " }\n" + + ITERATOR_IMPL_JRE8.replaceAll("\\*", "T") + " }\n" + " public static void main(String[] args) {\n" + " new IteratorChain<Number>(null, null);\n" + @@ -2486,7 +2491,7 @@ public class VarargsTest extends AbstractComparableTest { }, this.complianceLevel < ClassFileConstants.JDK1_7 ? "----------\n" + - "1. WARNING in X.java (at line 18)\n" + + "1. WARNING in X.java (at line 19)\n" + " new IteratorChain<Number>(null, null);\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Type safety: A generic array of Collection<? extends Number> is created for a varargs parameter\n" + @@ -2497,7 +2502,7 @@ public class VarargsTest extends AbstractComparableTest { " ^^^^^^^^^^^\n" + "Type safety: Potential heap pollution via varargs parameter collections\n" + "----------\n" + - "2. WARNING in X.java (at line 18)\n" + + "2. WARNING in X.java (at line 19)\n" + " new IteratorChain<Number>(null, null);\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Type safety: A generic array of Collection<? extends Number> is created for a varargs parameter\n" + diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava8Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava8Tests.java index c77fcd03a..449594c84 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava8Tests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava8Tests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2012 IBM Corporation and others. + * Copyright (c) 2011, 2013 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 @@ -29,12 +29,14 @@ import org.eclipse.jdt.core.tests.compiler.parser.ComplianceDiagnoseTest; import org.eclipse.jdt.core.tests.compiler.parser.LambdaExpressionSyntaxTest; import org.eclipse.jdt.core.tests.compiler.parser.ReferenceExpressionSyntaxTest; import org.eclipse.jdt.core.tests.compiler.parser.TypeAnnotationSyntaxTest; +import org.eclipse.jdt.core.tests.compiler.regression.CompilerInvocationTests; import org.eclipse.jdt.core.tests.compiler.regression.DefaultMethodsTest; import org.eclipse.jdt.core.tests.compiler.regression.GrammarCoverageTests308; import org.eclipse.jdt.core.tests.compiler.regression.NegativeLambdaExpressionsTest; import org.eclipse.jdt.core.tests.compiler.regression.NegativeTypeAnnotationTest; import org.eclipse.jdt.core.tests.compiler.regression.NullTypeAnnotationTest; import org.eclipse.jdt.core.tests.dom.ASTConverter15JLS8Test; +import org.eclipse.jdt.core.tests.dom.ASTConverter18Test; import org.eclipse.jdt.core.tests.dom.ASTConverterAST8Test; import org.eclipse.jdt.core.tests.dom.ASTConverterBugsTestJLS8; import org.eclipse.jdt.core.tests.dom.ASTConverterTestAST8_2; @@ -56,7 +58,8 @@ public class RunAllJava8Tests extends TestCase { DefaultMethodsTest.class, ComplianceDiagnoseTest.class, GrammarCoverageTests308.class, - NullTypeAnnotationTest.class + NullTypeAnnotationTest.class, + CompilerInvocationTests.class }; } @@ -67,6 +70,7 @@ public class RunAllJava8Tests extends TestCase { ASTConverterAST8Test.class, ASTConverterBugsTestJLS8.class, ASTConverter15JLS8Test.class, + ASTConverter18Test.class, }; } public static Test suite() { 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 new file mode 100644 index 000000000..d71cc4477 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java @@ -0,0 +1,1095 @@ +/******************************************************************************* + * Copyright (c) 2000, 2013 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 + *******************************************************************************/ +package org.eclipse.jdt.core.tests.dom; + +import java.util.List; + +import junit.framework.Test; + +import org.eclipse.jdt.core.dom.*; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.AnnotatableType; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.SimpleType; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; +import org.eclipse.jdt.core.dom.TypeDeclaration; + +public class ASTConverter18Test extends ConverterTestSetup { + + ICompilationUnit workingCopy; + + public void setUpSuite() throws Exception { + super.setUpSuite(); + this.ast = AST.newAST(AST.JLS8); + } + + public ASTConverter18Test(String name) { + super(name); + } + + static { +// TESTS_NUMBERS = new int[] { 19 }; +// TESTS_RANGE = new int[] { 1, -1 }; +// TESTS_NAMES = new String[] {"test0001"}; + } + public static Test suite() { + return buildModelTestSuite(ASTConverter18Test.class); + } + + protected void tearDown() throws Exception { + super.tearDown(); + if (this.workingCopy != null) { + this.workingCopy.discardWorkingCopy(); + this.workingCopy = null; + } + } + + /* + * Type Annotations on Variable Arguments + */ + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391898 + public void test0001() throws JavaModelException { + String contents = + " @java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + " @interface Marker {\n" + + " }\n" + + "public class X {\n" + + " public void foo(int @Marker... args) {\n" + + " }\n" + + " public void bar(@Marker int @Marker... args) {\n" + + " }\n" + + "}"; + this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); + ASTNode node = buildAST( + contents, + this.workingCopy); + assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); + CompilationUnit compilationUnit = (CompilationUnit) node; + assertProblemsSize(compilationUnit, 0); + node = getASTNode(compilationUnit, 1, 0); + assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); + MethodDeclaration methodDeclaration = (MethodDeclaration) node; + List parameters = methodDeclaration.parameters(); + assertEquals("wrong size", 1, parameters.size()); + SingleVariableDeclaration parameter = (SingleVariableDeclaration) parameters.get(0); + List annotations = parameter.varargsAnnotations(); + assertEquals("Wrong number of annotations", 1, annotations.size()); + ASTNode annotation = (ASTNode) annotations.get(0); + checkSourceRange(annotation, "@Marker", contents); + node = getASTNode(compilationUnit,1,1); + assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); + parameters = methodDeclaration.parameters(); + assertEquals("Wrong number of parameters", 1, parameters.size()); + parameter = (SingleVariableDeclaration) parameters.get(0); + annotations = parameter.varargsAnnotations(); + assertEquals("Wrong number of annotations", 1, annotations.size()); + annotation = (ASTNode) annotations.get(0); + checkSourceRange(annotation, "@Marker", contents); + } + /** + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 tests annotations on + * QTR in multiple scenarios of occurrence. + * + * @throws JavaModelException + */ + public void test0002() throws JavaModelException { + this.workingCopy = getWorkingCopy("/Converter18/src/test0002/X.java", + true/* resolve */); + String contents = "package test0002;\n" + + "import java.lang.annotation.Target;\n" + + "public class X {\n" + + " public static void main(String[] args) {\n" + + " Outer outer = new Outer();\n" + + " Object myObject = new Object();\n" + + " String myString;\n" + + " myString = (java.lang.@Marker String) myObject;\n" + + " Outer.Inner first = outer.new Inner();\n" + + " Outer. @Marker2 Inner second = outer.new Inner() ;\n" + + " Outer.Inner. @Marker1 Deeper deeper = second.new Deeper();\n" + + " Outer.@Marker1 Inner.@Marker2 Deeper deeper2 = second.new Deeper();\n" + + " }\n" + "}\n" + "class Outer {\n" + + " public class Inner {\n" + " public class Deeper {\n" + + " }\n" + " }\n" + "}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker {}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker1 {}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker2 {}\n"; + CompilationUnit cu = (CompilationUnit) buildAST(contents, + this.workingCopy); + MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(cu, 0, 0); + List statements = methodDeclaration.getBody().statements(); + int sCount = 3; + + // case 1 - annotation just before the last field + ExpressionStatement expressionStatement = (ExpressionStatement) statements.get(sCount++); + Assignment assignment = (Assignment) expressionStatement.getExpression(); + assertNotNull(assignment); + CastExpression castExpression = (CastExpression) assignment.getRightHandSide(); + assertNotNull(castExpression); + SimpleType simpleType = (SimpleType) castExpression.getType(); + assertNotNull(simpleType); + assertEquals("java.lang.@Marker String", simpleType.toString()); + List annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + assertEquals("@Marker", annotations.get(0).toString()); + + // case 2 - QualifiedType without annotations. + VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++); + Type type = variableDeclarationStatement.getType(); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + assertEquals("Outer.Inner", simpleType.toString()); + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 0); + + // case 3 - Qaulified Type with outer without annotations and inner with + // annotations. + variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++); + type = variableDeclarationStatement.getType(); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + assertNotNull(simpleType); + assertEquals("Outer.@Marker2 Inner", simpleType.toString()); + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + assertEquals("@Marker2", annotations.get(0).toString()); + + // case 4 - Multiple levels with annotations at the last only. + variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++); + type = variableDeclarationStatement.getType(); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + assertNotNull(simpleType); + assertEquals("Outer.Inner.@Marker1 Deeper", simpleType.toString()); + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + assertEquals("@Marker1", annotations.get(0).toString()); + + // case 5 - Multiple annotations + variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++); + type = variableDeclarationStatement.getType(); + assertTrue(type.isQualifiedType()); + QualifiedType qualifiedType = (QualifiedType) type; + assertNotNull(qualifiedType); + assertEquals("Outer.@Marker1 Inner.@Marker2 Deeper", qualifiedType.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 1); + assertEquals("@Marker2", annotations.get(0).toString()); + SimpleName simpleName = qualifiedType.getName(); + assertEquals("Deeper", simpleName.toString()); + Type qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isSimpleType()); + simpleType = (SimpleType) qualifierType; + assertEquals("Outer.@Marker1 Inner", simpleType.toString()); + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + assertEquals("@Marker1", annotations.get(0).toString()); + } + + /** + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 tests the + * representation of type annotations on a possible JAVA 7 and 8 place. + * + * @throws JavaModelException + */ + public void test0003() throws JavaModelException { + this.workingCopy = getWorkingCopy("/Converter18/src/test0003/X.java", + true/* resolve */); + String contents = "package test0003;\n" + + "import java.lang.annotation.Target;\n" + + "public class X {\n" + + " public static void main(String[] args) {\n" + + " @Marker Outer.Inner first[] = new Outer.Inner[1];\n" + + " }\n" + "}\n" + "class Outer {\n" + + " public class Inner {\n" + " }\n" + "}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker {}\n"; + CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); + MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(cu, 0, 0); + List statements = methodDeclaration.getBody().statements(); + int sCount = 0; + + // Current design expects annotation only at the JAVA 7 place if it is + // expected at JAVA 8. + VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount); + List modifiers = variableDeclarationStatement.modifiers(); + assertTrue(modifiers.size() == 1); + Annotation annotation = (Annotation) modifiers.get(0); + assertEquals("@Marker", annotation.toString()); + Type type = variableDeclarationStatement.getType(); + assertTrue(type.isSimpleType()); + SimpleType simpleType = (SimpleType) type; + assertEquals("Outer.Inner", simpleType.toString()); + List annotations = simpleType.annotations(); + assertTrue(annotations.size() == 0); + } + + /** + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 tests QTR with + * annotations + * + * @throws JavaModelException + */ + public void test0004() throws JavaModelException { + this.workingCopy = getWorkingCopy("/Converter18/src/test0004/X.java", + true/* resolve */); + String contents = "package test0004;" + + "import java.lang.annotation.Target;\n" + + "public class X implements One</*start*/@Marker1 Outer<Integer>. @Marker2 Inner<Double>[]/*end*/> {\n" + + "}\n" + "interface One<T> {}\n" + "class Outer<T> {\n" + + " public class Inner<S> {}\n" + "}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker1 {}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker2 {}\n"; + CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); + TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0); + ArrayType type = (ArrayType) ((ParameterizedType) typedeclaration.superInterfaceTypes().get(0)).typeArguments().get(0); + assertNotNull("No annotation", type); + ITypeBinding binding = type.resolveBinding(); + assertNotNull("No binding", binding); + assertEquals("Wrong qualified name", "test0004.Outer<java.lang.Integer>.Inner<java.lang.Double>[]", binding.getQualifiedName()); + Type componentType = type.getComponentType(); + binding = componentType.resolveBinding(); + assertNotNull("No binding", binding); + assertEquals("Wrong qualified name", + "test0004.Outer<java.lang.Integer>.Inner<java.lang.Double>", binding.getQualifiedName()); + assertTrue("Not parameterized", componentType.isParameterizedType()); + ParameterizedType parameterizedType = (ParameterizedType) componentType; + Type type2 = parameterizedType.getType(); + assertTrue("Not qualified", type2.isQualifiedType()); + QualifiedType qualifiedType = (QualifiedType) type2; + binding = qualifiedType.resolveBinding(); + assertNotNull("No binding", binding); + assertEquals("Wrong qualified name","test0004.Outer<java.lang.Integer>.Inner<java.lang.Double>", binding.getQualifiedName()); + Type qualifier = qualifiedType.getQualifier(); + assertTrue("Not parameterized", qualifier.isParameterizedType()); + binding = qualifier.resolveBinding(); + assertNotNull("No binding", binding); + assertEquals("Wrong qualified name", "test0004.Outer<java.lang.Integer>", binding.getQualifiedName()); + parameterizedType = (ParameterizedType) qualifier; + type2 = parameterizedType.getType(); + assertTrue("Not simple type", type2.isSimpleType()); + binding = type2.resolveBinding(); + assertNotNull("No binding", binding); + assertEquals("Wrong qualified name","test0004.Outer<java.lang.Integer>", binding.getQualifiedName()); + } + + /** + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 tests QTR with + * annotations + * + * @throws JavaModelException + */ + public void test0005() throws JavaModelException { + this.workingCopy = getWorkingCopy("/Converter18/src/test0005/X.java", + true/* resolve */); + String contents = "package test0005;" + + "import java.lang.annotation.Target;\n" + + "public class X implements One< Outer.Inner > {\n" + + "}\n" + + "class Y implements One< Outer. @Marker1 Inner > {\n" + + "}\n" + + "class Z implements One< @Marker1 Outer.Inner > {\n" + + "}\n" + + "class W implements One< @Marker1 Outer. @Marker2 Inner > {\n" + + "}\n" + "interface One<T> {}\n" + "class Outer {\n" + + " public class Inner {}\n" + "}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker1 {}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker2 {}\n"; + CompilationUnit cu = (CompilationUnit) buildAST(contents, + this.workingCopy); + int tCount = 0; + + // case 1 - no annotations Outer.Inner + TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + ParameterizedType parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + List typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + Type type = (Type) typeArguments.get(0); + assertTrue(type.isSimpleType()); + assertEquals("Outer.Inner", type.toString()); + + // case 2 - QTR with one annotation Outer.@Marker1 Inner + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration + .superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + type = (Type) typeArguments.get(0); + assertTrue(type.isSimpleType()); + SimpleType simpleType = (SimpleType) type; + assertEquals("Outer.@Marker1 Inner", simpleType.toString()); + List annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + Annotation annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + + // case 3 - QTR with one annotation at the beginning @Marker1 + // Outer.Inner + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + type = (Type) typeArguments.get(0); + assertTrue(type.isQualifiedType()); + assertEquals("@Marker1 Outer.Inner", type.toString()); + QualifiedType qualifiedType = (QualifiedType) type; + assertEquals("Inner", qualifiedType.getName().toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 0); + Type qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isSimpleType()); + simpleType = (SimpleType) qualifierType; + assertEquals("@Marker1 Outer", simpleType.toString()); + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + + // case 4 - QTR with annotations at both the types @Marker1 + // Outer.@Marker2 Inner + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + type = (Type) typeArguments.get(0); + assertTrue(type.isQualifiedType()); + assertEquals("@Marker1 Outer.@Marker2 Inner", type.toString()); + qualifiedType = (QualifiedType) type; + assertEquals("Inner", qualifiedType.getName().toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker2", annotation.toString()); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isSimpleType()); + simpleType = (SimpleType) qualifierType; + assertEquals("@Marker1 Outer", simpleType.toString()); + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + + } + + /** + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 tests PQTR with + * annotations part + * + * @throws JavaModelException + */ + public void test0006() throws JavaModelException { + this.workingCopy = getWorkingCopy("/Converter18/src/test0006/X.java", + true); + String contents = "package test0006;" + + "import java.lang.annotation.Target;\n" + + "public class X implements One<Outer. Inner.Deeper<Double>> {\n" + + "}\n" + + "class X1 implements One<Outer. @Marker1 Inner.Deeper<Double>> {\n" + + "}\n" + + "class X2 implements One<Outer. @Marker1 Inner.@Marker2 Deeper<Double>> {\n" + + "}\n" + + "class X3 implements One<@Marker1 Outer. @Marker2 Inner. Deeper<Double>> {\n" + + "}\n" + + "class Y implements One<Outer1. Inner<Integer>. Deeper<Double>> {\n" + + "}\n" + + "class Y1 implements One<Outer1. Inner<Integer>. @Marker1 Deeper<Double>> {\n" + + "}\n" + + "class Y2 implements One<Outer1. @Marker1 Inner<Integer>. Deeper<Double>> {\n" + + "}\n" + + "class Y3 implements One<@Marker1 Outer1. Inner<Integer>. Deeper<Double>> {\n" + + "}\n" + + "class Y4 implements One<@Marker1 Outer1. @Marker2 Inner<Integer>. Deeper<Double>> {\n" + + "}\n" + + "class Z implements One<Outer2<Integer>.Inner.Deeper<Double>> {\n" + + "}\n" + + "class Z1 implements One<@Marker1 Outer2<Integer>.Inner.Deeper<Double>> {\n" + + "}\n" + + "class Z2 implements One<Outer2<Integer>. @Marker1 Inner.@Marker2 Deeper<Double>> {\n" + + "}\n" + + "class W implements One<Outer3<Double>. @Marker1 @Marker2 Inner<Integer, Character>. Deeper<Double>> {\n" + + "}\n" + "interface One<T> {}\n" + "class Outer {\n" + + " public class Inner {\n" + + " public class Deeper<S> {\n" + " }\n" + " }\n" + + "}\n" + "class Outer1 {\n" + " public class Inner<T> {\n" + + " public class Deeper<S> {\n" + " }\n" + " }\n" + + "}\n" + "class Outer2 <T> {\n" + " public class Inner {\n" + + " public class Deeper<S> {}\n" + " }\n" + "}\n" + + "class Outer3 <T> {\n" + " public class Inner<K, V> {\n" + + " public class Deeper<S> {}\n" + " }\n" + "}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker1 {}\n" + + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker2 {}\n"; + CompilationUnit cu = (CompilationUnit) buildAST(contents, + this.workingCopy); + int tCount = 0; + + // case 1: vanilla case without annotations and with single typeArgument + // Outer.Inner.Deeper<Double> + TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + ParameterizedType parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + List typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("Outer.Inner.Deeper<Double>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + Type type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isSimpleType()); + SimpleType simpleType = (SimpleType) type; + assertEquals("Outer.Inner.Deeper", simpleType.toString()); + Name name = simpleType.getName(); + assertTrue(name.isQualifiedName()); + QualifiedName qualifiedName = (QualifiedName) name; + assertEquals("Outer.Inner.Deeper", qualifiedName.toString()); + + // case 2 - One annotation after the first class + // Outer. @Marker1 Inner.Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("Outer.@Marker1 Inner.Deeper<Double>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + QualifiedType qualifiedType = (QualifiedType) type; + assertEquals("Outer.@Marker1 Inner.Deeper", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + List annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 0); + Type qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isSimpleType()); + simpleType = (SimpleType) qualifierType; + assertEquals("Outer.@Marker1 Inner", simpleType.toString()); + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + Annotation annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + + // case 3 - Inner types annotated with outer not annotated with last + // type arg + // Outer. @Marker1 Inner.@Marker2 Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("Outer.@Marker1 Inner.@Marker2 Deeper<Double>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("Outer.@Marker1 Inner.@Marker2 Deeper", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker2", annotation.toString()); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isSimpleType()); + simpleType = (SimpleType) qualifierType; + assertEquals("Outer.@Marker1 Inner", simpleType.toString()); + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + + // case 4 - one annotation on the outermost, one in middle and one + // typearg in innermost + // @Marker1 Outer. @Marker2 Inner. Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration + .superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("@Marker1 Outer.@Marker2 Inner.Deeper<Double>", parametrizedType.toString()); + ITypeBinding typeBinding = parametrizedType.resolveBinding(); + assertNotNull("Binding non-null", typeBinding); + assertEquals("wrong qualified name", "test0006.Outer.Inner.Deeper<java.lang.Double>", typeBinding.getQualifiedName()); + assertTrue("Not a Parameterized Type", typeBinding.isParameterizedType()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("@Marker1 Outer.@Marker2 Inner.Deeper", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isQualifiedType()); + qualifiedType = (QualifiedType) qualifierType; + assertEquals("@Marker1 Outer.@Marker2 Inner", qualifierType.toString()); + typeBinding = qualifiedType.resolveBinding(); + assertNotNull("Binding non-null", typeBinding); + typeBinding = qualifiedType.resolveBinding(); + assertEquals("wrong qualified name", "test0006.Outer.Inner", typeBinding.getQualifiedName()); + assertTrue(qualifierType.isAnnotatable()); + AnnotatableType annotatableType = (AnnotatableType) qualifierType; + annotations = annotatableType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker2", annotation.toString()); + name = qualifiedType.getName(); + assertEquals("Inner", name.toString()); + type = qualifiedType.getQualifier(); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + assertEquals("@Marker1 Outer", simpleType.toString()); + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + + // case 5 - without annotations, but with typeargs at second and third + // types + // Outer1. Inner<Integer>. Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("Outer1.Inner<Integer>.Deeper<Double>",parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("Outer1.Inner<Integer>.Deeper", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 0); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isParameterizedType()); + parametrizedType = (ParameterizedType) qualifierType; + assertEquals("Outer1.Inner<Integer>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Integer", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + name = simpleType.getName(); + assertTrue(name.isQualifiedName()); + qualifiedName = (QualifiedName) name; + assertEquals("Outer1.Inner", qualifiedName.toString()); + + // case 6 - Annot in between two PQRT with outermost neither annotated + // nor having typeargs + // Outer1. Inner<Integer>. @Marker1 Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("Outer1.Inner<Integer>.@Marker1 Deeper<Double>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("Outer1.Inner<Integer>.@Marker1 Deeper", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isParameterizedType()); + parametrizedType = (ParameterizedType) qualifierType; + assertEquals("Outer1.Inner<Integer>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Integer", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + name = simpleType.getName(); + assertTrue(name.isQualifiedName()); + qualifiedName = (QualifiedName) name; + assertEquals("Outer1.Inner", qualifiedName.toString()); + + // case 7 - Outermost still empty (no annotations, no type args), + // followed by annotation, and then typeargs + // Outer1. @Marker1 Inner<Integer>. Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("Outer1.@Marker1 Inner<Integer>.Deeper<Double>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("Outer1.@Marker1 Inner<Integer>.Deeper", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 0); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isParameterizedType()); + parametrizedType = (ParameterizedType) qualifierType; + assertEquals("Outer1.@Marker1 Inner<Integer>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Integer", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + assertEquals("Outer1.@Marker1 Inner", simpleType.toString()); + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + + // case 8 - Similar to above, but with the major difference of + // annotation shifted to outermost. + // @Marker1 Outer1. Inner<Integer>. Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("@Marker1 Outer1.Inner<Integer>.Deeper<Double>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("@Marker1 Outer1.Inner<Integer>.Deeper", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 0); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isParameterizedType()); + parametrizedType = (ParameterizedType) qualifierType; + assertEquals("@Marker1 Outer1.Inner<Integer>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Integer", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("@Marker1 Outer1.Inner", qualifiedType.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 0); + name = qualifiedType.getName(); + assertTrue(name.isSimpleName()); + assertEquals("Inner", name.toString()); + type = qualifiedType.getQualifier(); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + name = simpleType.getName(); + assertTrue(name.isSimpleName()); + assertEquals("Outer1", name.toString()); + + // case 9: scenario of the above case plus another annotation at + // mid-level. + // @Marker1 Outer1.@Marker2 Inner<Integer>. Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("@Marker1 Outer1.@Marker2 Inner<Integer>.Deeper<Double>",parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("@Marker1 Outer1.@Marker2 Inner<Integer>.Deeper", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 0); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isParameterizedType()); + parametrizedType = (ParameterizedType) qualifierType; + assertEquals("@Marker1 Outer1.@Marker2 Inner<Integer>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Integer", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("@Marker1 Outer1.@Marker2 Inner", qualifiedType.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker2", annotation.toString()); + name = qualifiedType.getName(); + assertTrue(name.isSimpleName()); + assertEquals("Inner", name.toString()); + type = qualifiedType.getQualifier(); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + name = simpleType.getName(); + assertTrue(name.isSimpleName()); + assertEquals("Outer1", name.toString()); + + // case 10 - PQRT with two type args but without annotations + // Outer2<Integer>.Inner.Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("Outer2<Integer>.Inner.Deeper<Double>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("Outer2<Integer>.Inner.Deeper", qualifiedType.toString()); + ITypeBinding binding = qualifiedType.resolveBinding(); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 0); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isQualifiedType()); + qualifiedType = (QualifiedType) qualifierType; + binding = qualifiedType.resolveBinding(); + assertEquals("Outer2<Integer>.Inner", qualifiedType.toString()); + assertEquals("wrong qualified binding", "test0006.Outer2<java.lang.Integer>.Inner", binding.getQualifiedName()); + name = qualifiedType.getName(); + assertEquals("Inner", name.toString()); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isParameterizedType()); + parametrizedType = (ParameterizedType) qualifierType; + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Integer", type.toString()); + type = parametrizedType.getType(); + assertEquals("Outer2", type.toString()); + + // case 11 - annotation at outermost in addition to scenario in case 10. + // @Marker1 Outer2<Integer>.Inner.Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("@Marker1 Outer2<Integer>.Inner.Deeper<Double>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("@Marker1 Outer2<Integer>.Inner.Deeper", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 0); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isQualifiedType()); + qualifiedType = (QualifiedType) qualifierType; + assertEquals("@Marker1 Outer2<Integer>.Inner", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Inner", name.toString()); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isParameterizedType()); + parametrizedType = (ParameterizedType) qualifierType; + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Integer", type.toString()); + type = parametrizedType.getType(); + assertEquals("@Marker1 Outer2", type.toString()); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + annotations = simpleType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + + // case 12 - No annotations at outermost, but outermost has + // typeAnnotations. + // Outer2<Integer>. @Marker1 Inner.@Marker2 Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("Outer2<Integer>.@Marker1 Inner.@Marker2 Deeper<Double>", parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("Outer2<Integer>.@Marker1 Inner.@Marker2 Deeper",qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker2", annotation.toString()); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isQualifiedType()); + qualifiedType = (QualifiedType) qualifierType; + assertEquals("Outer2<Integer>.@Marker1 Inner", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Inner", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 1); + annotation = (Annotation) annotations.get(0); + assertEquals("@Marker1", annotation.toString()); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isParameterizedType()); + parametrizedType = (ParameterizedType) qualifierType; + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Integer", type.toString()); + type = parametrizedType.getType(); + assertEquals("Outer2", type.toString()); + assertTrue(type.isSimpleType()); + + // case 13 - a list of annotations and multiple typeArgument element + // lists. + // Outer3<Double>. @Marker1 @Marker2 Inner<Integer, Character>. + // Deeper<Double> + typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++); + parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0); + typeArguments = parametrizedType.typeArguments(); + assertEquals(1, typeArguments.size()); + parametrizedType = (ParameterizedType) typeArguments.get(0); + assertEquals("Outer3<Double>.@Marker1 @Marker2 Inner<Integer,Character>.Deeper<Double>",parametrizedType.toString()); + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + type = (Type) typeArguments.get(0); + assertEquals("Double", type.toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("Outer3<Double>.@Marker1 @Marker2 Inner<Integer,Character>.Deeper", qualifiedType.toString()); + name = qualifiedType.getName(); + assertEquals("Deeper", name.toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 0); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isParameterizedType()); + parametrizedType = (ParameterizedType) qualifierType; + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 2); + assertEquals("Integer", typeArguments.get(0).toString()); + assertEquals("Character", typeArguments.get(1).toString()); + type = parametrizedType.getType(); + assertTrue(type.isQualifiedType()); + qualifiedType = (QualifiedType) type; + assertEquals("Inner", qualifiedType.getName().toString()); + annotations = qualifiedType.annotations(); + assertTrue(annotations.size() == 2); + assertEquals("@Marker1", annotations.get(0).toString()); + assertEquals("@Marker2", annotations.get(1).toString()); + qualifierType = qualifiedType.getQualifier(); + assertTrue(qualifierType.isParameterizedType()); + parametrizedType = (ParameterizedType) qualifierType; + typeArguments = parametrizedType.typeArguments(); + assertTrue(typeArguments.size() == 1); + assertEquals("Double", typeArguments.get(0).toString()); + type = parametrizedType.getType(); + assertTrue(type.isSimpleType()); + simpleType = (SimpleType) type; + assertEquals("Outer3", simpleType.toString()); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391893 + public void test0007() throws JavaModelException { + String contents = + "public class X {\n" + + " public void foo(@Marker @Marker2 X this, @Marker2 @Marker int i){}\n" + + "}\n" + + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker {}\n" + + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker2 {}"; + 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 unit = (CompilationUnit) node; + node = getASTNode(unit, 0, 0); + assertEquals("Not a method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); + MethodDeclaration method = (MethodDeclaration) node; + AnnotatableType receiver = method.getReceiverType(); + assertEquals("Not an annotatable type", ASTNode.SIMPLE_TYPE, receiver.getNodeType()); + assertEquals("Incorrect receiver signature", "@Marker @Marker2 X", ((SimpleType) receiver).toString()); + assertEquals("Incorrect annotations on receiver", 2, ((SimpleType) receiver).annotations().size()); + assertNull("Incorrect receiver qualfier", method.getReceiverQualifier()); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391893 + public void test0008() throws JavaModelException { + String contents = + "public class X {\n" + + " class Y {\n" + + " public Y(@Marker @Marker2 X X.this, @Marker2 @Marker int i){}\n" + + " }\n" + + "}\n" + + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker {}\n" + + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + + "@interface Marker2 {}"; + + 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 unit = (CompilationUnit) node; + node = getASTNode(unit, 0, 0); + assertEquals("Not a type Declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); + TypeDeclaration innerType = (TypeDeclaration) node; + assertEquals("Incorrect no of methods", 1, innerType.getMethods().length); + MethodDeclaration method = innerType.getMethods()[0]; + AnnotatableType receiver = method.getReceiverType(); + assertEquals("Not an annotatable type", ASTNode.SIMPLE_TYPE, receiver.getNodeType()); + assertEquals("Incorrect receiver signature", "@Marker @Marker2 X", ((SimpleType) receiver).toString()); + assertEquals("Incorrect annotations on receiver", 2, ((SimpleType) receiver).annotations().size()); + assertNotNull("Incorrect receiver qualfier", method.getReceiverQualifier()); + assertEquals("Incorrect receiver qualfier", "X", method.getReceiverQualifier().getFullyQualifiedName()); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391895 + public void test0009() throws JavaModelException { + String contents = + "import java.lang.annotation.ElementType;\n" + + "public class X {\n" + + " class Y {\n" + + " @Annot int @Annot1 [] a @Annot2 @Annot3 [] @Annot3 @Annot2 [] @Annot4 [], b @Annot2 @Annot3 [] @Annot4 [], c [][][];\n" + + " public void foo1(@Annot int @Annot1 [] p @Annot2 @Annot3 [] @Annot3 @Annot2 [] @Annot4 @Annot3 []) {}\n" + + " public void foo2(@Annot int p [][]) {}\n" + + " @Annot String @Annot1 [] foo3() @Annot1 @Annot2 [][] { return null; }\n" + + " }\n" + + "}\n" + + "@java.lang.annotation.Target(value = {ElementType.TYPE_USE})\n" + + "@interface Annot {}\n" + + "@java.lang.annotation.Target(value = {ElementType.TYPE_USE})\n" + + "@interface Annot1 {}\n" + + "@java.lang.annotation.Target(value = {ElementType.TYPE_USE})\n" + + "@interface Annot2 {}\n" + + "@java.lang.annotation.Target(value = {ElementType.TYPE_USE})\n" + + "@interface Annot3 {}\n" + + "@java.lang.annotation.Target(value = {ElementType.TYPE_USE})\n" + + "@interface Annot4 {}"; + 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 unit = (CompilationUnit) node; + node = getASTNode(unit, 0, 0); + assertEquals("Not a type Declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); + TypeDeclaration type = (TypeDeclaration) node; + FieldDeclaration field = type.getFields()[0]; + List fragments = field.fragments(); + assertEquals("Incorrect no of fragments", 3, fragments.size()); + VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0); + assertExtraDimensionsEqual("Incorrect extra dimensions", fragment.extraDimensionInfos(), "@Annot2 @Annot3 [] @Annot3 @Annot2 [] @Annot4 []"); + fragment = (VariableDeclarationFragment) fragments.get(1); + assertExtraDimensionsEqual("Incorrect extra dimensions", fragment.extraDimensionInfos(), "@Annot2 @Annot3 [] @Annot4 []"); + fragment = (VariableDeclarationFragment) fragments.get(2); + assertExtraDimensionsEqual("Incorrect extra dimensions", fragment.extraDimensionInfos(), "[] [] []"); + MethodDeclaration[] methods = type.getMethods(); + assertEquals("Incorrect no of methods", 3, methods.length); + MethodDeclaration method = methods[0]; + List parameters = method.parameters(); + assertEquals("Incorrect no of parameters", 1, parameters.size()); + assertExtraDimensionsEqual("Incorrect extra dimensions", ((SingleVariableDeclaration) parameters.get(0)).extraDimensionInfos(), "@Annot2 @Annot3 [] @Annot3 @Annot2 [] @Annot4 @Annot3 []"); + + method = methods[1]; + parameters = method.parameters(); + assertEquals("Incorrect no of parameters", 1, parameters.size()); + assertExtraDimensionsEqual("Incorrect extra dimensions", ((SingleVariableDeclaration) parameters.get(0)).extraDimensionInfos(), "[] []"); + + method = methods[2]; + assertExtraDimensionsEqual("Incorrect extra dimensions", method.extraDimensionInfos(), "@Annot1 @Annot2 [] []"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399600 + public void test0010() throws JavaModelException { + String contents = + "import java.lang.annotation.ElementType;\n" + + "public class X {\n" + + " @Marker int foo(@Marker(\"Blah\") int z) @Marker [] @Marker [] {\n" + + " return null;\n" + + " }\n" + + "}\n" + + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + + "@interface Marker {\n" + + " String value() default \"Blah\";\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 unit = (CompilationUnit) node; + node = getASTNode(unit, 0, 0); + assertEquals("Not a method declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); + MethodDeclaration method = (MethodDeclaration) node; + assertExtraDimensionsEqual("Incorrect extra dimensions", method.extraDimensionInfos(), "@Marker [] @Marker []"); + } +} diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java index 6daa07aad..97ccf30fd 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 *******************************************************************************/ @@ -37,7 +41,16 @@ public class ASTConverterAST3Test extends ConverterTestSetup { public static Test suite() { return buildModelTestSuite(ASTConverterAST3Test.class); } - + /** + * Internal access method to VariableDeclarationFragment#setExtraDimensions() for avoiding deprecated warnings. + * + * @param node + * @param dimensions + * @deprecated + */ + private void internalSetExtraDimensions(VariableDeclarationFragment node, int dimensions) { + node.setExtraDimensions(dimensions); + } public void test0001() throws JavaModelException { ICompilationUnit sourceUnit = getCompilationUnit("Converter" , "src", "test0001", "Test.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ char[] source = sourceUnit.getSource().toCharArray(); @@ -2714,20 +2727,20 @@ public class ASTConverterAST3Test extends ConverterTestSetup { NumberLiteral literal = this.ast.newNumberLiteral(); literal.setToken("10");//$NON-NLS-1$ fragment.setInitializer(literal); - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); VariableDeclarationStatement statement = this.ast.newVariableDeclarationStatement(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("z"));//$NON-NLS-1$ fragment.setInitializer(this.ast.newNullLiteral()); - fragment.setExtraDimensions(1); + internalSetExtraDimensions(fragment, 1); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i"));//$NON-NLS-1$ - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("j"));//$NON-NLS-1$ - fragment.setExtraDimensions(2); + internalSetExtraDimensions(fragment, 2); statement.fragments().add(fragment); statement.setType(this.ast.newPrimitiveType(PrimitiveType.INT)); assertTrue("Both AST trees should be identical", statement.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ @@ -2754,20 +2767,20 @@ public class ASTConverterAST3Test extends ConverterTestSetup { NumberLiteral literal = this.ast.newNumberLiteral(); literal.setToken("10");//$NON-NLS-1$ fragment.setInitializer(literal); - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); VariableDeclarationStatement statement = this.ast.newVariableDeclarationStatement(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("z"));//$NON-NLS-1$ fragment.setInitializer(this.ast.newNullLiteral()); - fragment.setExtraDimensions(1); + internalSetExtraDimensions(fragment, 1); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i"));//$NON-NLS-1$ - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("j"));//$NON-NLS-1$ - fragment.setExtraDimensions(2); + internalSetExtraDimensions(fragment, 2); statement.fragments().add(fragment); statement.setType(this.ast.newArrayType(this.ast.newPrimitiveType(PrimitiveType.INT), 1)); assertTrue("Both AST trees should be identical", statement.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ @@ -2793,7 +2806,7 @@ public class ASTConverterAST3Test extends ConverterTestSetup { VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment(); variableDeclarationFragment.setName(this.ast.newSimpleName("tab")); //$NON-NLS-1$ variableDeclarationFragment.setInitializer(this.ast.newNullLiteral());//$NON-NLS-1$ - variableDeclarationFragment.setExtraDimensions(1); + internalSetExtraDimensions(variableDeclarationFragment, 1); VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment); variableDeclarationExpression.setType(this.ast.newArrayType(this.ast.newSimpleType(this.ast.newSimpleName("String")), 1));//$NON-NLS-1$ forStatement.initializers().add(variableDeclarationExpression); @@ -2821,7 +2834,7 @@ public class ASTConverterAST3Test extends ConverterTestSetup { VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment(); variableDeclarationFragment.setName(this.ast.newSimpleName("tab")); //$NON-NLS-1$ variableDeclarationFragment.setInitializer(this.ast.newNullLiteral());//$NON-NLS-1$ - variableDeclarationFragment.setExtraDimensions(1); + internalSetExtraDimensions(variableDeclarationFragment, 1); VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment); variableDeclarationExpression.setType(this.ast.newSimpleType(this.ast.newSimpleName("String")));//$NON-NLS-1$ forStatement.initializers().add(variableDeclarationExpression); @@ -2849,7 +2862,7 @@ public class ASTConverterAST3Test extends ConverterTestSetup { VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment(); variableDeclarationFragment.setName(this.ast.newSimpleName("tab")); //$NON-NLS-1$ variableDeclarationFragment.setInitializer(this.ast.newNullLiteral());//$NON-NLS-1$ - variableDeclarationFragment.setExtraDimensions(1); + internalSetExtraDimensions(variableDeclarationFragment, 1); VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment); variableDeclarationExpression.setType(this.ast.newSimpleType(this.ast.newSimpleName("String")));//$NON-NLS-1$ forStatement.initializers().add(variableDeclarationExpression); @@ -2878,7 +2891,7 @@ public class ASTConverterAST3Test extends ConverterTestSetup { assertTrue("Not a declaration", frag.getName().isDeclaration()); //$NON-NLS-1$ VariableDeclarationFragment fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i")); //$NON-NLS-1$ - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); FieldDeclaration fieldDeclaration = this.ast.newFieldDeclaration(fragment); fieldDeclaration.setType(this.ast.newPrimitiveType(PrimitiveType.INT)); assertTrue("Both AST trees should be identical", fieldDeclaration.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ @@ -2900,22 +2913,22 @@ public class ASTConverterAST3Test extends ConverterTestSetup { NumberLiteral literal = this.ast.newNumberLiteral(); literal.setToken("10"); //$NON-NLS-1$ fragment.setInitializer(literal); - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); FieldDeclaration fieldDeclaration = this.ast.newFieldDeclaration(fragment); fieldDeclaration.modifiers().add(this.ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); fieldDeclaration.setType(this.ast.newPrimitiveType(PrimitiveType.INT)); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("y"));//$NON-NLS-1$ - fragment.setExtraDimensions(1); + internalSetExtraDimensions(fragment, 1); fragment.setInitializer(this.ast.newNullLiteral()); fieldDeclaration.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i"));//$NON-NLS-1$ - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); fieldDeclaration.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("j"));//$NON-NLS-1$ - fragment.setExtraDimensions(2); + internalSetExtraDimensions(fragment, 2); fieldDeclaration.fragments().add(fragment); assertTrue("Both AST trees should be identical", fieldDeclaration.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ checkSourceRange(node, "public int x= 10, y[] = null, i, j[][];", source); //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java index 2d65325d6..b8d4af981 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2011 IBM Corporation and others. + * Copyright (c) 2013 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 *******************************************************************************/ @@ -37,7 +41,16 @@ public class ASTConverterAST4Test extends ConverterTestSetup { public static Test suite() { return buildModelTestSuite(ASTConverterAST4Test.class); } - + /** + * Internal access method to VariableDeclarationFragment#setExtraDimensions() for avoiding deprecated warnings. + * + * @param node + * @param dimensions + * @deprecated + */ + private void internalSetExtraDimensions(VariableDeclarationFragment node, int dimensions) { + node.setExtraDimensions(dimensions); + } public void test0001() throws JavaModelException { ICompilationUnit sourceUnit = getCompilationUnit("Converter" , "src", "test0001", "Test.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ char[] source = sourceUnit.getSource().toCharArray(); @@ -2714,20 +2727,20 @@ public class ASTConverterAST4Test extends ConverterTestSetup { NumberLiteral literal = this.ast.newNumberLiteral(); literal.setToken("10");//$NON-NLS-1$ fragment.setInitializer(literal); - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); VariableDeclarationStatement statement = this.ast.newVariableDeclarationStatement(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("z"));//$NON-NLS-1$ fragment.setInitializer(this.ast.newNullLiteral()); - fragment.setExtraDimensions(1); + internalSetExtraDimensions(fragment, 1); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i"));//$NON-NLS-1$ - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("j"));//$NON-NLS-1$ - fragment.setExtraDimensions(2); + internalSetExtraDimensions(fragment, 2); statement.fragments().add(fragment); statement.setType(this.ast.newPrimitiveType(PrimitiveType.INT)); assertTrue("Both AST trees should be identical", statement.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ @@ -2754,20 +2767,20 @@ public class ASTConverterAST4Test extends ConverterTestSetup { NumberLiteral literal = this.ast.newNumberLiteral(); literal.setToken("10");//$NON-NLS-1$ fragment.setInitializer(literal); - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); VariableDeclarationStatement statement = this.ast.newVariableDeclarationStatement(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("z"));//$NON-NLS-1$ fragment.setInitializer(this.ast.newNullLiteral()); - fragment.setExtraDimensions(1); + internalSetExtraDimensions(fragment, 1); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i"));//$NON-NLS-1$ - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("j"));//$NON-NLS-1$ - fragment.setExtraDimensions(2); + internalSetExtraDimensions(fragment, 2); statement.fragments().add(fragment); statement.setType(this.ast.newArrayType(this.ast.newPrimitiveType(PrimitiveType.INT), 1)); assertTrue("Both AST trees should be identical", statement.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ @@ -2793,7 +2806,7 @@ public class ASTConverterAST4Test extends ConverterTestSetup { VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment(); variableDeclarationFragment.setName(this.ast.newSimpleName("tab")); //$NON-NLS-1$ variableDeclarationFragment.setInitializer(this.ast.newNullLiteral());//$NON-NLS-1$ - variableDeclarationFragment.setExtraDimensions(1); + internalSetExtraDimensions(variableDeclarationFragment, 1); VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment); variableDeclarationExpression.setType(this.ast.newArrayType(this.ast.newSimpleType(this.ast.newSimpleName("String")), 1));//$NON-NLS-1$ forStatement.initializers().add(variableDeclarationExpression); @@ -2821,7 +2834,7 @@ public class ASTConverterAST4Test extends ConverterTestSetup { VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment(); variableDeclarationFragment.setName(this.ast.newSimpleName("tab")); //$NON-NLS-1$ variableDeclarationFragment.setInitializer(this.ast.newNullLiteral());//$NON-NLS-1$ - variableDeclarationFragment.setExtraDimensions(1); + internalSetExtraDimensions(variableDeclarationFragment, 1); VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment); variableDeclarationExpression.setType(this.ast.newSimpleType(this.ast.newSimpleName("String")));//$NON-NLS-1$ forStatement.initializers().add(variableDeclarationExpression); @@ -2849,7 +2862,7 @@ public class ASTConverterAST4Test extends ConverterTestSetup { VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment(); variableDeclarationFragment.setName(this.ast.newSimpleName("tab")); //$NON-NLS-1$ variableDeclarationFragment.setInitializer(this.ast.newNullLiteral());//$NON-NLS-1$ - variableDeclarationFragment.setExtraDimensions(1); + internalSetExtraDimensions(variableDeclarationFragment, 1); VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment); variableDeclarationExpression.setType(this.ast.newSimpleType(this.ast.newSimpleName("String")));//$NON-NLS-1$ forStatement.initializers().add(variableDeclarationExpression); @@ -2878,7 +2891,7 @@ public class ASTConverterAST4Test extends ConverterTestSetup { assertTrue("Not a declaration", frag.getName().isDeclaration()); //$NON-NLS-1$ VariableDeclarationFragment fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i")); //$NON-NLS-1$ - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); FieldDeclaration fieldDeclaration = this.ast.newFieldDeclaration(fragment); fieldDeclaration.setType(this.ast.newPrimitiveType(PrimitiveType.INT)); assertTrue("Both AST trees should be identical", fieldDeclaration.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ @@ -2900,22 +2913,22 @@ public class ASTConverterAST4Test extends ConverterTestSetup { NumberLiteral literal = this.ast.newNumberLiteral(); literal.setToken("10"); //$NON-NLS-1$ fragment.setInitializer(literal); - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); FieldDeclaration fieldDeclaration = this.ast.newFieldDeclaration(fragment); fieldDeclaration.modifiers().add(this.ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); fieldDeclaration.setType(this.ast.newPrimitiveType(PrimitiveType.INT)); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("y"));//$NON-NLS-1$ - fragment.setExtraDimensions(1); + internalSetExtraDimensions(fragment, 1); fragment.setInitializer(this.ast.newNullLiteral()); fieldDeclaration.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i"));//$NON-NLS-1$ - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); fieldDeclaration.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("j"));//$NON-NLS-1$ - fragment.setExtraDimensions(2); + internalSetExtraDimensions(fragment, 2); fieldDeclaration.fragments().add(fragment); assertTrue("Both AST trees should be identical", fieldDeclaration.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ checkSourceRange(node, "public int x= 10, y[] = null, i, j[][];", source); //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java index a72140c81..d0de9eed1 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2012 IBM Corporation and others. + * Copyright (c) 2011, 2013 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 @@ -37,6 +37,7 @@ public class ASTConverterAST8Test extends ConverterTestSetup { static { // TESTS_NUMBERS = new int[] { 356 }; +// TESTS_NAMES = new String[]{ "test0393" }; } public static Test suite() { return buildModelTestSuite(ASTConverterAST8Test.class); @@ -2718,20 +2719,23 @@ public class ASTConverterAST8Test extends ConverterTestSetup { NumberLiteral literal = this.ast.newNumberLiteral(); literal.setToken("10");//$NON-NLS-1$ fragment.setInitializer(literal); - fragment.setExtraDimensions(0); + fragment.extraDimensionInfos().clear(); VariableDeclarationStatement statement = this.ast.newVariableDeclarationStatement(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("z"));//$NON-NLS-1$ fragment.setInitializer(this.ast.newNullLiteral()); - fragment.setExtraDimensions(1); + fragment.extraDimensionInfos().clear(); + fragment.extraDimensionInfos().add(this.ast.newExtraDimension()); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i"));//$NON-NLS-1$ - fragment.setExtraDimensions(0); + fragment.extraDimensionInfos().clear(); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("j"));//$NON-NLS-1$ - fragment.setExtraDimensions(2); + fragment.extraDimensionInfos().clear(); + fragment.extraDimensionInfos().add(this.ast.newExtraDimension()); + fragment.extraDimensionInfos().add(this.ast.newExtraDimension()); statement.fragments().add(fragment); statement.setType(this.ast.newPrimitiveType(PrimitiveType.INT)); assertTrue("Both AST trees should be identical", statement.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ @@ -2758,20 +2762,23 @@ public class ASTConverterAST8Test extends ConverterTestSetup { NumberLiteral literal = this.ast.newNumberLiteral(); literal.setToken("10");//$NON-NLS-1$ fragment.setInitializer(literal); - fragment.setExtraDimensions(0); + fragment.extraDimensionInfos().clear(); VariableDeclarationStatement statement = this.ast.newVariableDeclarationStatement(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("z"));//$NON-NLS-1$ fragment.setInitializer(this.ast.newNullLiteral()); - fragment.setExtraDimensions(1); + fragment.extraDimensionInfos().clear(); + fragment.extraDimensionInfos().add(this.ast.newExtraDimension()); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i"));//$NON-NLS-1$ - fragment.setExtraDimensions(0); + fragment.extraDimensionInfos().clear(); statement.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("j"));//$NON-NLS-1$ - fragment.setExtraDimensions(2); + fragment.extraDimensionInfos().clear(); + fragment.extraDimensionInfos().add(this.ast.newExtraDimension()); + fragment.extraDimensionInfos().add(this.ast.newExtraDimension()); statement.fragments().add(fragment); statement.setType(this.ast.newArrayType(this.ast.newPrimitiveType(PrimitiveType.INT), 1)); assertTrue("Both AST trees should be identical", statement.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ @@ -2797,7 +2804,8 @@ public class ASTConverterAST8Test extends ConverterTestSetup { VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment(); variableDeclarationFragment.setName(this.ast.newSimpleName("tab")); //$NON-NLS-1$ variableDeclarationFragment.setInitializer(this.ast.newNullLiteral());//$NON-NLS-1$ - variableDeclarationFragment.setExtraDimensions(1); + variableDeclarationFragment.extraDimensionInfos().clear(); + variableDeclarationFragment.extraDimensionInfos().add(this.ast.newExtraDimension()); VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment); variableDeclarationExpression.setType(this.ast.newArrayType(this.ast.newSimpleType(this.ast.newSimpleName("String")), 1));//$NON-NLS-1$ forStatement.initializers().add(variableDeclarationExpression); @@ -2825,7 +2833,8 @@ public class ASTConverterAST8Test extends ConverterTestSetup { VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment(); variableDeclarationFragment.setName(this.ast.newSimpleName("tab")); //$NON-NLS-1$ variableDeclarationFragment.setInitializer(this.ast.newNullLiteral());//$NON-NLS-1$ - variableDeclarationFragment.setExtraDimensions(1); + variableDeclarationFragment.extraDimensionInfos().clear(); + variableDeclarationFragment.extraDimensionInfos().add(this.ast.newExtraDimension()); VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment); variableDeclarationExpression.setType(this.ast.newSimpleType(this.ast.newSimpleName("String")));//$NON-NLS-1$ forStatement.initializers().add(variableDeclarationExpression); @@ -2853,7 +2862,8 @@ public class ASTConverterAST8Test extends ConverterTestSetup { VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment(); variableDeclarationFragment.setName(this.ast.newSimpleName("tab")); //$NON-NLS-1$ variableDeclarationFragment.setInitializer(this.ast.newNullLiteral());//$NON-NLS-1$ - variableDeclarationFragment.setExtraDimensions(1); + variableDeclarationFragment.extraDimensionInfos().clear(); + variableDeclarationFragment.extraDimensionInfos().add(this.ast.newExtraDimension()); VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment); variableDeclarationExpression.setType(this.ast.newSimpleType(this.ast.newSimpleName("String")));//$NON-NLS-1$ forStatement.initializers().add(variableDeclarationExpression); @@ -2882,7 +2892,7 @@ public class ASTConverterAST8Test extends ConverterTestSetup { assertTrue("Not a declaration", frag.getName().isDeclaration()); //$NON-NLS-1$ VariableDeclarationFragment fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i")); //$NON-NLS-1$ - fragment.setExtraDimensions(0); + fragment.extraDimensionInfos().clear(); FieldDeclaration fieldDeclaration = this.ast.newFieldDeclaration(fragment); fieldDeclaration.setType(this.ast.newPrimitiveType(PrimitiveType.INT)); assertTrue("Both AST trees should be identical", fieldDeclaration.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ @@ -2904,22 +2914,25 @@ public class ASTConverterAST8Test extends ConverterTestSetup { NumberLiteral literal = this.ast.newNumberLiteral(); literal.setToken("10"); //$NON-NLS-1$ fragment.setInitializer(literal); - fragment.setExtraDimensions(0); + fragment.extraDimensionInfos().clear(); FieldDeclaration fieldDeclaration = this.ast.newFieldDeclaration(fragment); fieldDeclaration.modifiers().add(this.ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); fieldDeclaration.setType(this.ast.newPrimitiveType(PrimitiveType.INT)); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("y"));//$NON-NLS-1$ - fragment.setExtraDimensions(1); + fragment.extraDimensionInfos().clear(); + fragment.extraDimensionInfos().add(this.ast.newExtraDimension()); fragment.setInitializer(this.ast.newNullLiteral()); fieldDeclaration.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("i"));//$NON-NLS-1$ - fragment.setExtraDimensions(0); + fragment.extraDimensionInfos().clear(); fieldDeclaration.fragments().add(fragment); fragment = this.ast.newVariableDeclarationFragment(); fragment.setName(this.ast.newSimpleName("j"));//$NON-NLS-1$ - fragment.setExtraDimensions(2); + fragment.extraDimensionInfos().clear(); + fragment.extraDimensionInfos().add(this.ast.newExtraDimension()); + fragment.extraDimensionInfos().add(this.ast.newExtraDimension()); fieldDeclaration.fragments().add(fragment); assertTrue("Both AST trees should be identical", fieldDeclaration.subtreeMatch(new ASTMatcher(), node)); //$NON-NLS-1$ checkSourceRange(node, "public int x= 10, y[] = null, i, j[][];", source); //$NON-NLS-1$ @@ -8150,10 +8163,18 @@ public class ASTConverterAST8Test extends ConverterTestSetup { assertNotNull("not null", node); //$NON-NLS-1$ assertTrue("not a MethodDeclaration", node instanceof MethodDeclaration); //$NON-NLS-1$ MethodDeclaration methodDeclaration = (MethodDeclaration) node; - List thrownExceptions = methodDeclaration.thrownExceptions(); - assertEquals("Wrong size", 1, thrownExceptions.size()); //$NON-NLS-1$ - Name name = (Name) thrownExceptions.get(0); - IBinding binding = name.resolveBinding(); + IBinding binding; + if (node.getAST().apiLevel() < AST.JLS8) { + List thrownExceptions = methodDeclaration.thrownExceptions(); + assertEquals("Wrong size", 1, thrownExceptions.size()); //$NON-NLS-1$ + Name name = (Name) thrownExceptions.get(0); + binding = name.resolveBinding(); + } else { + List thrownExceptionTypes = methodDeclaration.thrownExceptionTypes(); + assertEquals("Wrong size", 1, thrownExceptionTypes.size()); //$NON-NLS-1$ + Type type = (Type) thrownExceptionTypes.get(0); + binding = type.resolveBinding(); + } assertEquals("wrong type", IBinding.TYPE, binding.getKind()); //$NON-NLS-1$ assertEquals("wrong name", "IOException", binding.getName()); //$NON-NLS-1$ //$NON-NLS-2$ } @@ -9583,6 +9604,8 @@ public class ASTConverterAST8Test extends ConverterTestSetup { assertNotNull("No type binding", typeBinding2); //$NON-NLS-1$ assertEquals("Wrong qualified name", "java.lang.String[]", typeBinding2.getQualifiedName()); //$NON-NLS-1$ //$NON-NLS-2$ assertEquals("Wrong dimension", 1, typeBinding2.getDimensions()); //$NON-NLS-1$ + List extraDimensions = methodDeclaration.extraDimensionInfos(); + assertExtraDimensionsEqual("Wrong extra extra dimensions", extraDimensions, "[]"); } /** @@ -9669,6 +9692,8 @@ public class ASTConverterAST8Test extends ConverterTestSetup { assertTrue("Not an array binding", typeBinding2.isArray()); //$NON-NLS-1$ assertEquals("Wrong dimension", 1, typeBinding2.getDimensions()); //$NON-NLS-1$ assertEquals("wrong fully qualified name", "java.lang.String[]", typeBinding2.getQualifiedName()); //$NON-NLS-1$ //$NON-NLS-2$ + List extraDimensions = singleVariableDeclaration.extraDimensionInfos(); + assertExtraDimensionsEqual("Wrong extra extra dimensions", extraDimensions, "[]"); } /** diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java index f34c99b78..6841c291b 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 *******************************************************************************/ @@ -8314,10 +8318,18 @@ public class ASTConverterTest extends ConverterTestSetup { assertNotNull("not null", node); //$NON-NLS-1$ assertTrue("not a MethodDeclaration", node instanceof MethodDeclaration); //$NON-NLS-1$ MethodDeclaration methodDeclaration = (MethodDeclaration) node; - List thrownExceptions = methodDeclaration.thrownExceptions(); - assertEquals("Wrong size", 1, thrownExceptions.size()); //$NON-NLS-1$ - Name name = (Name) thrownExceptions.get(0); - IBinding binding = name.resolveBinding(); + IBinding binding; + if (node.getAST().apiLevel() < AST.JLS8) { + List thrownExceptions = methodDeclaration.thrownExceptions(); + assertEquals("Wrong size", 1, thrownExceptions.size()); //$NON-NLS-1$ + Name name = (Name) thrownExceptions.get(0); + binding = name.resolveBinding(); + } else { + List thrownExceptionTypes = methodDeclaration.thrownExceptionTypes(); + assertEquals("Wrong size", 1, thrownExceptionTypes.size()); //$NON-NLS-1$ + Type type = (Type) thrownExceptionTypes.get(0); + binding = type.resolveBinding(); + } assertEquals("wrong type", IBinding.TYPE, binding.getKind()); //$NON-NLS-1$ assertEquals("wrong name", "IOException", binding.getName()); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST8_2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST8_2.java index ec2ff7a39..c725cb765 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST8_2.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST8_2.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2012 IBM Corporation and others. + * Copyright (c) 2011, 2013 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 @@ -378,7 +378,8 @@ public class ASTConverterTestAST8_2 extends ConverterTestSetup { compilationUnit.accept(bindingsCollectorVisitor); assertEquals("wrong number", 3, bindingsCollectorVisitor.getUnresolvedNodesSet().size()); //$NON-NLS-1$ Map bindingsMap = bindingsCollectorVisitor.getBindingsMap(); - assertEquals("wrong number", 211, bindingsMap.size()); //$NON-NLS-1$ + // changed to 212 - two bindings (type + name) for each Throwable derivatives. + assertEquals("wrong number", 212, bindingsMap.size()); //$NON-NLS-1$ ASTNodesCollectorVisitor nodesCollector = new ASTNodesCollectorVisitor(); compilationUnit.accept(nodesCollector); Set detachedNodes = nodesCollector.getDetachedAstNodes(); @@ -528,10 +529,18 @@ public class ASTConverterTestAST8_2 extends ConverterTestSetup { assertNotNull(node); assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); //$NON-NLS-1$ MethodDeclaration methodDeclaration = (MethodDeclaration) node; - List throwsException = methodDeclaration.thrownExceptions(); - assertEquals("wrong size", 2, throwsException.size()); //$NON-NLS-1$ - Name name = (Name) throwsException.get(0); - IBinding binding = name.resolveBinding(); + IBinding binding; + if (node.getAST().apiLevel() < AST.JLS8) { + List throwsException = methodDeclaration.thrownExceptions(); + assertEquals("wrong size", 2, throwsException.size()); //$NON-NLS-1$ + Name name = (Name) throwsException.get(0); + binding = name.resolveBinding(); + } else { + List throwsExceptionTypes = methodDeclaration.thrownExceptionTypes(); + assertEquals("wrong size", 2, throwsExceptionTypes.size()); //$NON-NLS-1$ + Type type = (Type) throwsExceptionTypes.get(0); + binding = type.resolveBinding(); + } assertNotNull("No binding", binding); //$NON-NLS-1$ assertEquals("LIOException;", binding.getKey()); assertTrue("Binding should be marked as recovered", binding.isRecovered()); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java index 32a444755..1d41acb27 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 *******************************************************************************/ @@ -39,6 +43,8 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T if (methods[i].getName().startsWith("test")) { //$NON-NLS-1$ suite.addTest(new ASTMatcherTest(methods[i].getName(), AST.JLS2)); suite.addTest(new ASTMatcherTest(methods[i].getName(), JLS3_INTERNAL)); + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391898 + suite.addTest(new ASTMatcherTest(methods[i].getName(), AST.JLS8)); } } return suite; @@ -62,6 +68,8 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T Block B1; SingleVariableDeclaration V1; SingleVariableDeclaration V2; + AnnotatableType R1; + Name Q1; VariableDeclarationFragment W1; VariableDeclarationFragment W2; FieldDeclaration FD1; @@ -95,7 +103,8 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T Modifier MOD2; EnumConstantDeclaration EC1; EnumConstantDeclaration EC2; - + Type T3; + Type T4; final StringBuffer b = new StringBuffer(); int API_LEVEL; @@ -127,6 +136,10 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T this.S1 = this.ast.newContinueStatement(); this.S2 = this.ast.newBreakStatement(); this.B1 = this.ast.newBlock(); + if (this.ast.apiLevel() >= AST.JLS8) { + this.R1 = this.ast.newSimpleType(this.ast.newSimpleName("XYZ")); + this.Q1 = this.ast.newSimpleName("XYZ"); + } this.V1 = this.ast.newSingleVariableDeclaration(); this.V1.setType(this.ast.newPrimitiveType(PrimitiveType.INT)); this.V1.setName(this.ast.newSimpleName("a")); //$NON-NLS-1$ @@ -225,7 +238,10 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T this.EC2 = this.ast.newEnumConstantDeclaration(); this.EC2.setName(this.ast.newSimpleName("G")); //$NON-NLS-1$ } - + if (this.ast.apiLevel() >= AST.JLS8) { + this.T3 = this.ast.newSimpleType(this.ast.newSimpleName("U")); //$NON-NLS-1$ + this.T4 = this.ast.newSimpleType(this.ast.newSimpleName("V")); //$NON-NLS-1$ + } } protected void tearDown() throws Exception { @@ -986,12 +1002,20 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T x1.typeParameters().add(this.TP1); x1.typeParameters().add(this.TP2); x1.setReturnType2(this.T1); + if (this.ast.apiLevel() >= AST.JLS8) { + x1.setReceiverType(this.R1); + } } x1.setName(this.N1); x1.parameters().add(this.V1); x1.parameters().add(this.V2); - x1.thrownExceptions().add(this.N2); - x1.thrownExceptions().add(this.N3); + if (this.ast.apiLevel() < AST.JLS8) { + x1.thrownExceptions().add(this.N2); + x1.thrownExceptions().add(this.N3); + } else { + x1.thrownExceptionTypes().add(this.T3); + x1.thrownExceptionTypes().add(this.T4); + } x1.setBody(this.B1); basicMatch(x1); } @@ -1320,4 +1344,45 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T basicMatch(x1); } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391898 + public void testSingleVariableDeclarationVarargsAnnotation() { + if (this.ast.apiLevel() < AST.JLS8) { + return; + } + SingleVariableDeclaration x1 = this.ast.newSingleVariableDeclaration(); + x1.setType(this.T1); + x1.setName(this.N1); + x1.setVarargs(true); + x1.varargsAnnotations().add(this.ANO1); + basicMatch(x1); + } + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 + public void testQualifiedTypeAnnotation() { + if (this.ast.apiLevel() < AST.JLS8) { + return; + } + QualifiedType x1 = this.ast.newQualifiedType(this.T1, this.N1); + x1.annotations().add(this.ANO1); + x1 = this.ast.newQualifiedType(x1, this.N2); + x1.annotations().add(this.ANO2); + basicMatch(x1); + } + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 + public void testParameterizedQualifiedTypeAnnotation() { + if (this.ast.apiLevel() < AST.JLS8) { + return; + } + QualifiedType qualifiedType = this.ast.newQualifiedType(this.T1, this.N1); + qualifiedType.annotations().add(this.ANO1); + ParameterizedType x1 = this.ast.newParameterizedType(qualifiedType); + x1.typeArguments().add(this.ast.newSimpleType(this.ast.newSimpleName("SN1"))); + qualifiedType = this.ast.newQualifiedType(x1, this.N2); + x1 = this.ast.newParameterizedType(qualifiedType); + SimpleType simpleType = this.ast.newSimpleType(this.ast.newSimpleName("SN2")); + simpleType.annotations().add(this.ANO2); + x1.typeArguments().add(simpleType); + basicMatch(x1); + } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java index c644091ed..a27192565 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2013 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 * Technical University Berlin - adapted for Object Teams @@ -391,10 +395,10 @@ public class ASTStructuralPropertyTest extends org.eclipse.jdt.core.tests.junit. } // {ObjectTeams: adapted for OT specific ASTNodes /* orig: - assertTrue(hi == 84); // last known one + assertEquals("Wrong last known type", 85, hi); // last known one :giro */ - assertTrue(hi == 100); // last known one + assertEquals("Wrong last known type", 101, hi); // last known one // jwl} - assertTrue(classes.size() == hi); // all classes are distinct + assertEquals("Wrong number of distinct types", hi, classes.size()); // all classes are distinct } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java index 0d57f96b7..7f173d82e 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 * Technical University Berlin - adapted for Object Teams @@ -786,6 +790,15 @@ public class ASTTest extends org.eclipse.jdt.core.tests.junit.extension.TestCase } /** + * Internal access method to VariableDeclarationFragment#setExtraDimensions for avoiding deprecated warnings. + * + * @param node + * @deprecated + */ + private void setExtraDimensions(VariableDeclarationFragment node, int dimensions) { + node.setExtraDimensions(dimensions); + } + /** * Snippets that show how to... * @deprecated using deprecated code */ @@ -3314,18 +3327,18 @@ public class ASTTest extends org.eclipse.jdt.core.tests.junit.extension.TestCase assertTrue(this.ast.modificationCount() == previousCount); previousCount = this.ast.modificationCount(); - x.setExtraDimensions(1); + setExtraDimensions(x, 1); assertTrue(this.ast.modificationCount() > previousCount); assertTrue(x.getExtraDimensions() == 1); previousCount = this.ast.modificationCount(); - x.setExtraDimensions(0); + setExtraDimensions(x, 0); assertTrue(this.ast.modificationCount() > previousCount); assertTrue(x.getExtraDimensions() == 0); // check that property cannot be set negative try { - x.setExtraDimensions(-1); + setExtraDimensions(x, -1); assertTrue(false); } catch (RuntimeException e) { // pass @@ -3413,7 +3426,11 @@ public class ASTTest extends org.eclipse.jdt.core.tests.junit.extension.TestCase assertTrue(x.getExtraDimensions() == 0); assertTrue(x.getJavadoc() == null); assertTrue(x.parameters().size() == 0); - assertTrue(x.thrownExceptions().size() == 0); + if (this.ast.apiLevel() < AST.JLS8) { + assertTrue(x.thrownExceptions().size() == 0); + } else { + assertTrue(x.thrownExceptionTypes().size() == 0); + } assertTrue(x.getBody() == null); assertTrue(x.getNodeType() == ASTNode.METHOD_DECLARATION); assertTrue(x.structuralPropertiesForType() == @@ -3553,16 +3570,29 @@ public class ASTTest extends org.eclipse.jdt.core.tests.junit.extension.TestCase } }); - genericPropertyListTest(x, x.thrownExceptions(), - new Property("ThrownExceptions", true, Name.class) { //$NON-NLS-1$ - public ASTNode sample(AST targetAst, boolean parented) { - SimpleName result = targetAst.newSimpleName("foo"); //$NON-NLS-1$ - if (parented) { - targetAst.newExpressionStatement(result); - } - return result; - } - }); + if (this.ast.apiLevel() < AST.JLS8) { + genericPropertyListTest(x, x.thrownExceptions(), + new Property("ThrownExceptions", true, Name.class) { //$NON-NLS-1$ + public ASTNode sample(AST targetAst, boolean parented) { + SimpleName result = targetAst.newSimpleName("foo"); //$NON-NLS-1$ + if (parented) { + targetAst.newExpressionStatement(result); + } + return result; + } + }); + } else { + genericPropertyListTest(x, x.thrownExceptionTypes(), + new Property("ThrownExceptionTypes", true, Type.class) { //$NON-NLS-1$ + public ASTNode sample(AST targetAst, boolean parented) { + Type result = targetAst.newSimpleType(targetAst.newSimpleName("foo")); //$NON-NLS-1$ + if (parented) { + targetAst.newArrayType(result); + } + return result; + } + }); + } genericPropertyTest(x, new Property("Body", false, Block.class) { //$NON-NLS-1$ public ASTNode sample(AST targetAst, boolean parented) { diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java index faf7a5087..5817b3726 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 *******************************************************************************/ @@ -119,7 +123,11 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T String EC1S; EnumConstantDeclaration EC2; String EC2S; - + Type T3; + String T3S; + Type T4; + String T4S; + final StringBuffer b = new StringBuffer(); int API_LEVEL; @@ -279,7 +287,13 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T this.EC2.setName(this.ast.newSimpleName("d")); //$NON-NLS-1$ this.EC2S = "[(ECD[(nSddnS)]ECD)]"; //$NON-NLS-1$ } - + if (this.ast.apiLevel() >= AST.JLS8) { + this.T3 = this.ast.newSimpleType(this.ast.newSimpleName("W")); //$NON-NLS-1$ + this.T3S = "[(tS[(nSWWnS)]tS)]"; //$NON-NLS-1$ + this.T4 = this.ast.newSimpleType(this.ast.newSimpleName("X")); //$NON-NLS-1$ + this.T4S = "[(tS[(nSXXnS)]tS)]"; //$NON-NLS-1$ + } + } protected void tearDown() throws Exception { @@ -1623,8 +1637,13 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T x1.setName(this.N1); x1.parameters().add(this.V1); x1.parameters().add(this.V2); - x1.thrownExceptions().add(this.N2); - x1.thrownExceptions().add(this.N3); + if (this.ast.apiLevel() < AST.JLS8) { + x1.thrownExceptions().add(this.N2); + x1.thrownExceptions().add(this.N3); + } else { + x1.thrownExceptions().add(this.T3); + x1.thrownExceptions().add(this.T4); + } x1.setBody(this.B1); TestVisitor v1 = new TestVisitor(); this.b.setLength(0); @@ -1632,8 +1651,10 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T String result = this.b.toString(); if (this.ast.apiLevel() == AST.JLS2) { assertTrue(result.equals("[(MD"+this.JD1S+this.T1S+this.N1S+this.V1S+this.V2S+this.N2S+this.N3S+this.B1S+"MD)]")); //$NON-NLS-1$ //$NON-NLS-2$ - } else { + } else if (this.ast.apiLevel() < AST.JLS8) { assertTrue(result.equals("[(MD"+this.JD1S+this.MOD1S+this.MOD2S+this.TP1S+this.T1S+this.N1S+this.V1S+this.V2S+this.N2S+this.N3S+this.B1S+"MD)]")); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + assertTrue(result.equals("[(MD"+this.JD1S+this.MOD1S+this.MOD2S+this.TP1S+this.T1S+this.T3S+this.V1S+this.V2S+this.T4S+this.N3S+this.B1S+"MD)]")); //$NON-NLS-1$ //$NON-NLS-2$ } } /** @deprecated using deprecated code */ diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java index cdbc4a0bb..8694f6700 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -15,6 +15,7 @@ package org.eclipse.jdt.core.tests.dom; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -141,6 +142,26 @@ public abstract class ConverterTestSetup extends AbstractASTTests { } } + protected void assertExtraDimensionsEqual(String message, List dimensions, String expected) { + StringBuffer buffer = new StringBuffer(); + Iterator iter = dimensions.iterator(); + while(iter.hasNext()) { + ExtraDimension dim = (ExtraDimension) iter.next(); + Iterator annotations = dim.annotations().iterator(); + while (annotations.hasNext()) { + buffer.append('@'); + buffer.append(((Annotation) annotations.next()).getTypeName().getFullyQualifiedName()); + buffer.append(' '); + } + if (iter.hasNext()) { + buffer.append("[] "); + } else { + buffer.append("[]"); + } + } + assertEquals(message, expected, buffer.toString()); + } + public ASTNode runConversion(ICompilationUnit unit, boolean resolveBindings, boolean bindingsRecovery) { return runConversion(astInternalJLS2(), unit, resolveBindings, false, bindingsRecovery); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java index e0e11c12d..091821b71 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 *******************************************************************************/ @@ -46,6 +50,7 @@ public static Class[] getAllTestClasses() { ASTConverter15JLS4Test.class, ASTConverter15JLS8Test.class, TypeAnnotationsConverterTest.class, + ASTConverter18Test.class, }; } public static Test suite() { diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingMethodDeclTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingMethodDeclTest.java index 63b0aa5b9..113642a4b 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingMethodDeclTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingMethodDeclTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 *******************************************************************************/ @@ -30,6 +34,13 @@ public class ASTRewritingMethodDeclTest extends ASTRewritingTest { private static final Class THIS= ASTRewritingMethodDeclTest.class; + /** + * Internal synonym for deprecated constant MethodDeclaration#EXTRA_DIMENSIONS_PROPERTY + * to alleviate deprecated warnings. + * @deprecated + */ + static final SimplePropertyDescriptor INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY = MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY; + public ASTRewritingMethodDeclTest(String name) { super(name); } @@ -1447,7 +1458,7 @@ public class ASTRewritingMethodDeclTest extends ASTRewritingTest { { // add extra dim, add throws MethodDeclaration methodDecl= findMethodDeclaration(type, "foo1"); - rewrite.set(methodDecl, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY, new Integer(1), null); + rewrite.set(methodDecl, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY, new Integer(1), null); Name newThrownException2= ast.newSimpleName("ArrayStoreException"); rewrite.getListRewrite(methodDecl, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY).insertLast(newThrownException2, null); @@ -1456,14 +1467,14 @@ public class ASTRewritingMethodDeclTest extends ASTRewritingTest { { // add extra dim, remove throws MethodDeclaration methodDecl= findMethodDeclaration(type, "foo2"); - rewrite.set(methodDecl, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY, new Integer(1), null); + rewrite.set(methodDecl, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY, new Integer(1), null); rewrite.remove((ASTNode) methodDecl.thrownExceptions().get(0), null); } { // remove extra dim, add throws MethodDeclaration methodDecl= findMethodDeclaration(type, "foo3"); - rewrite.set(methodDecl, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY, new Integer(1), null); + rewrite.set(methodDecl, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY, new Integer(1), null); Name newThrownException2= ast.newSimpleName("ArrayStoreException"); rewrite.getListRewrite(methodDecl, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY).insertLast(newThrownException2, null); @@ -1472,7 +1483,7 @@ public class ASTRewritingMethodDeclTest extends ASTRewritingTest { { // add extra dim, remove throws MethodDeclaration methodDecl= findMethodDeclaration(type, "foo4"); - rewrite.set(methodDecl, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY, new Integer(1), null); + rewrite.set(methodDecl, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY, new Integer(1), null); rewrite.remove((ASTNode) methodDecl.thrownExceptions().get(0), null); } @@ -1483,7 +1494,7 @@ public class ASTRewritingMethodDeclTest extends ASTRewritingTest { rewrite.getListRewrite(methodDecl, MethodDeclaration.PARAMETERS_PROPERTY).insertLast(newParam1, null); - rewrite.set(methodDecl, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY, new Integer(4), null); + rewrite.set(methodDecl, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY, new Integer(4), null); Name newThrownException2= ast.newSimpleName("ArrayStoreException"); rewrite.getListRewrite(methodDecl, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY).insertLast(newThrownException2, null); @@ -1494,7 +1505,7 @@ public class ASTRewritingMethodDeclTest extends ASTRewritingTest { rewrite.remove((ASTNode) methodDecl.parameters().get(0), null); - rewrite.set(methodDecl, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY, new Integer(4), null); + rewrite.set(methodDecl, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY, new Integer(4), null); rewrite.remove((ASTNode) methodDecl.thrownExceptions().get(0), null); } @@ -2006,7 +2017,7 @@ public class ASTRewritingMethodDeclTest extends ASTRewritingTest { MethodDeclaration methodDecl= findMethodDeclaration(type, "DD"); rewrite.set(methodDecl, MethodDeclaration.CONSTRUCTOR_PROPERTY, Boolean.TRUE, null); - rewrite.set(methodDecl, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY, new Integer(0), null); + rewrite.set(methodDecl, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY, new Integer(0), null); } String preview= evaluateRewrite(cu, rewrite); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java index 429dce8b3..2b98eb4d6 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 *******************************************************************************/ @@ -51,7 +55,16 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { // suite.addTest(new ASTRewritingStatementsTest("testTryStatementWithResources5")); // return suite; } - + /** + * Internal access method to VariableDeclarationFragment#setExtraDimensions() for avoiding deprecated warnings + * + * @param node + * @param dimensions + * @deprecated + */ + private void internalSetExtraDimensions(VariableDeclarationFragment node, int dimensions) { + node.setExtraDimensions(dimensions); + } public void testInsert1() throws Exception { IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null); /* foo(): append a return statement */ @@ -5156,7 +5169,7 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { TryStatement tryStatement = (TryStatement) statement; VariableDeclarationFragment fragment = ast.newVariableDeclarationFragment(); - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); fragment.setName(ast.newSimpleName("reader2")); ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation(); classInstanceCreation.setType(ast.newSimpleType(ast.newSimpleName("FileReader"))); @@ -5234,7 +5247,7 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { TryStatement tryStatement = (TryStatement) statement; VariableDeclarationFragment fragment = ast.newVariableDeclarationFragment(); - fragment.setExtraDimensions(0); + internalSetExtraDimensions(fragment, 0); fragment.setName(ast.newSimpleName("reader2")); ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation(); classInstanceCreation.setType(ast.newSimpleType(ast.newSimpleName("FileReader"))); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTrackingTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTrackingTest.java index 638256980..8107a81f0 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTrackingTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTrackingTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 *******************************************************************************/ @@ -45,7 +49,16 @@ public class ASTRewritingTrackingTest extends ASTRewritingTest { public static Test suite() { return allTests(); } - + /** + * Internal access method to VariableDeclarationFragment#setExtraDimensions() for avoiding deprecated warnings + * + * @param node + * @param dimensions + * @deprecated + */ + private void internalSetExtraDimensions(VariableDeclarationFragment node, int dimensions) { + node.setExtraDimensions(dimensions); + } public void testNamesWithDelete() throws Exception { IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null); @@ -159,7 +172,7 @@ public class ASTRewritingTrackingTest extends ASTRewritingTest { VariableDeclarationFragment newFrag= ast.newVariableDeclarationFragment(); newFrag.setName(ast.newSimpleName("newVariable")); - newFrag.setExtraDimensions(2); + internalSetExtraDimensions(newFrag, 2); rewrite.getListRewrite(field, FieldDeclaration.FRAGMENTS_PROPERTY).insertFirst(newFrag, null); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTypeDeclTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTypeDeclTest.java index 7f9a19267..f26d5b132 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTypeDeclTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTypeDeclTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 *******************************************************************************/ @@ -27,6 +31,19 @@ public class ASTRewritingTypeDeclTest extends ASTRewritingTest { private static final Class THIS= ASTRewritingTypeDeclTest.class; + /** + * Internal synonym for deprecated constant SingleVariableDeclaration#EXTRA_DIMENSIONS_PROPERTY + * to alleviate deprecated warnings. + * @deprecated + */ + static final SimplePropertyDescriptor INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY = SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY; + /** + * Internal synonym for deprecated constant VariableDeclarationFragment#EXTRA_DIMENSIONS_PROPERTY + * to alleviate deprecated warnings. + * @deprecated + */ + static final SimplePropertyDescriptor INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY = VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY; + public ASTRewritingTypeDeclTest(String name) { super(name); } @@ -1000,7 +1017,7 @@ public class ASTRewritingTypeDeclTest extends ASTRewritingTest { int newModifiers= Modifier.FINAL; rewrite.set(decl, SingleVariableDeclaration.MODIFIERS_PROPERTY, new Integer(newModifiers), null); - rewrite.set(decl, SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY, new Integer(1), null); + rewrite.set(decl, INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY, new Integer(1), null); ArrayType newVarType= ast.newArrayType(ast.newPrimitiveType(PrimitiveType.FLOAT), 2); rewrite.replace(decl.getType(), newVarType, null); @@ -1020,7 +1037,7 @@ public class ASTRewritingTypeDeclTest extends ASTRewritingTest { { // remove extra dim SingleVariableDeclaration decl= (SingleVariableDeclaration) arguments.get(2); - rewrite.set(decl, SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY, new Integer(0), null); + rewrite.set(decl, INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY, new Integer(0), null); } String preview= evaluateRewrite(cu, rewrite); @@ -1069,7 +1086,7 @@ public class ASTRewritingTypeDeclTest extends ASTRewritingTest { ASTNode name= ast.newSimpleName("a"); rewrite.replace(fragment.getName(), name, null); - rewrite.set(fragment, VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY, new Integer(2), null); + rewrite.set(fragment, INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY, new Integer(2), null); } { // add initializer @@ -1090,7 +1107,7 @@ public class ASTRewritingTypeDeclTest extends ASTRewritingTest { { // add dimension, add initializer VariableDeclarationFragment fragment= (VariableDeclarationFragment) fragments.get(3); - rewrite.set(fragment, VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY, new Integer(4), null); + rewrite.set(fragment, INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY, new Integer(4), null); assertTrue("Has initializer", fragment.getInitializer() == null); @@ -1100,7 +1117,7 @@ public class ASTRewritingTypeDeclTest extends ASTRewritingTest { { // remove dimension VariableDeclarationFragment fragment= (VariableDeclarationFragment) fragments.get(4); - rewrite.set(fragment, VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY, new Integer(0), null); + rewrite.set(fragment, INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY, new Integer(0), null); } String preview= evaluateRewrite(cu, rewrite); diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter18/src/X.java b/org.eclipse.jdt.core.tests.model/workspace/Converter18/src/X.java new file mode 100644 index 000000000..5a1a8880f --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/workspace/Converter18/src/X.java @@ -0,0 +1,4 @@ +public class X { + public void foo(X this) { + } +} 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 b0a1846d3..f8d10da67 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -163,6 +163,8 @@ * DereferencingNullableExpression * NullityMismatchingTypeAnnotation * NullityMismatchingTypeAnnotationUnchecked + * Jesper S Moller - added the following constants + * TargetTypeNotAFunctionalInterface *******************************************************************************/ package org.eclipse.jdt.core.compiler; @@ -1333,6 +1335,12 @@ void setSourceStart(int sourceStart); int IllegalTypeForExplicitThis = Internal + Syntax + 650; /** @since 3.9 */ int IllegalQualifierForExplicitThis = Internal + Syntax + 651; + /** @since 3.9 */ + int IllegalQualifierForExplicitThis2 = Internal + Syntax + 652; + /** @since 3.9 */ + int TargetTypeNotAFunctionalInterface = Internal + TypeRelated + 653; + /** @since 3.9 */ + int IllegalVarargInLambda = Internal + TypeRelated + 654; /** * More problems in generics diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java index 2a624dd60..8cae07549 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -513,6 +513,12 @@ public abstract class ASTVisitor { public void endVisit(Wildcard wildcard, ClassScope scope) { // do nothing by default } + public void endVisit(LambdaExpression lambdaExpression, BlockScope blockScope) { + // do nothing by default + } + public void endVisit(ReferenceExpression referenceExpression, BlockScope blockScope) { + // do nothing by default + } //{ObjectTeams: visit new ast nodes: public void endVisit(LiftingTypeReference liftingTypeReference, BlockScope scope) { @@ -1025,6 +1031,12 @@ public abstract class ASTVisitor { public boolean visit(Wildcard wildcard, ClassScope scope) { return true; // do nothing by default, keep traversing } + public boolean visit(LambdaExpression lambdaExpression, BlockScope blockScope) { + return true; // do nothing by default, keep traversing + } + public boolean visit(ReferenceExpression referenceExpression, BlockScope blockScope) { + return true; // do nothing by default, keep traversing + } //{ObjectTeams: visit new ast nodes: public boolean visit(LiftingTypeReference liftingTypeReference, BlockScope scope) { return true; // do nothing by default, keep traversing 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 dc2ba1e7e..98937eaa0 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 @@ -297,11 +297,6 @@ public class ClassFile implements TypeConstants, TypeIds { } else { this.codeStream = new CodeStream(this); } - if (this.targetJDK == ClassFileConstants.JDK1_8) { - //TODO JAVA8: Version number is not yet updated in the java8 beta... - //Remove this after it is upgraded - this.targetJDK = ClassFileConstants.JDK1_7; - } initByteArrays(); } @@ -4307,11 +4302,6 @@ public class ClassFile implements TypeConstants, TypeIds { this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3 this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP; } - if (this.targetJDK == ClassFileConstants.JDK1_8) { - //TODO JAVA8: Version number is not yet updated in the java8 beta... - //Remove this after it is upgraded - this.targetJDK = ClassFileConstants.JDK1_7; - } this.bytes = null; this.constantPool.reset(); this.codeStream.reset(this); 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 9e13af24c..2537b2b5a 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -190,7 +190,6 @@ public abstract class AbstractMethodDeclaration public Annotation[] annotations; // jsr 308 public Receiver receiver; - public Annotation[] receiverAnnotations; public Argument[] arguments; public TypeReference[] thrownExceptions; public Statement[] statements; @@ -337,21 +336,21 @@ public abstract class AbstractMethodDeclaration /** * Feed null information from argument annotations into the analysis and mark arguments as assigned. */ - void analyseArguments(FlowInfo flowInfo) { - if (this.arguments != null) { - for (int i = 0, count = this.arguments.length; i < count; i++) { - if (this.binding.parameterNonNullness != null) { + static void analyseArguments(FlowInfo flowInfo, Argument[] methodArguments, MethodBinding methodBinding) { + if (methodArguments != null) { + for (int i = 0, count = methodArguments.length; i < count; i++) { + if (methodBinding.parameterNonNullness != null) { // leverage null-info from parameter annotations: - Boolean nonNullNess = this.binding.parameterNonNullness[i]; + Boolean nonNullNess = methodBinding.parameterNonNullness[i]; if (nonNullNess != null) { if (nonNullNess.booleanValue()) - flowInfo.markAsDefinitelyNonNull(this.arguments[i].binding); + flowInfo.markAsDefinitelyNonNull(methodArguments[i].binding); else - flowInfo.markPotentiallyNullBit(this.arguments[i].binding); + flowInfo.markPotentiallyNullBit(methodArguments[i].binding); } } // tag parameters as being set: - flowInfo.markAsDefinitelyAssigned(this.arguments[i].binding); + flowInfo.markAsDefinitelyAssigned(methodArguments[i].binding); } } } @@ -728,10 +727,6 @@ public abstract class AbstractMethodDeclaration } } output.append(')'); - if (this.receiverAnnotations != null) { - output.append(" "); //$NON-NLS-1$ - printAnnotations(this.receiverAnnotations, output); - } if (this.thrownExceptions != null) { output.append(" throws "); //$NON-NLS-1$ for (int i = 0; i < this.thrownExceptions.length; i++) { @@ -791,7 +786,8 @@ public abstract class AbstractMethodDeclaration resolveJavadoc(); resolveAnnotations(this.scope, this.annotations, this.binding); // jsr 308 - resolveAnnotations(this.scope, this.receiverAnnotations, new Annotation.TypeUseBinding(Binding.TYPE_USE)); + if (this.receiver != null && this.receiver.annotations != null) + resolveAnnotations(this.scope, this.receiver.annotations, new Annotation.TypeUseBinding(Binding.TYPE_USE)); validateNullAnnotations(); resolveStatements(); // check @Deprecated annotation presence @@ -819,6 +815,7 @@ public abstract class AbstractMethodDeclaration /* neither static methods nor methods in anonymous types can have explicit 'this' */ if (this.isStatic() || declaringClass.isAnonymousType()) { this.scope.problemReporter().disallowedThisParameter(this.receiver); + this.receiver = null; return; // No need to do further validation } @@ -828,27 +825,27 @@ public abstract class AbstractMethodDeclaration if (declaringClass.isStatic() || (declaringClass.tagBits & (TagBits.IsLocalType | TagBits.IsMemberType)) == 0) { /* neither member nor local type */ this.scope.problemReporter().disallowedThisParameter(this.receiver); + this.receiver = null; return; // No need to do further validation } enclosingReceiver = enclosingReceiver.enclosingType(); } - if (enclosingReceiver != resolvedReceiverType) { - this.scope.problemReporter().illegalTypeForExplicitThis(this.receiver, enclosingReceiver); + char[][] tokens = (this.receiver.qualifyingName == null) ? null : this.receiver.qualifyingName.getName(); + if (this.isConstructor()) { + if (tokens == null || tokens.length > 1 || !CharOperation.equals(enclosingReceiver.sourceName(), tokens[0])) { + this.scope.problemReporter().illegalQualifierForExplicitThis(this.receiver, enclosingReceiver); + this.receiver.qualifyingName = null; + } + } else if (tokens != null && tokens.length > 0) { + this.scope.problemReporter().illegalQualifierForExplicitThis2(this.receiver); + this.receiver.qualifyingName = null; } - 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) { - for(int index = tokens.length - 1; index >= 0 && enclosingType != null; index--) { - if (!CharOperation.equals(enclosingType.sourceName(), tokens[index])) { - return false; - } - enclosingType = enclosingType.enclosingType(); + if (enclosingReceiver != resolvedReceiverType) { + this.scope.problemReporter().illegalTypeForExplicitThis(this.receiver, enclosingReceiver); + this.receiver = null; } - return true; } public void resolveJavadoc() { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java index 63a797116..09211dee2 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -252,7 +252,7 @@ public void analyseCode(ClassScope classScope, InitializationFlowContext initial } // nullity and mark as assigned - analyseArguments(flowInfo); + analyseArguments(flowInfo, this.arguments, this.binding); // propagate to constructor call if (this.constructorCall != null) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java new file mode 100644 index 000000000..1bc88f7d5 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + * Jesper S Moller - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression + *******************************************************************************/ +package org.eclipse.jdt.internal.compiler.ast; + +import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.internal.compiler.codegen.CodeStream; +import org.eclipse.jdt.internal.compiler.flow.FlowInfo; +import org.eclipse.jdt.internal.compiler.impl.Constant; +import org.eclipse.jdt.internal.compiler.lookup.BlockScope; +import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; +import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; +import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding; +import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; +import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; + +public abstract class FunctionalExpression extends Expression { + + TypeBinding expectedType; + MethodBinding singleAbstractMethod; + ReferenceBinding functionalInterfaceType; + + public FunctionalExpression() { + super(); + } + + public void setExpectedType(TypeBinding expectedType) { + this.expectedType = expectedType; + } + + public TypeBinding expectedType() { + return this.expectedType; + } + + public /* @NonNull */ TypeBinding resolveType(BlockScope blockScope) { + this.constant = Constant.NotAConstant; + this.singleAbstractMethod = this.expectedType == null ? null : this.expectedType.getSingleAbstractMethod(blockScope); + if (this.singleAbstractMethod == null || !this.singleAbstractMethod.isValidBinding()) { + blockScope.problemReporter().targetTypeIsNotAFunctionalInterface(this); + char [][] name = this.expectedType == null ? CharOperation.NO_CHAR_CHAR : CharOperation.splitOn('.', this.expectedType.shortReadableName()); + return this.functionalInterfaceType = new ProblemReferenceBinding(name, null, ProblemReasons.NotAFunctionalInterface); + } + return this.functionalInterfaceType = (ReferenceBinding) this.expectedType; + } + + public int nullStatus(FlowInfo flowInfo) { + return FlowInfo.NON_NULL; + } + + public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + int pc = codeStream.position; + if (valueRequired) { + codeStream.aconst_null(); // TODO: Real code + } + codeStream.recordPositionsFrom(pc, this.sourceStart); + } + +} 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 25b0f2b04..a82c9cbf2 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -11,19 +11,126 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Jesper S Moller - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; -public class LambdaExpression extends NullLiteral { // For the time being. - Argument [] arguments; +import org.eclipse.jdt.core.compiler.CategorizedProblem; +import org.eclipse.jdt.internal.compiler.ASTVisitor; +import org.eclipse.jdt.internal.compiler.CompilationResult; +import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext; +import org.eclipse.jdt.internal.compiler.flow.FlowContext; +import org.eclipse.jdt.internal.compiler.flow.FlowInfo; +import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; +import org.eclipse.jdt.internal.compiler.lookup.Binding; +import org.eclipse.jdt.internal.compiler.lookup.BlockScope; +import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; +import org.eclipse.jdt.internal.compiler.lookup.MethodScope; +import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; +import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; +import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit; +import org.eclipse.jdt.internal.compiler.problem.AbortMethod; +import org.eclipse.jdt.internal.compiler.problem.AbortType; +import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; + +public class LambdaExpression extends FunctionalExpression implements ProblemSeverities, ReferenceContext { + public Argument [] arguments; Statement body; + private MethodScope scope; + private CompilationResult compilationResult; + private boolean ignoreFurtherInvestigation; + private MethodBinding binding; - public LambdaExpression(Argument [] arguments, Statement body) { - super(0, 0); + public LambdaExpression(CompilationResult compilationResult, Argument [] arguments, Statement body) { + this.compilationResult = compilationResult; this.arguments = arguments; this.body = body; } + public TypeBinding resolveType(BlockScope blockScope) { + super.resolveType(blockScope); + this.scope = new MethodScope(blockScope, this, blockScope.methodScope().isStatic); + this.binding = this.scope.createAnonymousMethodBinding(this); + if (this.functionalInterfaceType.isValidBinding()) { + this.binding.thrownExceptions = computeKosherThrowables(); + // Resolve arguments, validate signature ... + if (this.arguments != null && this.singleAbstractMethod != null) { + int parameterCount = this.singleAbstractMethod.parameters != null ? this.singleAbstractMethod.parameters.length : 0; + int lambdaArgumentCount = this.arguments != null ? this.arguments.length : 0; + + if (parameterCount == lambdaArgumentCount) { + for (int i = 0, length = this.arguments.length; i < length; i++) { + Argument argument = this.arguments[i]; + if (argument.type != null) { + argument.resolve(this.scope); // TODO: Check it! + } else { + argument.bind(this.scope, this.singleAbstractMethod.parameters[i], false); + } + } + } /* TODO: else complain */ + } + } + if (this.body instanceof Expression) { + Expression expression = (Expression) this.body; + if (this.functionalInterfaceType.isValidBinding()) { + expression.setExpectedType(this.singleAbstractMethod.returnType); // chain expected type for any nested lambdas. + /* TypeBinding expressionType = */ expression.resolveType(this.scope); + // TODO: checkExpressionResult(singleAbstractMethod.returnType, expression, expressionType); + } + } else { + this.body.resolve(this.scope); + } + return this.functionalInterfaceType; + } + + private ReferenceBinding[] computeKosherThrowables() { + return this.singleAbstractMethod == null || !this.singleAbstractMethod.isValidBinding() ? Binding.NO_EXCEPTIONS : this.singleAbstractMethod.thrownExceptions; // for now. + } + + public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, final FlowInfo flowInfo) { + + if (this.ignoreFurtherInvestigation) + return flowInfo; + + FlowInfo lambdaInfo = flowInfo.copy(); // occurrence context immune to data flow inside lambda. + ExceptionHandlingFlowContext methodContext = + new ExceptionHandlingFlowContext( + flowContext, + this, + this.binding.thrownExceptions, + null, + this.scope, + FlowInfo.DEAD_END); + + // nullity and mark as assigned + AbstractMethodDeclaration.analyseArguments(lambdaInfo, this.arguments, this.binding); + + if (this.arguments != null) { + for (int i = 0, count = this.arguments.length; i < count; i++) { + this.bits |= (this.arguments[i].bits & ASTNode.HasTypeAnnotations); + } + } + + lambdaInfo = this.body.analyseCode(this.scope, methodContext, lambdaInfo); + + // check for missing returning path for block body's ... + if (this.body instanceof Block) { + TypeBinding returnTypeBinding = expectedResultType(); + if ((returnTypeBinding == TypeBinding.VOID)) { + if ((lambdaInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) { + this.bits |= ASTNode.NeedFreeReturn; + } + } else { + if (lambdaInfo != FlowInfo.DEAD_END) { + this.scope.problemReporter().shouldReturn(returnTypeBinding, this); + } + } + } + return flowInfo; + } + public StringBuffer printExpression(int tab, StringBuffer output) { int parenthesesCount = (this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; String suffix = ""; //$NON-NLS-1$ @@ -42,4 +149,60 @@ public class LambdaExpression extends NullLiteral { // For the time being. this.body.print(this.body instanceof Block ? tab : 0, output); return output.append(suffix); } -} + + public CompilationResult compilationResult() { + return this.compilationResult; + } + + public void abort(int abortLevel, CategorizedProblem problem) { + + switch (abortLevel) { + case AbortCompilation : + throw new AbortCompilation(this.compilationResult, problem); + case AbortCompilationUnit : + throw new AbortCompilationUnit(this.compilationResult, problem); + case AbortType : + throw new AbortType(this.compilationResult, problem); + default : + throw new AbortMethod(this.compilationResult, problem); + } + } + + public CompilationUnitDeclaration getCompilationUnitDeclaration() { + return this.scope == null ? null : this.scope.compilationUnitScope().referenceContext; + } + + public boolean hasErrors() { + return this.ignoreFurtherInvestigation; + } + + public void tagAsHavingErrors() { + this.ignoreFurtherInvestigation = true; + } + +//{ObjectTeams: and remove it again: + public void resetErrorFlag() { + this.ignoreFurtherInvestigation = false; + } +// SH} + + public TypeBinding expectedResultType() { + return this.singleAbstractMethod != null && this.singleAbstractMethod.isValidBinding() ? this.singleAbstractMethod.returnType : null; + } + + public void traverse(ASTVisitor visitor, BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + if (this.arguments != null) { + int argumentsLength = this.arguments.length; + for (int i = 0; i < argumentsLength; i++) + this.arguments[i].traverse(visitor, this.scope); + } + + if (this.body != null) { + this.body.traverse(visitor, this.scope); + } + } + visitor.endVisit(this, blockScope); + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java index f44e47e38..0774d2d40 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -152,7 +152,7 @@ public class MethodDeclaration extends AbstractMethodDeclaration { FlowInfo.DEAD_END); // nullity and mark as assigned - analyseArguments(flowInfo); + analyseArguments(flowInfo, this.arguments, this.binding); if (this.arguments != null) { for (int i = 0, count = this.arguments.length; i < count; i++) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Receiver.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Receiver.java index ff5fffb37..88307367e 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Receiver.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Receiver.java @@ -16,7 +16,7 @@ package org.eclipse.jdt.internal.compiler.ast; public class Receiver extends Argument { - NameReference qualifyingName; + public NameReference qualifyingName; public Receiver(char[] name, long posNom, TypeReference typeReference, NameReference qualifyingName, int modifiers) { super(name, posNom, typeReference, modifiers); this.qualifyingName = qualifyingName; 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 bc680d6ad..3e3ea7397 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 @@ -11,53 +11,69 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Jesper S Moller - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; -public class ReferenceExpression extends NullLiteral { // For the time being. +import org.eclipse.jdt.internal.compiler.ASTVisitor; +import org.eclipse.jdt.internal.compiler.lookup.BlockScope; +import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; + +public class ReferenceExpression extends FunctionalExpression { protected NameReference name; protected TypeReference type; protected Expression primary; - protected TypeReference [] typeArguments; + protected TypeReference [] typeParameters; protected SingleNameReference method; // == null ? "::new" : "::method" public ReferenceExpression(NameReference name, TypeReference[] typeArguments, int sourceEnd) { - super(name.sourceStart, sourceEnd); this.name = name; - this.typeArguments = typeArguments; + this.typeParameters = typeArguments; this.method = null; + this.sourceStart = name.sourceStart; + this.sourceEnd = sourceEnd; } public ReferenceExpression(NameReference name, TypeReference[] typeArguments, SingleNameReference method) { - super(name.sourceStart, method.sourceEnd); this.name = name; - this.typeArguments = typeArguments; + this.typeParameters = typeArguments; this.method = method; + this.sourceStart = name.sourceStart; + this.sourceEnd = method.sourceEnd; } public ReferenceExpression(Expression primary, TypeReference [] typeArguments, SingleNameReference method) { - super(primary.sourceStart, method.sourceEnd); this.primary = primary; - this.typeArguments = typeArguments; + this.typeParameters = typeArguments; this.method = method; + this.sourceStart = primary.sourceStart; + this.sourceEnd = method.sourceEnd; } public ReferenceExpression(TypeReference type, TypeReference[] typeArguments, SingleNameReference method) { - super(type.sourceStart, method.sourceEnd); this.type = type; - this.typeArguments = typeArguments; + this.typeParameters = typeArguments; this.method = method; + this.sourceStart = type.sourceStart; + this.sourceEnd = method.sourceEnd; } public ReferenceExpression(TypeReference type, TypeReference[] typeArguments, int sourceEnd) { - super(type.sourceStart, sourceEnd); this.type = type; - this.typeArguments = typeArguments; + this.typeParameters = typeArguments; this.method = null; + this.sourceStart = type.sourceStart; + this.sourceEnd = sourceEnd; + } + + public TypeBinding resolveType(BlockScope blockScope) { + super.resolveType(blockScope); + return this.functionalInterfaceType; } public StringBuffer printExpression(int tab, StringBuffer output) { @@ -70,14 +86,14 @@ public class ReferenceExpression extends NullLiteral { // For the time being. this.primary.print(0, output); } output.append("::"); //$NON-NLS-1$ - if (this.typeArguments != null) { + if (this.typeParameters != null) { output.append('<'); - int max = this.typeArguments.length - 1; + int max = this.typeParameters.length - 1; for (int j = 0; j < max; j++) { - this.typeArguments[j].print(0, output); + this.typeParameters[j].print(0, output); output.append(", ");//$NON-NLS-1$ } - this.typeArguments[max].print(0, output); + this.typeParameters[max].print(0, output); output.append('>'); } if (this.method == null) { @@ -93,4 +109,28 @@ public class ReferenceExpression extends NullLiteral { // For the time being. public boolean isMethodReference() { return this.method != null; } + public void traverse(ASTVisitor visitor, BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + + if (this.name != null) + this.name.traverse(visitor, blockScope); + + if (this.type != null) + this.type.traverse(visitor, blockScope); + + if (this.primary != null) + this.primary.traverse(visitor, blockScope); + + int length = this.typeParameters == null ? 0 : this.typeParameters.length; + for (int i = 0; i < length; i++) { + this.typeParameters[i].traverse(visitor, blockScope); + } + + if (this.method != null) + this.method.traverse(visitor, blockScope); + + } + visitor.endVisit(this, blockScope); + } }
\ No newline at end of file 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 4c11965c9..9b701900b 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 @@ -22,6 +22,8 @@ * bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null" * bug 388996 - [compiler][resource] Incorrect 'potential resource leak' * bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional + * Jesper S Moller - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; @@ -265,6 +267,7 @@ public void resolve(BlockScope scope) { MethodScope methodScope = scope.methodScope(); MethodBinding methodBinding; TypeBinding methodType = + (methodScope.referenceContext instanceof LambdaExpression) ? ((LambdaExpression) methodScope.referenceContext).expectedResultType() : (methodScope.referenceContext instanceof AbstractMethodDeclaration) ? ((methodBinding = ((AbstractMethodDeclaration) methodScope.referenceContext).binding) == null ? null diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java index 31ed460d6..640cb61ce 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 GK Software AG and others. + * Copyright (c) 2012, 2013 GK Software AG, 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 @@ -168,7 +168,9 @@ public class ImplicitNullAnnotationVerifier { MethodBinding currentMethod = ifcMethods[i]; if (currentMethod.isStatic()) continue; - if (areParametersEqual(original, currentMethod)) { +//{ObjectTeams: added 3. argument: + if (areParametersEqual(original, currentMethod, this.environment)) { +// SH} result.add(currentMethod); return; // at most one method is overridden from any supertype } @@ -375,8 +377,9 @@ public class ImplicitNullAnnotationVerifier { } // ==== minimal set of utility methods previously from MethodVerifier15: ==== - - boolean areParametersEqual(MethodBinding one, MethodBinding two) { +//{ObjectTeams: added 3. argument: + static boolean areParametersEqual(MethodBinding one, MethodBinding two, LookupEnvironment environment) { +// SH} //{ObjectTeams: retrench callin methods: /* orig: TypeBinding[] oneArgs = one.parameters; @@ -395,8 +398,8 @@ public class ImplicitNullAnnotationVerifier { // with parameterized parameters for backwards compatibility, need a more complex check int i; foundRAW: for (i = 0; i < length; i++) { -//{ObjectTeams: added 3. argument: - if (!areTypesEqual(oneArgs[i], twoArgs[i], two)) { +//{ObjectTeams: added arguments 3 & 4: + if (!areTypesEqual(oneArgs[i], twoArgs[i], two, environment)) { // SH} if (oneArgs[i].leafComponentType().isRawType()) { if (oneArgs[i].dimensions() == twoArgs[i].dimensions() && oneArgs[i].leafComponentType().isEquivalentTo(twoArgs[i].leafComponentType())) { @@ -418,7 +421,7 @@ public class ImplicitNullAnnotationVerifier { // all raw mode for remaining parameters (if any) for (i++; i < length; i++) { //{ObjectTeams: added 3. argument: - if (!areTypesEqual(oneArgs[i], twoArgs[i], two)) { + if (!areTypesEqual(oneArgs[i], twoArgs[i], two, null)) { // SH} if (oneArgs[i].leafComponentType().isRawType()) if (oneArgs[i].dimensions() == twoArgs[i].dimensions() && oneArgs[i].leafComponentType().isEquivalentTo(twoArgs[i].leafComponentType())) @@ -431,11 +434,11 @@ public class ImplicitNullAnnotationVerifier { return true; } //{ObjectTeams: enable role type comparison -//added 3. parameter: - boolean areTypesEqual(TypeBinding one, TypeBinding two, MethodBinding methodTwo) { +//added parameters 3 & 4: + static boolean areTypesEqual(TypeBinding one, TypeBinding two, MethodBinding methodTwo, LookupEnvironment environment) { if (one == two) return true; // different comparison for role types: - if (areEqualRoleTypes(one, two, methodTwo.declaringClass, this.environment)) + if (areEqualRoleTypes(one, two, methodTwo.declaringClass, environment)) return true; // SH} // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329584 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 ef7fade0b..40e919659 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -1769,4 +1769,17 @@ public boolean hasNonNullDefault() { return false; return this.declaringClass.hasNonNullDefault(); } + +public boolean redeclaresPublicObjectMethod(Scope scope) { + ReferenceBinding javaLangObject = scope.getJavaLangObject(); + MethodBinding [] methods = javaLangObject.getMethods(this.selector); + for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++) { + final MethodBinding method = methods[i]; + if (!method.isPublic() || method.isStatic() || method.parameters.length != this.parameters.length) + continue; + if (MethodVerifier.doesMethodOverride(this, method, scope.environment())) + return true; + } + return false; +} } 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 fc0a73612..7d00b9202 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 @@ -18,6 +18,8 @@ * bug 374605 - Unreasonable warning for enum-based switch statements * bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods. * bug 382354 - [1.8][compiler] Compiler silent on conflicting modifier + * Jesper S Moller - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -89,7 +91,7 @@ public class MethodScope extends BlockScope { // remember suppressed warning re missing 'default:' to give hints on possibly related flow problems public boolean hasMissingSwitchDefault; // TODO(stephan): combine flags to a bitset? -public MethodScope(ClassScope parent, ReferenceContext context, boolean isStatic) { +public MethodScope(Scope parent, ReferenceContext context, boolean isStatic) { super(METHOD_SCOPE, parent); this.locals = new LocalVariableBinding[5]; this.referenceContext = context; @@ -468,7 +470,6 @@ MethodBinding createMethod(AbstractMethodDeclaration method) { problemReporter().illegalSourceLevelForThis(method.receiver); } if (method.receiver.annotations != null) { - method.receiverAnnotations = method.receiver.annotations; method.bits |= ASTNode.HasTypeAnnotations; } } @@ -484,6 +485,27 @@ MethodBinding createMethod(AbstractMethodDeclaration method) { return method.binding; } +public MethodBinding createAnonymousMethodBinding(LambdaExpression lambda) { + + SourceTypeBinding declaringClass = null; // for now. + int modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccUnresolved; + MethodBinding binding = new MethodBinding(modifiers, TypeConstants.ANONYMOUS_METHOD, null, null, null, declaringClass); + + Argument[] arguments = lambda.arguments; + int argLength = arguments == null ? 0 : arguments.length; + if (argLength > 0) { + Argument argument = arguments[--argLength]; + if (argument.isVarArgs()) + binding.modifiers |= ClassFileConstants.AccVarargs; + while (--argLength >= 0) { + argument = arguments[argLength]; + if (argument.isVarArgs()) + problemReporter().illegalVarargInLambda(argument); + } + } + return binding; +} + /** * Overridden to detect the error case inside an explicit constructor call: class X { 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 c6f415257..0c7a47d6a 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, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -18,18 +18,24 @@ * bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance * bug 388954 - [1.8][compiler] detect default methods in class files * bug 388281 - [compiler][null] inheritance of null annotations as an option + * bug 388739 - [1.8][compiler] consider default methods when detecting whether a class needs to be declared abstract + * bug 390883 - [1.8][compiler] Unable to override default method *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import org.eclipse.jdt.core.compiler.CharOperation; -import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeReference; +import org.eclipse.jdt.internal.compiler.ast.*; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.compiler.util.SimpleSet; +import org.eclipse.jdt.internal.compiler.util.Sorting; import org.eclipse.objectteams.otdt.core.compiler.IOTConstants; import org.eclipse.objectteams.otdt.core.compiler.OTNameUtils; import org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CalloutImplementor; @@ -63,12 +69,11 @@ import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer; * Why: would report unimplemented methods. * */ -public class MethodVerifier extends ImplicitNullAnnotationVerifier { +public abstract class MethodVerifier extends ImplicitNullAnnotationVerifier { SourceTypeBinding type; HashtableOfObject inheritedMethods; HashtableOfObject currentMethods; LookupEnvironment environment; - private boolean allowCompatibleReturnTypes; /* Binding creation is responsible for reporting all problems with types: - all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations - abstract/final) @@ -94,51 +99,45 @@ MethodVerifier(LookupEnvironment environment) { this.inheritedMethods = null; this.currentMethods = null; this.environment = environment; - this.allowCompatibleReturnTypes = - environment.globalOptions.complianceLevel >= ClassFileConstants.JDK1_5 - && environment.globalOptions.sourceLevel < ClassFileConstants.JDK1_5; } boolean areMethodsCompatible(MethodBinding one, MethodBinding two) { - return isParameterSubsignature(one, two) && areReturnTypesCompatible(one, two); + return areMethodsCompatible(one, two, this.environment); } -boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) { -//{ObjectTeams: consider enhanced callin signatures: - /* orig: - if (one.returnType == two.returnType) return true; - :giro */ - if (MethodModel.getReturnType(one) == MethodModel.getReturnType(two)) return true; -// SH} +static boolean areMethodsCompatible(MethodBinding one, MethodBinding two, LookupEnvironment environment) { + // use the original methods to test compatibility, but do not check visibility, etc + one = one.original(); + two = one.findOriginalInheritedMethod(two); -//{ObjectTeams: added 3. argument, added adjustment of callin-return - if (areTypesEqual(MethodModel.getReturnType(one), MethodModel.getReturnType(two), two)) return true; -/* orig: - if (areTypesEqual(one.returnType, two.returnType)) return true; - */ -// SH} - -//different comparison for role types: - if (areEqualRoleTypes(one.returnType, two.returnType, two.declaringClass, this.environment)) - return true; -// SH} + if (two == null) + return false; // method's declaringClass does not inherit from inheritedMethod's - // when sourceLevel < 1.5 but compliance >= 1.5, allow return types in binaries to be compatible instead of just equal - if (this.allowCompatibleReturnTypes && - one.declaringClass instanceof BinaryTypeBinding && - two.declaringClass instanceof BinaryTypeBinding) { - return areReturnTypesCompatible0(one, two); - } - return false; + return isParameterSubsignature(one, two, environment); } -boolean areReturnTypesCompatible0(MethodBinding one, MethodBinding two) { - // short is compatible with int, but as far as covariance is concerned, its not - if (one.returnType.isBaseType()) return false; - - if (!one.declaringClass.isInterface() && one.declaringClass.id == TypeIds.T_JavaLangObject) - return two.returnType.isCompatibleWith(one.returnType); // interface methods inherit from Object - - // TODO(SH): Confined?? - - return one.returnType.isCompatibleWith(two.returnType); +boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) { + return areReturnTypesCompatible(one, two, this.type.scope.environment()); +} +static boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two, LookupEnvironment environment) { +//{ObjectTeams: consider enhanced callin signatures: + TypeBinding oneReturnType = MethodModel.getReturnType(one); + TypeBinding twoReturnType = MethodModel.getReturnType(two); + // almost orig: + if (oneReturnType == twoReturnType) return true; + if (environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_5) { + // short is compatible with int, but as far as covariance is concerned, its not + if (oneReturnType.isBaseType()) return false; + + // OT: different comparison for role types: + if (areEqualRoleTypes(one.returnType, two.returnType, two.declaringClass, environment)) + return true; + // :TO + if (!one.declaringClass.isInterface() && one.declaringClass.id == TypeIds.T_JavaLangObject) + return twoReturnType.isCompatibleWith(oneReturnType); // interface methods inherit from Object + + return oneReturnType.isCompatibleWith(twoReturnType); + } else { + return areTypesEqual(oneReturnType.erasure(), twoReturnType.erasure(), two, environment); + } +// SH} } boolean canSkipInheritedMethods() { if (this.type.superclass() != null && this.type.superclass().isAbstract()) @@ -320,8 +319,23 @@ public void checkAgainstImplicitlyInherited( // 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; + } } + // OT: // can't directly compare types (may need to involve role type adjustment). TypeBinding inheritedReturn = (inheritedMethod.isAnyCallin()) ? @@ -338,12 +352,20 @@ public void checkAgainstImplicitlyInherited( return; // orig: continue nextMethod; } + reportRawReferences(currentMethod, inheritedMethod); // if they were deferred, emit them now. if (currentMethod.thrownExceptions != Binding.NO_EXCEPTIONS) checkExceptions(currentMethod, inheritedMethod); if (inheritedMethod.isFinal()) problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod); if (!isAsVisible(currentMethod, inheritedMethod)) +//{ObjectTeams: only if both methods are role interface methods or both are not + if ( Protections.isRoleInterfaceMethod(inheritedMethod) + == Protections.isRoleInterfaceMethod(currentMethod)) +//SH} /*OT:*/ this.problemReporter(currentMethod).tsubMethodReducesVisibility(currentMethod, inheritedMethod); + if(inheritedMethod.isSynchronized() && !currentMethod.isSynchronized()) { + problemReporter(currentMethod).missingSynchronizedOnInheritedMethod(currentMethod, inheritedMethod); + } if (options.reportDeprecationWhenOverridingDeprecatedMethod && inheritedMethod.isViewedAsDeprecated()) { if (!currentMethod.isViewedAsDeprecated() || options.reportDeprecationInsideDeprecatedCode) { @@ -545,7 +567,7 @@ void checkForRedundantSuperinterfaces(ReferenceBinding superclass, ReferenceBind } } -void checkInheritedMethods(MethodBinding[] methods, int length) { +void checkInheritedMethods(MethodBinding[] methods, int length, boolean[] isOverridden) { /* 1. find concrete method 2. if it doesn't exist then find first inherited abstract method whose return type is compatible with all others @@ -559,7 +581,7 @@ void checkInheritedMethods(MethodBinding[] methods, int length) { MethodBinding concreteMethod = this.type.isInterface() || methods[0].isAbstract() ? null : methods[0]; if (concreteMethod == null) { - MethodBinding bestAbstractMethod = length == 1 ? methods[0] : findBestInheritedAbstractMethod(methods, length); + MethodBinding bestAbstractMethod = length == 1 ? methods[0] : findBestInheritedAbstractOrDefaultMethod(methods, length); boolean noMatch = bestAbstractMethod == null; if (noMatch) bestAbstractMethod = methods[0]; @@ -582,7 +604,7 @@ void checkInheritedMethods(MethodBinding[] methods, int length) { } } } else if (noMatch) { - problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length); + problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length, isOverridden); } else if (this.environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_8) { checkInheritedDefaultMethods(methods, length); } @@ -594,9 +616,9 @@ void checkInheritedMethods(MethodBinding[] methods, int length) { while (--index > 0 && checkInheritedReturnTypes(concreteMethod, methods[index])) {/*empty*/} if (index > 0) { // concreteMethod is not the best match - MethodBinding bestAbstractMethod = findBestInheritedAbstractMethod(methods, length); + MethodBinding bestAbstractMethod = findBestInheritedAbstractOrDefaultMethod(methods, length); if (bestAbstractMethod == null) - problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length); + problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length, isOverridden); else // can only happen in >= 1.5 since return types must be equal prior to 1.5 problemReporter().abstractMethodMustBeImplemented(this.type, bestAbstractMethod, concreteMethod); return; @@ -657,87 +679,7 @@ For each inherited method identifier (message pattern - vm signature minus the r else complain about missing implementation only if type is NOT an interface or abstract */ -void checkMethods() { - boolean mustImplementAbstractMethods = mustImplementAbstractMethods(); - boolean skipInheritedMethods = mustImplementAbstractMethods && canSkipInheritedMethods(); // have a single concrete superclass so only check overridden methods - boolean isOrEnclosedByPrivateType = this.type.isOrEnclosedByPrivateType(); - char[][] methodSelectors = this.inheritedMethods.keyTable; - nextSelector : for (int s = methodSelectors.length; --s >= 0;) { - if (methodSelectors[s] == null) continue nextSelector; - - MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(methodSelectors[s]); - MethodBinding[] inherited = (MethodBinding[]) this.inheritedMethods.valueTable[s]; - - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660, if current type is exposed, - // inherited methods of super classes are too. current != null case handled below. - if (current == null && !isOrEnclosedByPrivateType) { - int length = inherited.length; - for (int i = 0; i < length; i++){ - inherited[i].original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed; - } - } - - if (current == null && skipInheritedMethods) - continue nextSelector; - - if (inherited.length == 1 && current == null) { // handle the common case - if (mustImplementAbstractMethods && inherited[0].isAbstract()) - checkAbstractMethod(inherited[0]); - continue nextSelector; - } - - int index = -1; - MethodBinding[] matchingInherited = new MethodBinding[inherited.length]; - if (current != null) { - for (int i = 0, length1 = current.length; i < length1; i++) { - MethodBinding currentMethod = current[i]; - for (int j = 0, length2 = inherited.length; j < length2; j++) { - MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod); - if (inheritedMethod != null) { - if (isParameterSubsignature(currentMethod, inheritedMethod)) { - matchingInherited[++index] = inheritedMethod; - inherited[j] = null; // do not want to find it again - } - } - } - if (index >= 0) { - checkAgainstInheritedMethods(currentMethod, matchingInherited, index + 1, inherited); // pass in the length of matching - while (index >= 0) matchingInherited[index--] = null; // clear the contents of the matching methods - } - } - } - - for (int i = 0, length = inherited.length; i < length; i++) { - MethodBinding inheritedMethod = inherited[i]; - if (inheritedMethod == null) continue; - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660, if current type is exposed, - // inherited methods of super classes are too. current == null case handled already. - if (!isOrEnclosedByPrivateType && current != null) { - inheritedMethod.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed; - } - matchingInherited[++index] = inheritedMethod; - for (int j = i + 1; j < length; j++) { - MethodBinding otherInheritedMethod = inherited[j]; - if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) - continue; - otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); - if (otherInheritedMethod != null) { - if (isParameterSubsignature(inheritedMethod, otherInheritedMethod)) { - matchingInherited[++index] = otherInheritedMethod; - inherited[j] = null; // do not want to find it again - } - } - } - if (index == -1) continue; - if (index > 0) - checkInheritedMethods(matchingInherited, index + 1); // pass in the length of matching - else if (mustImplementAbstractMethods && matchingInherited[0].isAbstract()) - checkAbstractMethod(matchingInherited[0]); - while (index >= 0) matchingInherited[index--] = null; // clear the contents of the matching methods - } - } -} - +abstract void checkMethods(); void checkPackagePrivateAbstractMethod(MethodBinding abstractMethod) { // check that the inherited abstract method (package private visibility) is implemented within the same package PackageBinding necessaryPackage = abstractMethod.declaringClass.fPackage; @@ -790,36 +732,11 @@ void computeInheritedMethods(ReferenceBinding superclass, ReferenceBinding[] sup // if an inheritedMethod has been 'replaced' by a supertype's method then skip it, however // see usage of canOverridingMethodDifferInErasure below. this.inheritedMethods = new HashtableOfObject(51); // maps method selectors to an array of methods... must search to match paramaters & return type - ReferenceBinding[] interfacesToVisit = null; - int nextPosition = 0; - ReferenceBinding[] itsInterfaces = superInterfaces; - if (itsInterfaces != Binding.NO_SUPERINTERFACES) { - nextPosition = itsInterfaces.length; - interfacesToVisit = itsInterfaces; - } ReferenceBinding superType = superclass; HashtableOfObject nonVisibleDefaultMethods = new HashtableOfObject(3); // maps method selectors to an array of methods while (superType != null && superType.isValidBinding()) { - // We used to only include superinterfaces if immediate superclasses are abstract - // but that is problematic. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358 - if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { - if (interfacesToVisit == null) { - interfacesToVisit = itsInterfaces; - nextPosition = interfacesToVisit.length; - } else { - int itsLength = itsInterfaces.length; - if (nextPosition + itsLength >= interfacesToVisit.length) - System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); - nextInterface : for (int a = 0; a < itsLength; a++) { - ReferenceBinding next = itsInterfaces[a]; - for (int b = 0; b < nextPosition; b++) - if (next == interfacesToVisit[b]) continue nextInterface; - interfacesToVisit[nextPosition++] = next; - } - } - } MethodBinding[] methods = superType.unResolvedMethods(); nextMethod : for (int m = methods.length; --m >= 0;) { @@ -886,24 +803,27 @@ void computeInheritedMethods(ReferenceBinding superclass, ReferenceBinding[] sup } superType = superType.superclass(); } - if (nextPosition == 0) return; + List superIfcList = new ArrayList(); + HashSet seenTypes = new HashSet(); + collectAllDistinctSuperInterfaces(superInterfaces, seenTypes, superIfcList); + if (superclass != null) + collectAllDistinctSuperInterfaces(superclass.superInterfaces(), seenTypes, superIfcList); + if (superIfcList.size() == 0) return; + + if (superIfcList.size() == 1) { + superInterfaces = new ReferenceBinding[] { (ReferenceBinding) superIfcList.get(0) }; + } else { + superInterfaces = (ReferenceBinding[]) superIfcList.toArray(new ReferenceBinding[superIfcList.size()]); + superInterfaces = Sorting.sortTypes(superInterfaces); + } + SimpleSet skip = findSuperinterfaceCollisions(superclass, superInterfaces); - for (int i = 0; i < nextPosition; i++) { - superType = interfacesToVisit[i]; + int len = superInterfaces.length; + for (int i = len-1; i >= 0; i--) { + superType = superInterfaces[i]; if (superType.isValidBinding()) { if (skip != null && skip.includes(superType)) continue; - if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { - int itsLength = itsInterfaces.length; - if (nextPosition + itsLength >= interfacesToVisit.length) - System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); - nextInterface : for (int a = 0; a < itsLength; a++) { - ReferenceBinding next = itsInterfaces[a]; - for (int b = 0; b < nextPosition; b++) - if (next == interfacesToVisit[b]) continue nextInterface; - interfacesToVisit[nextPosition++] = next; - } - } MethodBinding[] methods = superType.unResolvedMethods(); nextMethod : for (int m = methods.length; --m >= 0;) { // Interface methods are all abstract public @@ -933,6 +853,18 @@ void computeInheritedMethods(ReferenceBinding superclass, ReferenceBinding[] sup } } +void collectAllDistinctSuperInterfaces(ReferenceBinding[] superInterfaces, Set seen, List result) { + // use 'seen' to avoid duplicates, use result to maintain stable order + int length = superInterfaces.length; + for (int i=0; i<length; i++) { + ReferenceBinding superInterface = superInterfaces[i]; + if (seen.add(superInterface)) { + result.add(superInterface); + collectAllDistinctSuperInterfaces(superInterface.superInterfaces(), seen, result); + } + } +} + // Given `overridingMethod' which overrides `inheritedMethod' answer whether some subclass method that // differs in erasure from overridingMethod could override `inheritedMethod' protected boolean canOverridingMethodDifferInErasure(MethodBinding overridingMethod, MethodBinding inheritedMethod) { @@ -964,25 +896,67 @@ void computeMethods() { } MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) { + return computeSubstituteMethod(inheritedMethod, currentMethod, this.environment); +} + +static MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod, LookupEnvironment environment) { if (inheritedMethod == null) return null; if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match -//{ObjectTeams: copied from MethodVerifier15 and guarded with own condition: - if ( (currentMethod.declaringClass.isRole() && inheritedMethod.declaringClass.isRole()) - || (currentMethod.declaringClass.isTeam() && inheritedMethod.declaringClass.isTeam())) - { - // orig 15: - // due to hierarchy & compatibility checks, we need to ensure these 2 methods are resolved - if (currentMethod.declaringClass instanceof BinaryTypeBinding) - ((BinaryTypeBinding) currentMethod.declaringClass).resolveTypesFor(currentMethod); - if (inheritedMethod.declaringClass instanceof BinaryTypeBinding) - ((BinaryTypeBinding) inheritedMethod.declaringClass).resolveTypesFor(inheritedMethod); - // :giro - } -//SH} - return inheritedMethod; -} -boolean couldMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { + // due to hierarchy & compatibility checks, we need to ensure these 2 methods are resolved + if (currentMethod.declaringClass instanceof BinaryTypeBinding) + ((BinaryTypeBinding) currentMethod.declaringClass).resolveTypesFor(currentMethod); + if (inheritedMethod.declaringClass instanceof BinaryTypeBinding) + ((BinaryTypeBinding) inheritedMethod.declaringClass).resolveTypesFor(inheritedMethod); + TypeVariableBinding[] inheritedTypeVariables = inheritedMethod.typeVariables; + int inheritedLength = inheritedTypeVariables.length; + if (inheritedLength == 0) return inheritedMethod; // no substitution needed + TypeVariableBinding[] typeVariables = currentMethod.typeVariables; + int length = typeVariables.length; + if (length == 0) + return inheritedMethod.asRawMethod(environment); + if (length != inheritedLength) + return inheritedMethod; // no match JLS 8.4.2 + + // interface I { <T> void foo(T t); } + // class X implements I { public <T extends I> void foo(T t) {} } + // for the above case, we do not want to answer the substitute method since its not a match + TypeBinding[] arguments = new TypeBinding[length]; + System.arraycopy(typeVariables, 0, arguments, 0, length); + ParameterizedGenericMethodBinding substitute = + environment.createParameterizedGenericMethod(inheritedMethod, arguments); + for (int i = 0; i < inheritedLength; i++) { + TypeVariableBinding inheritedTypeVariable = inheritedTypeVariables[i]; + TypeBinding argument = arguments[i]; + if (argument instanceof TypeVariableBinding) { + TypeVariableBinding typeVariable = (TypeVariableBinding) argument; + if (typeVariable.firstBound == inheritedTypeVariable.firstBound) { + if (typeVariable.firstBound == null) + continue; // both are null + } else if (typeVariable.firstBound != null && inheritedTypeVariable.firstBound != null) { + if (typeVariable.firstBound.isClass() != inheritedTypeVariable.firstBound.isClass()) + return inheritedMethod; // not a match + } + if (Scope.substitute(substitute, inheritedTypeVariable.superclass) != typeVariable.superclass) + return inheritedMethod; // not a match + int interfaceLength = inheritedTypeVariable.superInterfaces.length; + ReferenceBinding[] interfaces = typeVariable.superInterfaces; + if (interfaceLength != interfaces.length) + return inheritedMethod; // not a match + next : for (int j = 0; j < interfaceLength; j++) { + TypeBinding superType = Scope.substitute(substitute, inheritedTypeVariable.superInterfaces[j]); + for (int k = 0; k < interfaceLength; k++) + if (superType == interfaces[k]) + continue next; + return inheritedMethod; // not a match + } + } else if (inheritedTypeVariable.boundCheck(substitute, argument) != TypeConstants.OK) { + return inheritedMethod; + } + } + return substitute; +} +static boolean couldMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector)) return false; if (method == inheritedMethod || method.isStatic() || inheritedMethod.isStatic()) @@ -1002,37 +976,33 @@ boolean couldMethodOverride(MethodBinding method, MethodBinding inheritedMethod) } return true; } + //{ObjectTeams: is method the static implementation of a role ifc's abstract static? -private boolean staticRoleMethodImpl(MethodBinding method, MethodBinding inheritedMethod) +private static boolean staticRoleMethodImpl(MethodBinding method, MethodBinding inheritedMethod) { if (inheritedMethod.declaringClass.isSynthInterface()) return method.isStatic() && inheritedMethod.isStatic(); return false; } // SH} + // Answer whether the method overrides the inheritedMethod // Check the necessary visibility rules & inheritance from the inheritedMethod's declaringClass // See isMethodSubsignature() for parameter comparisons public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { - if (!couldMethodOverride(method, inheritedMethod)) - return false; - - inheritedMethod = inheritedMethod.original(); - TypeBinding match = method.declaringClass.findSuperTypeOriginatingFrom(inheritedMethod.declaringClass); - if (!(match instanceof ReferenceBinding)) - return false; // method's declaringClass does not inherit from inheritedMethod's - - return isParameterSubsignature(method, inheritedMethod); + return doesMethodOverride(method, inheritedMethod, this.environment); +} +public static boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod, LookupEnvironment environment) { + return couldMethodOverride(method, inheritedMethod) && areMethodsCompatible(method, inheritedMethod, environment); } - SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) { return null; // noop in 1.4 } -MethodBinding findBestInheritedAbstractMethod(MethodBinding[] methods, int length) { +MethodBinding findBestInheritedAbstractOrDefaultMethod(MethodBinding[] methods, int length) { findMethod : for (int i = 0; i < length; i++) { MethodBinding method = methods[i]; - if (!method.isAbstract()) continue findMethod; + if (!(method.isAbstract() || method.isDefaultMethod())) continue findMethod; for (int j = 0; j < length; j++) { if (i == j) continue; if (!checkInheritedReturnTypes(method, methods[j])) { @@ -1122,7 +1092,9 @@ boolean isAsVisible(MethodBinding newMethod, MethodBinding inheritedMethod) { boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) { // skip interface method with the same signature if visible to its declaringClass - return areParametersEqual(existingMethod, inheritedMethod) && existingMethod.declaringClass.implementsInterface(superType, true); +//{ObjectTeams: added 3. argument: + return areParametersEqual(existingMethod, inheritedMethod, this.environment) && existingMethod.declaringClass.implementsInterface(superType, true); +// SH} } public boolean isMethodSubsignature(MethodBinding method, MethodBinding inheritedMethod) { @@ -1131,7 +1103,62 @@ public boolean isMethodSubsignature(MethodBinding method, MethodBinding inherite } boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod) { - return areParametersEqual(method, inheritedMethod); + return isParameterSubsignature(method, inheritedMethod, this.environment); +} +static boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod, LookupEnvironment environment) { + MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method, environment); + return substitute != null && isSubstituteParameterSubsignature(method, substitute, environment); +} + +//if method "overrides" substituteMethod then we can skip over substituteMethod while resolving a message send +//if it does not then a name clash error is likely +boolean isSubstituteParameterSubsignature(MethodBinding method, MethodBinding substituteMethod) { + return isSubstituteParameterSubsignature(method, substituteMethod, this.environment); +} + +static boolean isSubstituteParameterSubsignature(MethodBinding method, MethodBinding substituteMethod, LookupEnvironment environment) { +//{ObjectTeams: added 3. argument: + if (!areParametersEqual(method, substituteMethod, environment)) { +// SH} + // method can still override substituteMethod in cases like : + // <U extends Number> void c(U u) {} + // @Override void c(Number n) {} + // but method cannot have a "generic-enabled" parameter type + if (substituteMethod.hasSubstitutedParameters() && method.areParameterErasuresEqual(substituteMethod)) + return method.typeVariables == Binding.NO_TYPE_VARIABLES && !hasGenericParameter(method); + + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=279836 + if (method.declaringClass.isRawType() && substituteMethod.declaringClass.isRawType()) + if (method.hasSubstitutedParameters() && substituteMethod.hasSubstitutedParameters()) + return areMethodsCompatible(method, substituteMethod, environment); + + return false; + } + + if (substituteMethod instanceof ParameterizedGenericMethodBinding) { + if (method.typeVariables != Binding.NO_TYPE_VARIABLES) + return !((ParameterizedGenericMethodBinding) substituteMethod).isRaw; + // since substituteMethod has substituted type variables, method cannot have a generic signature AND no variables -> its a name clash if it does + return !hasGenericParameter(method); + } + + // if method has its own variables, then substituteMethod failed bounds check in computeSubstituteMethod() + return method.typeVariables == Binding.NO_TYPE_VARIABLES; +} +static boolean hasGenericParameter(MethodBinding method) { + if (method.genericSignature() == null) return false; + + // may be only the return type that is generic, need to check parameters + TypeBinding[] params = method.parameters; + for (int i = 0, l = params.length; i < l; i++) { + TypeBinding param = params[i].leafComponentType(); + if (param instanceof ReferenceBinding) { + int modifiers = ((ReferenceBinding) param).modifiers; + if ((modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) + return true; + } + } + return false; } boolean isSameClassOrSubclassOf(ReferenceBinding testClass, ReferenceBinding superclass) { 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 7b461c313..2ee3d87b7 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,10 +1,13 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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: MethodVerifier15.java 23404 2010-02-03 14:10:22Z 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 @@ -15,6 +18,8 @@ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 * bug 388281 - [compiler][null] inheritance of null annotations as an option * bug 388795 - [compiler] detection of name clash depends on order of super interfaces + * bug 388739 - [1.8][compiler] consider default methods when detecting whether a class needs to be declared abstract + * bug 390883 - [1.8][compiler] Unable to override default method *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -30,6 +35,7 @@ import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.compiler.util.SimpleSet; +import org.eclipse.jdt.internal.compiler.util.Sorting; import org.eclipse.objectteams.otdt.core.compiler.IOTConstants; import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel; import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel; @@ -47,38 +53,6 @@ class MethodVerifier15 extends MethodVerifier { MethodVerifier15(LookupEnvironment environment) { super(environment); } -boolean areMethodsCompatible(MethodBinding one, MethodBinding two) { - return areMethodsCompatible(one, two, false); -} -boolean areMethodsCompatible(MethodBinding one, MethodBinding two, boolean allowReverse) { - // use the original methods to test compatibility, but do not check visibility, etc - one = one.original(); - two = one.findOriginalInheritedMethod(two); - - if (two == null) - return false; // method's declaringClass does not inherit from inheritedMethod's - - return isParameterSubsignature(one, two) || (allowReverse && isParameterSubsignature(two, one)); -} -boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) { -//{ObjectTeams: consider enhanced callin signatures: - /* orig: - if (one.returnType == two.returnType) return true; - :giro */ - if (MethodModel.getReturnType(one) == MethodModel.getReturnType(two)) return true; -// SH} -//{ObjectTeams: different comparison for role types: - if (areEqualRoleTypes(one.returnType, two.returnType, two.declaringClass, this.environment)) - return true; -// SH} - if (this.type.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { - return areReturnTypesCompatible0(one, two); - } else { -//{ObjectTeams: added 3. parameter: - return areTypesEqual(one.returnType.erasure(), two.returnType.erasure(), two); -// SH} - } -} // Given `overridingMethod' which overrides `inheritedMethod' answer whether some subclass method that // differs in erasure from overridingMethod could override `inheritedMethod' protected boolean canOverridingMethodDifferInErasure(MethodBinding overridingMethod, MethodBinding inheritedMethod) { @@ -297,12 +271,13 @@ void checkInheritedMethods(MethodBinding inheritedMethod, MethodBinding otherInh detectInheritedNameClash(inheritedMethod.original(), otherInheritedMethod.original()); } // 8.4.8.4 -void checkInheritedMethods(MethodBinding[] methods, int length) { +void checkInheritedMethods(MethodBinding[] methods, int length, boolean[] isOverridden) { boolean continueInvestigation = true; MethodBinding concreteMethod = null; for (int i = 0; i < length; i++) { if (!methods[i].isAbstract()) { - if (concreteMethod != null) { + // re-checking compatibility is needed for https://bugs.eclipse.org/346029 + if (concreteMethod != null && !(isOverridden[i] && areMethodsCompatible(concreteMethod, methods[i]))) { problemReporter().duplicateInheritedMethods(this.type, concreteMethod, methods[i]); continueInvestigation = false; } @@ -310,7 +285,7 @@ void checkInheritedMethods(MethodBinding[] methods, int length) { } } if (continueInvestigation) { - super.checkInheritedMethods(methods, length); + super.checkInheritedMethods(methods, length, isOverridden); } } boolean checkInheritedReturnTypes(MethodBinding method, MethodBinding otherMethod) { @@ -464,6 +439,8 @@ void checkMethods() { MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(methodSelectors[s]); MethodBinding[] inherited = (MethodBinding[]) this.inheritedMethods.valueTable[s]; + // ensure that if we have a concrete method this shows up at position [0]: + inherited = Sorting.concreteFirst(inherited, inherited.length); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660, if current type is exposed, // inherited methods of super classes are too. current != null case handled below. @@ -501,6 +478,7 @@ void checkMethods() { // either because they match the same currentMethod or match each other // - methods that are overridden by a current method boolean[] skip = new boolean[inheritedLength]; + boolean[] isOverridden = new boolean[inheritedLength]; if (current != null) { for (int i = 0, length1 = current.length; i < length1; i++) { MethodBinding currentMethod = current[i]; @@ -528,7 +506,7 @@ void checkMethods() { if (inheritedMethod != null) { if (foundMatch[j] == null && isSubstituteParameterSubsignature(currentMethod, inheritedMethod)) { // already checked compatibility, do visibility etc. also indicate overriding? If so ignore inheritedMethod further downstream - skip[j] = couldMethodOverride(currentMethod, inheritedMethod); + isOverridden[j] = skip[j] = couldMethodOverride(currentMethod, inheritedMethod); matchingInherited[++index] = inheritedMethod; foundMatch[j] = currentMethod; } else { @@ -561,7 +539,8 @@ void checkMethods() { // SH} } } - + // first round: collect information into skip and isOverridden by comparing all pairs: + // (and perform some side effects : bridge methods & use flags) for (int i = 0; i < inheritedLength; i++) { MethodBinding matchMethod = foundMatch[i]; if (matchMethod == null && current != null && this.type.isPublic()) { // current == null case handled already. @@ -575,10 +554,7 @@ void checkMethods() { if (!isOrEnclosedByPrivateType && matchMethod == null && current != null) { inherited[i].original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed; } - if (skip[i]) continue; MethodBinding inheritedMethod = inherited[i]; - if (matchMethod == null) - matchingInherited[++index] = inheritedMethod; for (int j = i + 1; j < inheritedLength; j++) { MethodBinding otherInheritedMethod = inherited[j]; if (matchMethod == foundMatch[j] && matchMethod != null) @@ -589,29 +565,38 @@ void checkMethods() { // This elimination used to happen rather eagerly in computeInheritedMethods step // itself earlier. (https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358) if (inheritedMethod.declaringClass != otherInheritedMethod.declaringClass) { - if (otherInheritedMethod.declaringClass.isInterface() && !inheritedMethod.declaringClass.isInterface()) { - if (isInterfaceMethodImplemented(otherInheritedMethod, inheritedMethod, otherInheritedMethod.declaringClass)) { - skip[j] = true; - continue; - } - } else if (areMethodsCompatible(inheritedMethod, otherInheritedMethod, true)) { - skip[j] = true; + // these method calls produce their effect as side-effects into skip and isOverridden: + if (isSkippableOrOverridden(inheritedMethod, otherInheritedMethod, skip, isOverridden, j)) + continue; + if (isSkippableOrOverridden(otherInheritedMethod, inheritedMethod, skip, isOverridden, i)) continue; - } } - otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); - if (otherInheritedMethod != null) { - if (((!inheritedMethod.isAbstract() || otherInheritedMethod.isAbstract()) // if (abstract(inherited) => abstract(other)) check if inherited overrides other - && isSubstituteParameterSubsignature(inheritedMethod, otherInheritedMethod)) - || ((!otherInheritedMethod.isAbstract() || inheritedMethod.isAbstract()) // if (abstract(other) => abstract(inherited)) check if other overrides inherited - && isSubstituteParameterSubsignature(otherInheritedMethod, inheritedMethod))) - { - if (index == -1) - matchingInherited[++index] = inheritedMethod; - if (foundMatch[j] == null) - matchingInherited[++index] = otherInheritedMethod; + } + } + // second round: collect and check matchingInherited, directly check methods with no replacing etc. + for (int i = 0; i < inheritedLength; i++) { + MethodBinding matchMethod = foundMatch[i]; + if (skip[i]) continue; + MethodBinding inheritedMethod = inherited[i]; + if (matchMethod == null) + matchingInherited[++index] = inheritedMethod; + for (int j = i + 1; j < inheritedLength; j++) { + if (foundMatch[j] == null) { + MethodBinding otherInheritedMethod = inherited[j]; + if (matchMethod == foundMatch[j] && matchMethod != null) + continue; // both inherited methods matched the same currentMethod + if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) + continue; + + MethodBinding replaceMatch; + if ((replaceMatch = findReplacedMethod(inheritedMethod, otherInheritedMethod)) != null) { + matchingInherited[++index] = replaceMatch; skip[j] = true; - } else if (matchMethod == null && foundMatch[j] == null) { + } else if ((replaceMatch = findReplacedMethod(otherInheritedMethod, inheritedMethod)) != null) { + matchingInherited[++index] = replaceMatch; + skip[j] = true; + } else if (matchMethod == null) { + // none replaced by the other, check these methods against each other now: checkInheritedMethods(inheritedMethod, otherInheritedMethod); } } @@ -619,13 +604,52 @@ void checkMethods() { if (index == -1) continue; if (index > 0) - checkInheritedMethods(matchingInherited, index + 1); // pass in the length of matching + checkInheritedMethods(matchingInherited, index + 1, isOverridden); // pass in the length of matching else if (mustImplementAbstractMethods && matchingInherited[0].isAbstract() && matchMethod == null) checkAbstractMethod(matchingInherited[0]); while (index >= 0) matchingInherited[index--] = null; // clear the previous contents of the matching methods } } } +/* mark as skippable + * - any interface method implemented by a class method + * - an x method (x in {class, interface}), for which another x method with a subsignature was found + * mark as isOverridden + * - any skippable method as defined above iff it is actually overridden by the specific method (disregarding visibility etc.) + * Note, that 'idx' corresponds to the position of 'general' in the arrays 'skip' and 'isOverridden' + */ +boolean isSkippableOrOverridden(MethodBinding specific, MethodBinding general, boolean[] skip, boolean[] isOverridden, int idx) { + boolean specificIsInterface = specific.declaringClass.isInterface(); + boolean generalIsInterface = general.declaringClass.isInterface(); + if (!specificIsInterface && generalIsInterface) { + if (isInterfaceMethodImplemented(general, specific, general.declaringClass)) { + skip[idx] = true; + isOverridden[idx] = true; + return true; + } + } else if (specificIsInterface == generalIsInterface) { + if (isParameterSubsignature(specific, general)) { + skip[idx] = true; + isOverridden[idx] = specific.declaringClass.isCompatibleWith(general.declaringClass); + return true; + } + } + return false; +} +/* 'general' is considered as replaced by 'specific' if + * - 'specific' is "at least as concrete as" 'general' + * - 'specific' has a signature that is a subsignature of the substituted signature of 'general' (as seen from specific's declaring class) + */ +MethodBinding findReplacedMethod(MethodBinding specific, MethodBinding general) { + MethodBinding generalSubstitute = computeSubstituteMethod(general, specific); + if (generalSubstitute != null + && (!specific.isAbstract() || general.isAbstract()) // if (abstract(specific) => abstract(general)) check if 'specific' overrides 'general' + && isSubstituteParameterSubsignature(specific, generalSubstitute)) + { + return generalSubstitute; + } + return null; +} //{ObjectTeams: specific treatment of callin modifier: /** @@ -724,69 +748,6 @@ void checkTypeVariableMethods(TypeParameter typeParameter) { } } } -MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) { - if (inheritedMethod == null) return null; -//{ObjectTeams: use source-level params in case of enhanced callin methods: -/* orig: - if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match - :giro */ - if (currentMethod.getSourceParamLength() != inheritedMethod.getSourceParamLength()) return null; // no match -// SH} - - // due to hierarchy & compatibility checks, we need to ensure these 2 methods are resolved - if (currentMethod.declaringClass instanceof BinaryTypeBinding) - ((BinaryTypeBinding) currentMethod.declaringClass).resolveTypesFor(currentMethod); - if (inheritedMethod.declaringClass instanceof BinaryTypeBinding) - ((BinaryTypeBinding) inheritedMethod.declaringClass).resolveTypesFor(inheritedMethod); - - TypeVariableBinding[] inheritedTypeVariables = inheritedMethod.typeVariables; - int inheritedLength = inheritedTypeVariables.length; - if (inheritedLength == 0) return inheritedMethod; // no substitution needed - TypeVariableBinding[] typeVariables = currentMethod.typeVariables; - int length = typeVariables.length; - if (length == 0) - return inheritedMethod.asRawMethod(this.environment); - if (length != inheritedLength) - return inheritedMethod; // no match JLS 8.4.2 - - // interface I { <T> void foo(T t); } - // class X implements I { public <T extends I> void foo(T t) {} } - // for the above case, we do not want to answer the substitute method since its not a match - TypeBinding[] arguments = new TypeBinding[length]; - System.arraycopy(typeVariables, 0, arguments, 0, length); - ParameterizedGenericMethodBinding substitute = - this.environment.createParameterizedGenericMethod(inheritedMethod, arguments); - for (int i = 0; i < inheritedLength; i++) { - TypeVariableBinding inheritedTypeVariable = inheritedTypeVariables[i]; - TypeBinding argument = arguments[i]; - if (argument instanceof TypeVariableBinding) { - TypeVariableBinding typeVariable = (TypeVariableBinding) argument; - if (typeVariable.firstBound == inheritedTypeVariable.firstBound) { - if (typeVariable.firstBound == null) - continue; // both are null - } else if (typeVariable.firstBound != null && inheritedTypeVariable.firstBound != null) { - if (typeVariable.firstBound.isClass() != inheritedTypeVariable.firstBound.isClass()) - return inheritedMethod; // not a match - } - if (Scope.substitute(substitute, inheritedTypeVariable.superclass) != typeVariable.superclass) - return inheritedMethod; // not a match - int interfaceLength = inheritedTypeVariable.superInterfaces.length; - ReferenceBinding[] interfaces = typeVariable.superInterfaces; - if (interfaceLength != interfaces.length) - return inheritedMethod; // not a match - next : for (int j = 0; j < interfaceLength; j++) { - TypeBinding superType = Scope.substitute(substitute, inheritedTypeVariable.superInterfaces[j]); - for (int k = 0; k < interfaceLength; k++) - if (superType == interfaces[k]) - continue next; - return inheritedMethod; // not a match - } - } else if (inheritedTypeVariable.boundCheck(substitute, argument) != TypeConstants.OK) { - return inheritedMethod; - } - } - return substitute; -} boolean detectInheritedNameClash(MethodBinding inherited, MethodBinding otherInherited) { if (!inherited.areParameterErasuresEqual(otherInherited)) return false; @@ -847,9 +808,6 @@ boolean detectNameClash(MethodBinding current, MethodBinding inherited, boolean if (severity == ProblemSeverities.Warning) return false; return true; } -public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { - return couldMethodOverride(method, inheritedMethod) && areMethodsCompatible(method, inheritedMethod); -} boolean doTypeVariablesClash(MethodBinding one, MethodBinding substituteTwo) { // one has type variables and substituteTwo did not pass bounds check in computeSubstituteMethod() return one.typeVariables != Binding.NO_TYPE_VARIABLES && !(substituteTwo instanceof ParameterizedGenericMethodBinding); @@ -923,21 +881,6 @@ SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBin } return copy; } -boolean hasGenericParameter(MethodBinding method) { - if (method.genericSignature() == null) return false; - - // may be only the return type that is generic, need to check parameters - TypeBinding[] params = method.parameters; - for (int i = 0, l = params.length; i < l; i++) { - TypeBinding param = params[i].leafComponentType(); - if (param instanceof ReferenceBinding) { - int modifiers = ((ReferenceBinding) param).modifiers; - if ((modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) - return true; - } - } - return false; -} boolean isAcceptableReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) { // called when currentMethod's return type is compatible with inheritedMethod's return type @@ -983,39 +926,6 @@ public boolean isMethodSubsignature(MethodBinding method, MethodBinding inherite MethodBinding inheritedOriginal = method.findOriginalInheritedMethod(inheritedMethod); return isParameterSubsignature(method, inheritedOriginal == null ? inheritedMethod : inheritedOriginal); } -boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod) { - MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method); - return substitute != null && isSubstituteParameterSubsignature(method, substitute); -} -// if method "overrides" substituteMethod then we can skip over substituteMethod while resolving a message send -// if it does not then a name clash error is likely -boolean isSubstituteParameterSubsignature(MethodBinding method, MethodBinding substituteMethod) { - if (!areParametersEqual(method, substituteMethod)) { - // method can still override substituteMethod in cases like : - // <U extends Number> void c(U u) {} - // @Override void c(Number n) {} - // but method cannot have a "generic-enabled" parameter type - if (substituteMethod.hasSubstitutedParameters() && method.areParameterErasuresEqual(substituteMethod)) - return method.typeVariables == Binding.NO_TYPE_VARIABLES && !hasGenericParameter(method); - - // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=279836 - if (method.declaringClass.isRawType() && substituteMethod.declaringClass.isRawType()) - if (method.hasSubstitutedParameters() && substituteMethod.hasSubstitutedParameters()) - return areMethodsCompatible(method, substituteMethod); - - return false; - } - - if (substituteMethod instanceof ParameterizedGenericMethodBinding) { - if (method.typeVariables != Binding.NO_TYPE_VARIABLES) - return !((ParameterizedGenericMethodBinding) substituteMethod).isRaw; - // since substituteMethod has substituted type variables, method cannot have a generic signature AND no variables -> its a name clash if it does - return !hasGenericParameter(method); - } - - // if method has its own variables, then substituteMethod failed bounds check in computeSubstituteMethod() - return method.typeVariables == Binding.NO_TYPE_VARIABLES; -} boolean isUnsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) { // called when currentMethod's return type is NOT compatible with inheritedMethod's return type @@ -1024,8 +934,8 @@ boolean isUnsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding in TypeBinding[] currentParams = currentMethod.parameters; TypeBinding[] inheritedParams = inheritedMethod.parameters; for (int i = 0, l = currentParams.length; i < l; i++) -//{ObjectTeams: added 3. arg: - if (!areTypesEqual(currentParams[i], inheritedParams[i], inheritedMethod)) +//{ObjectTeams: added arguments 3 & 4: + if (!areTypesEqual(currentParams[i], inheritedParams[i], inheritedMethod, this.environment)) // SH} return true; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java index 5bf9846c2..586bed916 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 IBM Corporation and others. + * Copyright (c) 2005, 2013 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 @@ -1319,4 +1319,70 @@ public class ParameterizedTypeBinding extends ReferenceBinding implements Substi public FieldBinding[] unResolvedFields() { return this.fields; } + public MethodBinding getSingleAbstractMethod(final Scope scope) { + MethodBinding theAbstractMethod = genericType().getSingleAbstractMethod(scope); + if (theAbstractMethod == null || !theAbstractMethod.isValidBinding()) + return theAbstractMethod; + + TypeBinding [] typeArguments = this.arguments; // A1 ... An + TypeVariableBinding [] typeParameters = genericType().typeVariables(); // P1 ... Pn + TypeBinding [] types = new TypeBinding[typeArguments.length]; // T1 ... Tn + for (int i = 0, length = typeArguments.length; i < length; i++) { + TypeBinding typeArgument = typeArguments[i]; + switch (typeArgument.kind()) { + case Binding.WILDCARD_TYPE : + WildcardBinding wildcard = (WildcardBinding) typeArgument; + switch(wildcard.boundKind) { + case Wildcard.EXTENDS : + case Wildcard.SUPER : + types[i] = wildcard.bound; + break; + case Wildcard.UNBOUND : + // if Pi has upper bound Bi that mentions none of P1...Pn, then Ti = Bi; otherwise, Ti = Object + final TypeBinding upperBound = typeParameters[i].firstBound; + if (upperBound == null || typeParametersMentioned(upperBound)) { + types[i] = scope.getJavaLangObject(); + } else { + types[i] = upperBound; + } + break; + } + break; + default : + types[i] = typeArgument; + break; + } + if (typeParameters[i].boundCheck(null, types[i]) != TypeConstants.OK) + return this.singleAbstractMethod = new ProblemMethodBinding(TypeConstants.ANONYMOUS_METHOD, null, ProblemReasons.NoSuchSingleAbstractMethod); + } + ParameterizedTypeBinding parameterizedType = scope.environment().createParameterizedType(genericType(), types, this.enclosingType); + return this.singleAbstractMethod = new ParameterizedMethodBinding(parameterizedType, theAbstractMethod); + } + + private boolean typeParametersMentioned(TypeBinding upperBound) { + class MentionListener implements Substitution { + private boolean typeParametersMentioned = false; + public TypeBinding substitute(TypeVariableBinding typeVariable) { + this.typeParametersMentioned = true; + return typeVariable; + } + public boolean isRawSubstitution() { + return false; + } + public LookupEnvironment environment() { + return null; + } + public boolean typeParametersMentioned() { + return this.typeParametersMentioned; + } +//{ObjectTeams: new method: + public ITeamAnchor substituteAnchor(ITeamAnchor anchor, int rank) { + return anchor; + } +// SH} + } + MentionListener mentionListener = new MentionListener(); + Scope.substitute(mentionListener, upperBound); + return mentionListener.typeParametersMentioned(); + } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java index 33fb90050..37c924e48 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -9,6 +9,9 @@ * IBM Corporation - initial API and implementation * Fraunhofer FIRST - extended API and implementation * Technical University Berlin - extended API and implementation + * Jesper S Moller - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression + *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -30,6 +33,8 @@ public interface ProblemReasons { final int InvalidTypeForStaticImport = 14; final int InvalidTypeForAutoManagedResource = 15; final int VarargsElementTypeNotVisible = 16; + final int NoSuchSingleAbstractMethod = 17; + final int NotAFunctionalInterface = 18; //{ObjectTeams; final int NoTeamContext = 20; final int AnchorNotFinal = 21; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java index 5ad6d9647..8bd7821cb 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -21,6 +21,8 @@ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults * bug 388281 - [compiler][null] inheritance of null annotations as an option * bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types + * Jesper S Moller - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -28,6 +30,7 @@ import java.util.Arrays; import java.util.Comparator; import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.core.compiler.InvalidInputException; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; @@ -103,6 +106,7 @@ abstract public class ReferenceBinding extends AbstractOTReferenceBinding { private SimpleLookupTable compatibleCache; int typeBits; // additional bits characterizing this type + protected MethodBinding singleAbstractMethod; public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */ public boolean hasTypeBit(int bit) { return false; } @@ -348,56 +352,6 @@ public MethodBinding[] availableMethods() { return methods(); } -public FieldBinding[] unResolvedFields() { - return Binding.NO_FIELDS; -} - -/* - * If a type - known to be a Closeable - is mentioned in one of our white lists - * answer the typeBit for the white list (BitWrapperCloseable or BitResourceFreeCloseable). - */ -protected int applyCloseableWhitelists() { - switch (this.compoundName.length) { - case 3: - if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) { - if (CharOperation.equals(TypeConstants.IO, this.compoundName[1])) { - char[] simpleName = this.compoundName[2]; - int l = TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES.length; - for (int i = 0; i < l; i++) { - if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES[i])) - return TypeIds.BitWrapperCloseable; - } - l = TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES.length; - for (int i = 0; i < l; i++) { - if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES[i])) - return TypeIds.BitResourceFreeCloseable; - } - } - } - break; - case 4: - if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) { - if (CharOperation.equals(TypeConstants.UTIL, this.compoundName[1])) { - if (CharOperation.equals(TypeConstants.ZIP, this.compoundName[2])) { - char[] simpleName = this.compoundName[3]; - int l = TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES.length; - for (int i = 0; i < l; i++) { - if (CharOperation.equals(simpleName, TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES[i])) - return TypeIds.BitWrapperCloseable; - } - } - } - } - break; - } - int l = TypeConstants.OTHER_WRAPPER_CLOSEABLES.length; - for (int i = 0; i < l; i++) { - if (CharOperation.equals(this.compoundName, TypeConstants.OTHER_WRAPPER_CLOSEABLES[i])) - return TypeIds.BitWrapperCloseable; - } - return 0; -} - /** * Answer true if the receiver can be instantiated */ @@ -1087,12 +1041,6 @@ public long getAnnotationTagBits() { return this.tagBits; } -// Answer methods named selector, which take no more than the suggestedParameterLength. -// The suggested parameter length is optional and may not be guaranteed by every type. -public MethodBinding[] getMethods(char[] selector, int suggestedParameterLength) { - return getMethods(selector); -} - /** * @return the enclosingInstancesSlotSize */ @@ -1117,8 +1065,6 @@ public FieldBinding getField(char[] fieldName, boolean needResolve) { public char[] getFileName() { return this.fileName; } -/** Answer an additional bit characterizing this type, like {@link TypeIds#BitAutoCloseable}. */ -abstract public boolean hasTypeBit(int bit); public ReferenceBinding getMemberType(char[] typeName) { ReferenceBinding[] memberTypes = memberTypes(); @@ -1144,6 +1090,13 @@ public ReferenceBinding getMemberTypeRecurse(char[] typeName) { public MethodBinding[] getMethods(char[] selector) { return Binding.NO_METHODS; } + +//Answer methods named selector, which take no more than the suggestedParameterLength. +//The suggested parameter length is optional and may not be guaranteed by every type. +public MethodBinding[] getMethods(char[] selector, int suggestedParameterLength) { + return getMethods(selector); +} + //{ObjectTeams: /** * get method by its selector, search includes superclasses, superinterfaces. @@ -1214,7 +1167,7 @@ public MethodBinding[] getMethods(char[] selector) { MethodBinding superSubstitute= verifier.computeSubstituteMethod(superMethod, match1); if (superSubstitute != null) superMethod= superSubstitute; - if (!verifier.areParametersEqual(match1, superMethod)) + if (!ImplicitNullAnnotationVerifier.areParametersEqual(match1, superMethod, verifier.environment)) foundMethod = new ProblemMethodBinding(match1.selector, Binding.NO_PARAMETERS, ProblemReasons.Ambiguous); } } @@ -1333,6 +1286,8 @@ boolean hasNonNullDefault() { public final boolean hasRestrictedAccess() { return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0; } +/** Answer an additional bit characterizing this type, like {@link TypeIds#BitAutoCloseable}. */ +abstract public boolean hasTypeBit(int bit); //{ObjectTeams: support asymmetric comparison. // FIXME(SH): is this needed or is super-impl smart enough?? @Override @@ -2023,6 +1978,57 @@ public SyntheticArgumentBinding[] syntheticOuterLocalVariables() { MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types return methods(); } + +public FieldBinding[] unResolvedFields() { + return Binding.NO_FIELDS; +} + +/* + * If a type - known to be a Closeable - is mentioned in one of our white lists + * answer the typeBit for the white list (BitWrapperCloseable or BitResourceFreeCloseable). + */ +protected int applyCloseableWhitelists() { + switch (this.compoundName.length) { + case 3: + if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) { + if (CharOperation.equals(TypeConstants.IO, this.compoundName[1])) { + char[] simpleName = this.compoundName[2]; + int l = TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES.length; + for (int i = 0; i < l; i++) { + if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES[i])) + return TypeIds.BitWrapperCloseable; + } + l = TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES.length; + for (int i = 0; i < l; i++) { + if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES[i])) + return TypeIds.BitResourceFreeCloseable; + } + } + } + break; + case 4: + if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) { + if (CharOperation.equals(TypeConstants.UTIL, this.compoundName[1])) { + if (CharOperation.equals(TypeConstants.ZIP, this.compoundName[2])) { + char[] simpleName = this.compoundName[3]; + int l = TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES.length; + for (int i = 0; i < l; i++) { + if (CharOperation.equals(simpleName, TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES[i])) + return TypeIds.BitWrapperCloseable; + } + } + } + } + break; + } + int l = TypeConstants.OTHER_WRAPPER_CLOSEABLES.length; + for (int i = 0; i < l; i++) { + if (CharOperation.equals(this.compoundName, TypeConstants.OTHER_WRAPPER_CLOSEABLES[i])) + return TypeIds.BitWrapperCloseable; + } + return 0; +} + //{ObjectTeams: support for checking substitution of a value parameter public VariableBinding valueParamSynthArgAt(int typeParamPosition) { SyntheticArgumentBinding[] args = valueParamSynthArgs(); @@ -2031,4 +2037,166 @@ public VariableBinding valueParamSynthArgAt(int typeParamPosition) { return null; } // SH} +private MethodBinding [] getInterfaceAbstractContracts(Scope scope) throws InvalidInputException { + + if (!isInterface() || !isValidBinding()) { + throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$ + } + + MethodBinding [] methods = methods(); + MethodBinding [] contracts = new MethodBinding[0]; + int contractsCount = 0; + int contractsLength = 0; + MethodBinding aContract = null; + int contractParameterLength = 0; + char [] contractSelector = null; + + for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++) { + final MethodBinding method = methods[i]; + if (!method.isAbstract() || method.redeclaresPublicObjectMethod(scope)) continue; // skips statics, defaults, public object methods ... + final boolean validBinding = method.isValidBinding(); + if (aContract == null && validBinding) { + aContract = method; + contractParameterLength = aContract.parameters.length; + contractSelector = aContract.selector; + } else { + if (!validBinding || method.parameters.length != contractParameterLength || !CharOperation.equals(contractSelector, method.selector)) { + throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$ + } + } + if (contractsCount == contractsLength) { + System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength += 16], 0, contractsCount); + } + contracts[contractsCount++] = method; + } + ReferenceBinding [] superInterfaces = superInterfaces(); + for (int i = 0, length = superInterfaces.length; i < length; i++) { + MethodBinding [] superInterfaceContracts = superInterfaces[i].getInterfaceAbstractContracts(scope); + final int superInterfaceContractsLength = superInterfaceContracts == null ? 0 : superInterfaceContracts.length; + + if (superInterfaceContractsLength == 0) continue; + if (aContract == null) { + aContract = superInterfaceContracts[0]; + contractParameterLength = aContract.parameters.length; + contractSelector = aContract.selector; + contracts = superInterfaceContracts; + contractsCount = contractsLength = superInterfaceContractsLength; + } else { + if (superInterfaceContracts[0].parameters.length != contractParameterLength || !CharOperation.equals(contractSelector, superInterfaceContracts[0].selector)) { + throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$ + } + if (contractsLength < contractsCount + superInterfaceContractsLength) { + System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength = contractsCount + superInterfaceContractsLength], 0, contractsCount); + } + System.arraycopy(superInterfaceContracts, 0, contracts, contractsCount, superInterfaceContractsLength); + contractsCount += superInterfaceContractsLength; + } + } + if (contractsCount < contractsLength) { + System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsCount], 0, contractsCount); + } + return contracts; +} +public MethodBinding getSingleAbstractMethod(Scope scope) { + + if (this.singleAbstractMethod != null) { + return this.singleAbstractMethod; + } + + MethodBinding[] methods = null; + try { + methods = getInterfaceAbstractContracts(scope); + } catch (InvalidInputException e) { + return this.singleAbstractMethod = new ProblemMethodBinding(TypeConstants.ANONYMOUS_METHOD, null, ProblemReasons.NoSuchSingleAbstractMethod); + } + if (methods != null && methods.length == 1) + return this.singleAbstractMethod = methods[0]; + + final LookupEnvironment environment = scope.environment(); + boolean genericMethodSeen = false; + next:for (int i = 0, length = methods.length; i < length; i++) { + MethodBinding method = methods[i], otherMethod = null; + if (method.typeVariables != Binding.NO_TYPE_VARIABLES) + genericMethodSeen = true; + for (int j = 0; j < length; j++) { + if (i == j) continue; + otherMethod = methods[j]; + if (otherMethod.typeVariables != Binding.NO_TYPE_VARIABLES) + genericMethodSeen = true; + if (!MethodVerifier.isParameterSubsignature(method, otherMethod, environment) || !MethodVerifier.areReturnTypesCompatible(method, otherMethod, environment)) + continue next; + } + // If we reach here, we found a method that is override equivalent with every other method and is also return type substitutable. Compute kosher exceptions now ... + ReferenceBinding [] exceptions = new ReferenceBinding[0]; + int exceptionsCount = 0, exceptionsLength = 0; + final MethodBinding theAbstractMethod = method; + boolean shouldEraseThrows = theAbstractMethod.typeVariables == Binding.NO_TYPE_VARIABLES && genericMethodSeen; + boolean shouldAdaptThrows = theAbstractMethod.typeVariables != Binding.NO_TYPE_VARIABLES; + final int typeVariableLength = theAbstractMethod.typeVariables.length; + + none:for (i = 0; i < length; i++) { + method = methods[i]; + ReferenceBinding[] methodThrownExceptions = method.thrownExceptions; + int methodExceptionsLength = methodThrownExceptions == null ? 0: methodThrownExceptions.length; + if (methodExceptionsLength == 0) break none; + if (shouldAdaptThrows && method != theAbstractMethod) { + System.arraycopy(methodThrownExceptions, 0, methodThrownExceptions = new ReferenceBinding[methodExceptionsLength], 0, methodExceptionsLength); + for (int tv = 0; tv < typeVariableLength; tv++) { + if (methodThrownExceptions[tv] instanceof TypeVariableBinding) { + methodThrownExceptions[tv] = theAbstractMethod.typeVariables[tv]; + } + } + } + nextException: for (int j = 0; j < methodExceptionsLength; j++) { + ReferenceBinding methodException = methodThrownExceptions[j]; + if (shouldEraseThrows) + methodException = (ReferenceBinding) methodException.erasure(); + nextMethod: for (int k = 0; k < length; k++) { + if (i == k) continue; + otherMethod = methods[k]; + ReferenceBinding[] otherMethodThrownExceptions = otherMethod.thrownExceptions; + int otherMethodExceptionsLength = otherMethodThrownExceptions == null ? 0 : otherMethodThrownExceptions.length; + if (otherMethodExceptionsLength == 0) break none; + if (shouldAdaptThrows && otherMethod != theAbstractMethod) { + System.arraycopy(otherMethodThrownExceptions, + 0, + otherMethodThrownExceptions = new ReferenceBinding[otherMethodExceptionsLength], + 0, + otherMethodExceptionsLength); + for (int tv = 0; tv < typeVariableLength; tv++) { + if (otherMethodThrownExceptions[tv] instanceof TypeVariableBinding) { + otherMethodThrownExceptions[tv] = theAbstractMethod.typeVariables[tv]; + } + } + } + for (int l = 0; l < otherMethodExceptionsLength; l++) { + ReferenceBinding otherException = otherMethodThrownExceptions[l]; + if (shouldEraseThrows) + otherException = (ReferenceBinding) otherException.erasure(); + if (methodException.isCompatibleWith(otherException)) + continue nextMethod; + } + continue nextException; + } + // If we reach here, method exception or its super type is covered by every throws clause. + if (exceptionsCount == exceptionsLength) { + System.arraycopy(exceptions, 0, exceptions = new ReferenceBinding[exceptionsLength += 16], 0, exceptionsCount); + } + exceptions[exceptionsCount++] = methodException; + } + } + if (exceptionsCount != exceptionsLength) { + System.arraycopy(exceptions, 0, exceptions = new ReferenceBinding[exceptionsCount], 0, exceptionsCount); + } + this.singleAbstractMethod = new MethodBinding(theAbstractMethod.modifiers, + theAbstractMethod.selector, + theAbstractMethod.returnType, + theAbstractMethod.parameters, + exceptions, + theAbstractMethod.declaringClass); + this.singleAbstractMethod.typeVariables = theAbstractMethod.typeVariables; + return this.singleAbstractMethod; + } + return this.singleAbstractMethod = new ProblemMethodBinding(TypeConstants.ANONYMOUS_METHOD, null, ProblemReasons.NoSuchSingleAbstractMethod); +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java index bceeae03e..febc18dba 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -16,6 +16,8 @@ * Stephen Herrmann <stephan@cs.tu-berlin.de> - Contributions for * bug 317046 - Exception during debugging when hover mouse over a field * bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types + * Jesper S Moller <jesper@selskabet.org> - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -1301,4 +1303,14 @@ public DependentTypeBinding asPlainDependentType() { return null; // is not a dependent type } // SH} + +/** + * Return the single abstract method of a functional interface, or null, if the receiver is not a functional interface as defined in JLS 9.8. + * @param scope scope + * + * @return The single abstract method of a functional interface, or null, if the receiver is not a functional interface. + */ +public MethodBinding getSingleAbstractMethod(Scope scope) { + return null; +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java index 66569aa02..8205d623b 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -85,6 +85,7 @@ public interface TypeConstants { char[] UPPER_LOCAL_VARIABLE = "LOCAL_VARIABLE".toCharArray(); //$NON-NLS-1$ char[] UPPER_ANNOTATION_TYPE = "ANNOTATION_TYPE".toCharArray(); //$NON-NLS-1$ char[] UPPER_PACKAGE = "PACKAGE".toCharArray(); //$NON-NLS-1$ + char[] ANONYMOUS_METHOD = " anonymous ".toCharArray(); //$NON-NLS-1$ // for now - serialization issues ? // jsr308 char[] TYPE_USE_TARGET = "TYPE_USE".toCharArray(); //$NON-NLS-1$ 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 d00d2089c..ce39db1eb 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -18,6 +18,8 @@ * bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639) * bug 374605 - Unreasonable warning for enum-based switch statements * bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods. + * Jesper S Moller - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression *******************************************************************************/ package org.eclipse.jdt.internal.compiler.parser; @@ -6165,20 +6167,20 @@ protected void consumeMethodInvocationName() { this.identifierLengthPtr--; } else { this.identifierLengthStack[this.identifierLengthPtr]--; - int length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]; - Annotation [] typeAnnotations; - if (length != 0) { - System.arraycopy( - this.typeAnnotationStack, - (this.typeAnnotationPtr -= length) + 1, - typeAnnotations = new Annotation[length], - 0, - length); - problemReporter().misplacedTypeAnnotations(typeAnnotations[0], typeAnnotations[typeAnnotations.length - 1]); - } m.receiver = getUnspecifiedReference(); m.sourceStart = m.receiver.sourceStart; } + int length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]; + Annotation [] typeAnnotations; + if (length != 0) { + System.arraycopy( + this.typeAnnotationStack, + (this.typeAnnotationPtr -= length) + 1, + typeAnnotations = new Annotation[length], + 0, + length); + problemReporter().misplacedTypeAnnotations(typeAnnotations[0], typeAnnotations[typeAnnotations.length - 1]); + } pushOnExpressionStack(m); } protected void consumeMethodInvocationNameWithTypeArguments() { @@ -9760,7 +9762,7 @@ protected void consumeLambdaExpression() { problemReporter().illegalThis(arguments[i]); } } - LambdaExpression lexp = new LambdaExpression(arguments, body); + LambdaExpression lexp = new LambdaExpression(this.compilationUnit.compilationResult, arguments, body); this.intPtr--; // ')' position, discard for now. lexp.sourceStart = this.intStack[this.intPtr--]; // '(' position or identifier position. lexp.sourceEnd = body.sourceEnd; 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 fed07305b..7a2ce40ff 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -29,6 +29,9 @@ * bug 388281 - [compiler][null] inheritance of null annotations as an option * bug 376053 - [compiler][resource] Strange potential resource leak problems * bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types + * bug 388739 - [1.8][compiler] consider default methods when detecting whether a class needs to be declared abstract + * Jesper S Moller <jesper@selskabet.org> - Contributions for + * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression *******************************************************************************/ package org.eclipse.jdt.internal.compiler.problem; @@ -1486,6 +1489,14 @@ public void cannotUseSuperInJavaLangObject(ASTNode reference) { reference.sourceStart, reference.sourceEnd); } +public void targetTypeIsNotAFunctionalInterface(ASTNode target) { + this.handle( + IProblem.TargetTypeNotAFunctionalInterface, + NoArgument, + NoArgument, + target.sourceStart, + target.sourceEnd); +} public void caseExpressionMustBeConstant(Expression expression) { this.handle( IProblem.NonConstantExpression, @@ -2974,6 +2985,15 @@ public void illegalVararg(Argument argType, AbstractMethodDeclaration methodDecl argType.sourceStart, argType.sourceEnd); } +public void illegalVarargInLambda(Argument argType) { + String[] arguments = new String[] { CharOperation.toString(argType.type.getTypeName())}; + this.handle( + IProblem.IllegalVarargInLambda, + arguments, + arguments, + argType.sourceStart, + argType.sourceEnd); +} public void illegalThisDeclaration(Argument argument) { String[] arguments = NoArgument; this.handle( @@ -3002,11 +3022,20 @@ public void disallowedThisParameter(Receiver receiver) { receiver.sourceEnd); } public void illegalQualifierForExplicitThis(Receiver receiver, TypeBinding expectedType) { + String[] problemArguments = new String[] { new String(expectedType.sourceName())}; this.handle( IProblem.IllegalQualifierForExplicitThis, - new String[] { new String(expectedType.readableName())}, - new String[] { new String(expectedType.qualifiedSourceName())}, - receiver.sourceStart, + problemArguments, + problemArguments, + (receiver.qualifyingName == null) ? receiver.sourceStart : receiver.qualifyingName.sourceStart, + receiver.sourceEnd); +} +public void illegalQualifierForExplicitThis2(Receiver receiver) { + this.handle( + IProblem.IllegalQualifierForExplicitThis2, + NoArgument, + NoArgument, + receiver.qualifyingName.sourceStart, receiver.sourceEnd); } public void illegalTypeForExplicitThis(Receiver receiver, TypeBinding expectedType) { @@ -3474,10 +3503,11 @@ public void inheritedMethodsHaveIncompatibleReturnTypes(ASTNode location, Method location.sourceStart, location.sourceEnd); } -public void inheritedMethodsHaveIncompatibleReturnTypes(SourceTypeBinding type, MethodBinding[] inheritedMethods, int length) { +public void inheritedMethodsHaveIncompatibleReturnTypes(SourceTypeBinding type, MethodBinding[] inheritedMethods, int length, boolean[] isOverridden) { StringBuffer methodSignatures = new StringBuffer(); StringBuffer shortSignatures = new StringBuffer(); for (int i = length; --i >= 0;) { + if (isOverridden[i]) continue; methodSignatures .append(inheritedMethods[i].declaringClass.readableName()) .append('.') 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 c30428eea..d5bb0dfa7 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 @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2000, 2012 IBM Corporation and others. +# Copyright (c) 2000, 2013 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 @@ -27,6 +27,8 @@ # bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance # bug 388281 - [compiler][null] inheritance of null annotations as an option # bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types +# Jesper S Moller <jesper@selskabet.org> - Contributions for +# bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression ############################################################################### 0 = {0} 1 = super cannot be used in java.lang.Object @@ -607,6 +609,9 @@ 649 = Annotation types that do not specify explicit target element types cannot be applied here 650 = The declared type of the explicit ''this'' parameter is expected to be {0} 651 = The explicit ''this'' parameter is expected to be qualified with {0} +652 = The explicit ''this'' parameter for a method cannot have a qualifying name +653 = The target type of this expression must be a functional interface +654 = The variable argument type {0} of the lambda expression must be the last parameter ### MORE GENERICS 660 = Unused type arguments for the non generic constructor {0}({1}) of type {2}; it should not be parameterized with arguments <{3}> 661 = Unused type parameter {0} diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Sorting.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Sorting.java new file mode 100644 index 000000000..d7670a9df --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Sorting.java @@ -0,0 +1,114 @@ +/********************************************************************** + * Copyright 2008, 2012 Technical University Berlin, Germany 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: + * Stephan Herrmann - Initial API and implementation + **********************************************************************/ +package org.eclipse.jdt.internal.compiler.util; + +import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; +import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; +import org.eclipse.jdt.internal.compiler.lookup.TypeIds; + +/** + * Sorting utilities. + * Originally developed for the <a href="http://www.eclipse.org/objectteams">Object Teams project</a>. + */ +public class Sorting { + + /** + * Topological sort for types + * Guarantee: supertypes come before subtypes. + */ + public static ReferenceBinding[] sortTypes(ReferenceBinding[] types) { + int len = types.length; + + ReferenceBinding[] unsorted = new ReferenceBinding[len]; + ReferenceBinding[] sorted = new ReferenceBinding[len]; + System.arraycopy(types, 0, unsorted, 0, len); + + int o = 0; + for(int i=0; i<len; i++) + o = sort(unsorted, i, sorted, o); + + return sorted; + } + // Transfer input[i] and all its supers into output[o] ff. + private static int sort(ReferenceBinding[] input, int i, + ReferenceBinding[] output, int o) + { + if (input[i] == null) + return o; + + ReferenceBinding superclass = input[i].superclass(); + o = sortSuper(superclass, input, output, o); + + ReferenceBinding[] superInterfaces = input[i].superInterfaces(); + for (int j=0; j<superInterfaces.length; j++) { + o = sortSuper(superInterfaces[j], input, output, o); + } + + // done with supers, now input[i] can safely be transferred: + output[o++] = input[i]; + input[i] = null; + + return o; + } + // if superclass is within the set of types to sort, + // transfer it and all its supers to output[o] ff. + private static int sortSuper(ReferenceBinding superclass, + ReferenceBinding[] input, + ReferenceBinding[] output, int o) + { +//{ObjectTeams: top-confined types have no super: + if (superclass == null) + return o; +//SH} + if (superclass.id != TypeIds.T_JavaLangObject) { + // search superclass within input: + int j = 0; + for(j=0; j<input.length; j++) + if (input[j] == superclass) + break; + if (j < input.length) + // depth first traversal: + o = sort(input, j, output, o); + // otherwise assume super was already transferred. + } + return o; + } + public static MethodBinding[] concreteFirst(MethodBinding[] methods, int length) { + if (length == 0 || (length > 0 && !methods[0].isAbstract())) + return methods; + MethodBinding[] copy = new MethodBinding[length]; + int idx = 0; + for (int i=0; i<length; i++) + if (!methods[i].isAbstract()) + copy[idx++] = methods[i]; + for (int i=0; i<length; i++) + if (methods[i].isAbstract()) + copy[idx++] = methods[i]; + return copy; + } + public static MethodBinding[] abstractFirst(MethodBinding[] methods, int length) { + if (length == 0 || (length > 0 && methods[0].isAbstract())) + return methods; + MethodBinding[] copy = new MethodBinding[length]; + int idx = 0; + for (int i=0; i<length; i++) + if (methods[i].isAbstract()) + copy[idx++] = methods[i]; + for (int i=0; i<length; i++) + if (!methods[i].isAbstract()) + copy[idx++] = methods[i]; + return copy; + } +} diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java index f49141994..58e22dba8 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -1155,6 +1155,25 @@ public final class AST { } /** + * Creates and returns a new unparented annotatable extra dimension node + * (Supported only in JLS8 level). + * + * @return a new unparented annotatable extra dimension node + * @exception IllegalArgumentException if: + * <ul> + * <li>the node belongs to a different AST</li> + * <li>the node already has a parent</li> + * </ul> + * @exception UnsupportedOperationException if this operation is used + * in a JLS2, JLS3 or JLS4 AST + * @since 3.9 + */ + public ExtraDimension newExtraDimension() { + ExtraDimension result = new ExtraDimension(this); + return result; + } + + /** * Creates and returns a new unparented array type node with the given * element type and number of (additional) dimensions. * <p> diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java index 7e376ec2b..4590c6e5c 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -51,6 +51,7 @@ import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.Receiver; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation; @@ -462,6 +463,36 @@ class ASTConverter { } } } + /** + * Internal access method to SingleVariableDeclaration#setExtraDimensions() for avoiding deprecated warnings + * + * @param node + * @param dimensions + * @deprecated + */ + private void internalSetExtraDimensions(SingleVariableDeclaration node, int dimensions) { + node.setExtraDimensions(dimensions); + } + /** + * Internal access method to VariableDeclarationFragment#setExtraDimensions() for avoiding deprecated warnings + * + * @param node + * @param dimensions + * @deprecated + */ + private void internalSetExtraDimensions(VariableDeclarationFragment node, int dimensions) { + node.setExtraDimensions(dimensions); + } + /** + * Internal access method to MethodDeclaration#setExtraDimension() for avoiding deprecated warnings + * + * @param node + * @param dimensions + * @deprecated + */ + private void internalSetExtraDimensions(MethodDeclaration node, int dimensions) { + node.setExtraDimensions(dimensions); + } /** * @param compilationUnit @@ -575,13 +606,31 @@ class ASTConverter { int methodHeaderEnd = methodDeclaration.sourceEnd; int thrownExceptionsLength = thrownExceptions == null ? 0 : thrownExceptions.length; if (thrownExceptionsLength > 0) { - Name thrownException; - int i = 0; - do { - thrownException = convert(thrownExceptions[i++]); - methodDecl.thrownExceptions().add(thrownException); - } while (i < thrownExceptionsLength); - methodHeaderEnd = thrownException.getStartPosition() + thrownException.getLength(); + if (this.ast.apiLevel() < AST.JLS8) { + Name thrownException; + int i = 0; + do { + thrownException = convert(thrownExceptions[i++]); + methodDecl.thrownExceptions().add(thrownException); + } while (i < thrownExceptionsLength); + methodHeaderEnd = thrownException.getStartPosition() + thrownException.getLength(); + } else { + Type thrownExceptionType; + int i = 0; + do { + thrownExceptionType = convertType(thrownExceptions[i++]); + methodDecl.thrownExceptionTypes().add(thrownExceptionType); + } while (i < thrownExceptionsLength); + methodHeaderEnd = thrownExceptionType.getStartPosition() + thrownExceptionType.getLength(); + } + } + + if (methodDeclaration.receiver != null) { + if(this.ast.apiLevel >= AST.JLS8) { + convertAndSetReceiver(methodDeclaration, methodDecl); + } else { + methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED); + } } //{ObjectTeams: /* orig: @@ -628,7 +677,12 @@ class ASTConverter { // get the positions of the right parenthesis int rightParenthesisPosition = retrieveEndOfRightParenthesisPosition(end, method.bodyEnd); int extraDimensions = retrieveExtraDimension(rightParenthesisPosition, method.bodyEnd); - methodDecl.setExtraDimensions(extraDimensions); + if (this.ast.apiLevel >= AST.JLS8) { + setExtraAnnotatedDimensions(rightParenthesisPosition, this.scanner.currentPosition, typeReference, + methodDecl.extraDimensionInfos, extraDimensions); + } else { + internalSetExtraDimensions(methodDecl, extraDimensions); + } setTypeForMethodDeclaration(methodDecl, returnType, extraDimensions); } else { // no return type for a method that is not a constructor @@ -928,6 +982,36 @@ class ASTConverter { return annotationTypeMemberDeclaration2; } + private void convertAndSetReceiver(AbstractMethodDeclaration method, MethodDeclaration methodDecl) { + Receiver receiver = method.receiver; + if (receiver.qualifyingName != null) { + final SimpleName name = new SimpleName(this.ast); + name.internalSetIdentifier(new String(receiver.qualifyingName.getName()[0])); + int start = receiver.qualifyingName.sourceStart; + int nameEnd = receiver.qualifyingName.sourceEnd; + name.setSourceRange(start, nameEnd - start + 1); + methodDecl.setReceiverQualifier(name); + if (this.resolveBindings) { + recordNodes(name, receiver); + } + } + AnnotatableType type = (AnnotatableType) convertType(receiver.type); + org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = receiver.annotations; + int length = (annotations == null) ? 0 : annotations.length; + for (int i = 0; i < length; i++) { + type.annotations().add(convert(annotations[i])); + } + if (length > 0) { + int start = annotations[0].sourceStart; + type.setSourceRange(start, (receiver.type.sourceEnd - start + 1)); + } + methodDecl.setReceiverType(type); + if (this.resolveBindings) { + recordNodes(type, receiver); + type.resolveBinding(); + } + } + public SingleVariableDeclaration convert(org.eclipse.jdt.internal.compiler.ast.Argument argument) { SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast); setModifiers(variableDecl, argument); @@ -946,7 +1030,12 @@ class ASTConverter { variableDecl.setName(name); final int typeSourceEnd = argument.type.sourceEnd; final int extraDimensions = retrieveExtraDimension(nameEnd + 1, typeSourceEnd); - variableDecl.setExtraDimensions(extraDimensions); + if (this.ast.apiLevel >= AST.JLS8) { + setExtraAnnotatedDimensions(nameEnd + 1, this.scanner.currentPosition, argument.type, + variableDecl.extraDimensionInfos, extraDimensions); + } else { + internalSetExtraDimensions(variableDecl, extraDimensions); + } final boolean isVarArgs = argument.isVarArgs(); if (isVarArgs && extraDimensions == 0) { // remove the ellipsis from the type source end @@ -961,6 +1050,18 @@ class ASTConverter { */ if (isVarArgs) { setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions + 1); + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391898 + if (type.isAnnotatable()) { + AnnotatableType annotatableType = (AnnotatableType) type; + if (this.ast.apiLevel() >= AST.JLS8 && !annotatableType.annotations().isEmpty()) { + Iterator annotations = annotatableType.annotations.iterator(); + while (annotations.hasNext()) { + Annotation annotation = (Annotation) annotations.next(); + annotation.setParent(null, null); + variableDecl.varargsAnnotations().add(annotation); + } + } + } if (extraDimensions != 0) { variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED); } @@ -3049,7 +3150,7 @@ class ASTConverter { // QualifiedName org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference qualifiedTypeReference = (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference; final long[] positions = qualifiedTypeReference.sourcePositions; - return setQualifiedNameNameAndSourceRanges(typeName, positions, typeReference, typeReference.annotations); + return setQualifiedNameNameAndSourceRanges(typeName, positions, typeReference); } else { final SimpleName name = new SimpleName(this.ast); name.internalSetIdentifier(new String(typeName[0])); @@ -3058,10 +3159,6 @@ class ASTConverter { if (this.resolveBindings) { recordNodes(name, typeReference); } - org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations; - if (typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) { - annotateName(name, annotations); - } return name; } } @@ -3277,7 +3374,12 @@ class ASTConverter { name.setSourceRange(start, nameEnd - start + 1); variableDecl.setName(name); final int extraDimensions = retrieveExtraDimension(nameEnd + 1, localDeclaration.type.sourceEnd); - variableDecl.setExtraDimensions(extraDimensions); + if (this.ast.apiLevel >= AST.JLS8) { + setExtraAnnotatedDimensions(nameEnd + 1, this.scanner.currentPosition, localDeclaration.type, + variableDecl.extraDimensionInfos, extraDimensions); + } else { + internalSetExtraDimensions(variableDecl, extraDimensions); + } Type type = convertType(localDeclaration.type); int typeEnd = type.getStartPosition() + type.getLength() - 1; int rightEnd = Math.max(typeEnd, localDeclaration.declarationSourceEnd); @@ -3295,6 +3397,17 @@ class ASTConverter { return variableDecl; } + private ExtraDimension convertToExtraDimensions(int start, int end, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotation) { + int length = annotation == null ? 0 : annotation.length; + ExtraDimension dimension = this.ast.newExtraDimension(); + for (int i = 0; i < length; i++) { + Annotation annot = convert(annotation[i]); + dimension.annotations.add(annot); + } + retrieveDimensionAndSetPositions(start, end, dimension); + return dimension; + } + protected VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) { final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast); final SimpleName name = new SimpleName(this.ast); @@ -3304,7 +3417,12 @@ class ASTConverter { int start = fieldDeclaration.sourceEnd; int end = start; int extraDimensions = retrieveExtraDimension(fieldDeclaration.sourceEnd + 1, fieldDeclaration.declarationSourceEnd ); - variableDeclarationFragment.setExtraDimensions(extraDimensions); + if (this.ast.apiLevel >= AST.JLS8) { + setExtraAnnotatedDimensions(fieldDeclaration.sourceEnd + 1, this.scanner.currentPosition, + fieldDeclaration.type, variableDeclarationFragment.extraDimensionInfos, extraDimensions); + } else { + internalSetExtraDimensions(variableDeclarationFragment, extraDimensions); + } if (fieldDeclaration.initialization != null) { final Expression expression = convert(fieldDeclaration.initialization); variableDeclarationFragment.setInitializer(expression); @@ -3342,7 +3460,13 @@ class ASTConverter { int start = localDeclaration.sourceEnd; org.eclipse.jdt.internal.compiler.ast.Expression initialization = localDeclaration.initialization; int extraDimension = retrieveExtraDimension(localDeclaration.sourceEnd + 1, this.compilationUnitSourceLength); - variableDeclarationFragment.setExtraDimensions(extraDimension); + if (this.ast.apiLevel >= AST.JLS8) { + setExtraAnnotatedDimensions(localDeclaration.sourceEnd + 1, this.scanner.currentPosition, + localDeclaration.type, variableDeclarationFragment.extraDimensionInfos, extraDimension); + } else { + internalSetExtraDimensions(variableDeclarationFragment, extraDimension); + } + boolean hasInitialization = initialization != null; int end; if (hasInitialization) { @@ -3373,6 +3497,18 @@ class ASTConverter { return variableDeclarationFragment; } + protected void setExtraAnnotatedDimensions(int start, int end, TypeReference type, final List extraAnnotatedDimensions, int extraDimension) { + if (extraDimension > 0) { + org.eclipse.jdt.internal.compiler.ast.Annotation[][] annotationsOnDims = type.getAnnotationsOnDimensions(); + int length = (annotationsOnDims == null) ? 0 : annotationsOnDims.length; + for (int i = (length - extraDimension); i < length; i++) { + ExtraDimension dim = convertToExtraDimensions(start, end, (annotationsOnDims == null) ? null : annotationsOnDims[i]); + extraAnnotatedDimensions.add(dim); + start = dim.getStartPosition() + dim.getLength(); + } + } + } + protected VariableDeclarationStatement convertToVariableDeclarationStatement(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) { final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration); final VariableDeclarationStatement variableDeclarationStatement = new VariableDeclarationStatement(this.ast); @@ -3389,7 +3525,7 @@ class ASTConverter { return variableDeclarationStatement; } - private void annotateType(Type type, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations) { + private void annotateType(AnnotatableType type, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations) { switch(this.ast.apiLevel) { case AST.JLS2_INTERNAL : case AST.JLS3_INTERNAL : @@ -3410,27 +3546,7 @@ class ASTConverter { } } } - private void annotateName(Name name, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations) { - switch(this.ast.apiLevel) { - case AST.JLS2_INTERNAL : - case AST.JLS3_INTERNAL : - case AST.JLS4: - name.setFlags(name.getFlags() | ASTNode.MALFORMED); - break; - default: - int annotationsLength = annotations.length; - for (int i = 0; i < annotationsLength; i++) { - org.eclipse.jdt.internal.compiler.ast.Annotation typeAnnotation = annotations[i]; - if (typeAnnotation != null) { - Annotation annotation = convert(typeAnnotation); - int start = typeAnnotation.sourceStart; - int end = typeAnnotation.sourceEnd; - annotation.setSourceRange(start, end - start + 1); - name.annotations.add(annotation); - } - } - } - } + private void annotateTypeParameter(TypeParameter typeParameter, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations) { switch(this.ast.apiLevel) { case AST.JLS2_INTERNAL : @@ -3497,7 +3613,8 @@ class ASTConverter { length = typeReference.sourceEnd - typeReference.sourceStart + 1; // need to find out if this is an array type of primitive types or not if (isPrimitiveType(name)) { - int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length); + int[] positions = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length); + int end = positions[1]; if (end == -1) { end = sourceStart + length - 1; } @@ -3512,11 +3629,17 @@ class ASTConverter { ParameterizedSingleTypeReference parameterizedSingleTypeReference = (ParameterizedSingleTypeReference) typeReference; final SimpleName simpleName = new SimpleName(this.ast); simpleName.internalSetIdentifier(new String(name)); - int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length); + int[] positions = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length); + int end = positions[1]; if (end == -1) { end = sourceStart + length - 1; } - simpleName.setSourceRange(sourceStart, end - sourceStart + 1); + if (positions[0] != -1) { + simpleName.setSourceRange(positions[0], end - positions[0] + 1); + } else { + simpleName.setSourceRange(sourceStart, end - sourceStart + 1); + } + switch(this.ast.apiLevel) { case AST.JLS2_INTERNAL : SimpleType simpleType = new SimpleType(this.ast); @@ -3571,11 +3694,16 @@ class ASTConverter { simpleName.internalSetIdentifier(new String(name)); // we need to search for the starting position of the first brace in order to set the proper length // PR http://dev.eclipse.org/bugs/show_bug.cgi?id=10759 - int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length); + int[] positions = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length); + int end = positions[1]; if (end == -1) { end = sourceStart + length - 1; } - simpleName.setSourceRange(sourceStart, end - sourceStart + 1); + if (positions[0] != -1) { + simpleName.setSourceRange(positions[0], end - positions[0] + 1); + } else { + simpleName.setSourceRange(sourceStart, end - sourceStart + 1); + } final SimpleType simpleType = new SimpleType(this.ast); simpleType.setName(simpleName); type = simpleType; @@ -3616,6 +3744,10 @@ class ASTConverter { ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference = (ParameterizedQualifiedTypeReference) typeReference; char[][] tokens = parameterizedQualifiedTypeReference.tokens; TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments; + org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations = parameterizedQualifiedTypeReference.annotations; + TypeReference[] arguments = null; + int lenth = tokens.length; + int firstTypeIndex = lenth - 1; long[] positions = parameterizedQualifiedTypeReference.sourcePositions; sourceStart = (int)(positions[0]>>>32); switch(this.ast.apiLevel) { @@ -3624,7 +3756,7 @@ class ASTConverter { int nameLength = name.length; sourceStart = (int)(positions[0]>>>32); length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1; - Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference, typeReference.annotations); + Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference); final SimpleType simpleType = new SimpleType(this.ast); simpleType.setName(qualifiedName); simpleType.setSourceRange(sourceStart, length); @@ -3633,115 +3765,131 @@ class ASTConverter { } break; default : - if (typeArguments != null) { - int numberOfEnclosingType = 0; - int startingIndex = 0; - int endingIndex = 0; - for (int i = 0, max = typeArguments.length; i < max; i++) { - if (typeArguments[i] != null) { - numberOfEnclosingType++; - } else if (numberOfEnclosingType == 0) { - endingIndex++; - } + for (int i = 0; i < lenth; ++i) { + if (typeArguments != null && typeArguments[i] != null) { + firstTypeIndex = i; + break; } - Name name = null; - if (endingIndex - startingIndex == 0) { - final SimpleName simpleName = new SimpleName(this.ast); - simpleName.internalSetIdentifier(new String(tokens[startingIndex])); - recordPendingNameScopeResolution(simpleName); - int start = (int)(positions[startingIndex]>>>32); - int end = (int) positions[startingIndex]; - simpleName.setSourceRange(start, end - start + 1); - simpleName.index = 1; - name = simpleName; - if (this.resolveBindings) { - recordNodes(simpleName, typeReference); - } - } else { - name = this.setQualifiedNameNameAndSourceRanges(tokens, positions, endingIndex, typeReference); + if (typeAnnotations != null && typeAnnotations[i] != null) { + firstTypeIndex = i; + break; } - SimpleType simpleType = new SimpleType(this.ast); - simpleType.setName(name); - int start = (int)(positions[startingIndex]>>>32); - int end = (int) positions[endingIndex]; - simpleType.setSourceRange(start, end - start + 1); - if (endingIndex == 0 && typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) { - annotateType(simpleType, annotations); + } + + Name name = null; + if (firstTypeIndex == 0) { + final SimpleName simpleName = new SimpleName(this.ast); + simpleName.setIdentifier(new String(tokens[0])); + recordPendingNameScopeResolution(simpleName); + int start = (int) (positions[0] >>> 32); + int end = (int) positions[0]; + simpleName.setSourceRange(start, end - start + 1); + simpleName.index = 1; + name = simpleName; + if (this.resolveBindings) { + recordNodes(simpleName, typeReference); } + } else { + name = this.setQualifiedNameNameAndSourceRanges(tokens, positions, firstTypeIndex, typeReference); + } + + SimpleType simpleType = new SimpleType(this.ast); + simpleType.setName(name); + int start = (int)(positions[0] >>> 32); + int end = (int)positions[firstTypeIndex]; + simpleType.setSourceRange(start, end - start + 1); + if (typeAnnotations != null && (annotations = typeAnnotations[firstTypeIndex]) != null) { + annotateType(simpleType, annotations); + } + if (this.resolveBindings) { + recordNodes(simpleType, typeReference); + } + Type currentType = simpleType; + int indexOfEnclosingType = 1; + if (typeArguments != null && (arguments = typeArguments[firstTypeIndex]) != null) { + int arglen = arguments.length; ParameterizedType parameterizedType = new ParameterizedType(this.ast); - parameterizedType.setType(simpleType); + parameterizedType.index = indexOfEnclosingType; + parameterizedType.setType(currentType); if (this.resolveBindings) { - recordNodes(simpleType, typeReference); recordNodes(parameterizedType, typeReference); } - start = simpleType.getStartPosition(); - end = start + simpleType.getLength() - 1; - for (int i = 0, max = typeArguments[endingIndex].length; i < max; i++) { - final Type type2 = convertType(typeArguments[endingIndex][i]); + Type type2 = null; + for (int i = 0; i < arglen; ++i ) { + type2 = convertType(arguments[i]); parameterizedType.typeArguments().add(type2); - end = type2.getStartPosition() + type2.getLength() - 1; } - int indexOfEnclosingType = 1; - parameterizedType.index = indexOfEnclosingType; + end = type2 != null ? type2.getStartPosition() + type2.getLength() - 1 : end; end = retrieveClosingAngleBracketPosition(end + 1); - length = end + 1; parameterizedType.setSourceRange(start, end - start + 1); - startingIndex = endingIndex + 1; - Type currentType = parameterizedType; - while(startingIndex < typeArguments.length) { - SimpleName simpleName = new SimpleName(this.ast); - simpleName.internalSetIdentifier(new String(tokens[startingIndex])); - simpleName.index = startingIndex + 1; - start = (int)(positions[startingIndex]>>>32); - end = (int) positions[startingIndex]; - simpleName.setSourceRange(start, end - start + 1); - recordPendingNameScopeResolution(simpleName); - QualifiedType qualifiedType = new QualifiedType(this.ast); - qualifiedType.setQualifier(currentType); - qualifiedType.setName(simpleName); - if (typeReference.annotations != null && (annotations = typeReference.annotations[startingIndex]) != null) { - annotateType(qualifiedType, annotations); - } + currentType = parameterizedType; + } + + for (int i = firstTypeIndex + 1; i < lenth; ++i) { + SimpleName simpleName = new SimpleName(this.ast); + simpleName.setIdentifier(new String(tokens[i])); + simpleName.index = i + 1; + start = (int) (positions[i] >>> 32); + end = (int) positions[i]; + simpleName.setSourceRange(start, end - start + 1); + recordPendingNameScopeResolution(simpleName); + QualifiedType qualifiedType = new QualifiedType(this.ast); + qualifiedType.setQualifier(currentType); + qualifiedType.setName(simpleName); + if (typeAnnotations != null && (annotations = typeAnnotations[i]) != null) { + annotateType(qualifiedType, annotations); + } + if (this.resolveBindings) { + recordNodes(simpleName, typeReference); + recordNodes(qualifiedType, typeReference); + } + start = currentType.getStartPosition(); + end = simpleName.getStartPosition() + simpleName.getLength() - 1; + qualifiedType.setSourceRange(start, end - start + 1); + currentType = qualifiedType; + indexOfEnclosingType++; + + if (typeArguments != null && (arguments = typeArguments[i]) != null) { + int arglen = arguments.length; + qualifiedType.index = indexOfEnclosingType; + ParameterizedType parameterizedType = new ParameterizedType(this.ast); + parameterizedType.index = indexOfEnclosingType; + parameterizedType.setType(currentType); if (this.resolveBindings) { - recordNodes(simpleName, typeReference); - recordNodes(qualifiedType, typeReference); + recordNodes(parameterizedType, typeReference); } - start = currentType.getStartPosition(); - end = simpleName.getStartPosition() + simpleName.getLength() - 1; - qualifiedType.setSourceRange(start, end - start + 1); - indexOfEnclosingType++; - if (typeArguments[startingIndex] != null) { - qualifiedType.index = indexOfEnclosingType; - ParameterizedType parameterizedType2 = new ParameterizedType(this.ast); - parameterizedType2.setType(qualifiedType); - parameterizedType2.index = indexOfEnclosingType; - if (this.resolveBindings) { - recordNodes(parameterizedType2, typeReference); - } - for (int i = 0, max = typeArguments[startingIndex].length; i < max; i++) { - final Type type2 = convertType(typeArguments[startingIndex][i]); - parameterizedType2.typeArguments().add(type2); - end = type2.getStartPosition() + type2.getLength() - 1; - } - end = retrieveClosingAngleBracketPosition(end + 1); - length = end + 1; - parameterizedType2.setSourceRange(start, end - start + 1); - currentType = parameterizedType2; - } else { - currentType = qualifiedType; - qualifiedType.index = indexOfEnclosingType; + Type type2 = null; + for (int j = 0; j < arglen; ++j ) { + type2 = convertType(arguments[j]); + parameterizedType.typeArguments().add(type2); } - startingIndex++; - } - if (this.resolveBindings) { - this.recordNodes(currentType, typeReference); + end = type2 != null ? type2.getStartPosition() + type2.getLength() - 1 : end; + end = retrieveClosingAngleBracketPosition(end + 1); + parameterizedType.setSourceRange(start, end - start + 1); + currentType = parameterizedType; + } else { + qualifiedType.index = indexOfEnclosingType; } - type = currentType; - length -= sourceStart; } + type = currentType; } } else if (typeReference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) { - char[][] name = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).getTypeName(); + QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) typeReference; + long[] positions = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).sourcePositions; + org.eclipse.jdt.internal.compiler.ast.Annotation [][] typeAnnotations = typeReference.annotations; + char [][] tokens = qualifiedTypeReference.tokens; + int lenth = tokens.length; + int firstTypeIndex = lenth - 1; + + if (typeAnnotations != null) { + for (int i = 0; i < lenth; ++i) { + if (typeAnnotations[i] != null) { + firstTypeIndex = i; + break; + } + } + } + sourceStart = (int)(positions[0]>>>32); //{ObjectTeams: revert anchored types like in MyTeam.this._OT$base.R => base.R org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).resolvedType; @@ -3752,21 +3900,66 @@ class ASTConverter { if (rtb.hasExplicitAnchor()) { char[][] newName = CharOperation.splitOn('.', rtb.optimalName()); // refuse to use best name which is longer than source name. - if (name.length >= newName.length) - name = newName; + if (tokens.length >= newName.length) + tokens = newName; } } } -// SH} - int nameLength = name.length; - long[] positions = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).sourcePositions; - sourceStart = (int)(positions[0]>>>32); - length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1; - final Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference, typeReference.annotations); - final SimpleType simpleType = new SimpleType(this.ast); - simpleType.setName(qualifiedName); - type = simpleType; - type.setSourceRange(sourceStart, length); +// SH} + Name name = null; + if (firstTypeIndex == 0) { + final SimpleName simpleName = new SimpleName(this.ast); + simpleName.internalSetIdentifier(new String(tokens[0])); + recordPendingNameScopeResolution(simpleName); + int start = (int) (positions[0] >>> 32); + int end = (int) positions[0]; + simpleName.setSourceRange(start, end); + simpleName.index = 1; + name = simpleName; + if (this.resolveBindings) { + recordNodes(simpleName, typeReference); + } + } else { + name = setQualifiedNameNameAndSourceRanges(tokens, positions, firstTypeIndex, typeReference); + } + SimpleType simpleType = new SimpleType(this.ast); + simpleType.setName(name); + int start = (int)(positions[0] >>> 32); + int end = (int)positions[firstTypeIndex]; + simpleType.setSourceRange(start, end - start + 1); + if (typeAnnotations != null && (annotations = typeAnnotations[firstTypeIndex]) != null) { + annotateType(simpleType, annotations); + } + if (this.resolveBindings) { + recordNodes(simpleType, typeReference); + } + Type currentType = simpleType; + + for (int i = firstTypeIndex + 1; i < lenth; ++i) { + SimpleName simpleName = new SimpleName(this.ast); + simpleName.internalSetIdentifier(new String(tokens[i])); + simpleName.index = i + 1; + start = (int) (positions[i] >>> 32); + end = (int) positions[i]; + simpleName.setSourceRange(start, end - start +1); + recordPendingNameScopeResolution(simpleName); + QualifiedType qualifiedType = new QualifiedType(this.ast); + qualifiedType.setQualifier(currentType); + qualifiedType.setName(simpleName); + if (typeAnnotations != null && (annotations = typeAnnotations[i]) != null) { + annotateType(qualifiedType, annotations); + } + if (this.resolveBindings) { + recordNodes(simpleName, typeReference); + recordNodes(qualifiedType, typeReference); + } + start = currentType.getStartPosition(); + end = simpleName.getStartPosition() + simpleName.getLength() - 1; + qualifiedType.setSourceRange(start, end - start + 1); + currentType = qualifiedType; + qualifiedType.index = 1; + } + type = currentType; } else { TypeReference[] typeReferences = ((org.eclipse.jdt.internal.compiler.ast.UnionTypeReference) typeReference).typeReferences; switch(this.ast.apiLevel) { @@ -4538,16 +4731,26 @@ class ASTConverter { } /** - * This method is used to retrieve the position just before the left bracket. - * @return int the dimension found, -1 if none + * This method is used to retrieve the start and end position of a name. + * + * @return int[] a single dimensional array, with two elements, for the start and end positions of the name respectively */ - protected int retrieveEndOfElementTypeNamePosition(int start, int end) { + protected int[] retrieveEndOfElementTypeNamePosition(int start, int end) { this.scanner.resetTo(start, end); + boolean isAnnotation = false; try { int token; while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { switch(token) { + case TerminalTokens.TokenNameAT: + isAnnotation = true; + break; case TerminalTokens.TokenNameIdentifier: + if (isAnnotation) { + isAnnotation = false; + break; + } + //$FALL-THROUGH$ case TerminalTokens.TokenNamebyte: case TerminalTokens.TokenNamechar: case TerminalTokens.TokenNamedouble: @@ -4556,13 +4759,13 @@ class ASTConverter { case TerminalTokens.TokenNamelong: case TerminalTokens.TokenNameshort: case TerminalTokens.TokenNameboolean: - return this.scanner.currentPosition - 1; + return new int[]{this.scanner.startPosition, this.scanner.currentPosition - 1}; } } } catch(InvalidInputException e) { // ignore } - return -1; + return new int[]{-1, -1}; } /** @@ -4573,10 +4776,18 @@ class ASTConverter { this.scanner.resetTo(start, end); try { int token; + int count = 0; while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { switch(token) { case TerminalTokens.TokenNameRPAREN: - return this.scanner.currentPosition; + count--; + if (count <= 0) return this.scanner.currentPosition; + break; + case TerminalTokens.TokenNameLPAREN: + count++; + //$FALL-THROUGH$ + default: + break; } } } catch(InvalidInputException e) { @@ -4598,14 +4809,26 @@ class ASTConverter { int dimensions = 0; try { int token; + boolean isAnnotation = false; while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { switch(token) { case TerminalTokens.TokenNameLBRACKET: case TerminalTokens.TokenNameCOMMENT_BLOCK: case TerminalTokens.TokenNameCOMMENT_JAVADOC: case TerminalTokens.TokenNameCOMMENT_LINE: + isAnnotation = false; + break; + case TerminalTokens.TokenNameAT: + isAnnotation = true; + break; + case TerminalTokens.TokenNameIdentifier: + if (!isAnnotation) { + return dimensions; + } + isAnnotation = false; break; case TerminalTokens.TokenNameRBRACKET://166 + isAnnotation = false; dimensions++; break; default: @@ -4618,6 +4841,31 @@ class ASTConverter { return dimensions; } + protected void retrieveDimensionAndSetPositions(int start, int end, ExtraDimension dim) { + this.scanner.resetTo(start, end); + int token; + boolean startSet = false; + try { + while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { + switch(token) { + case TerminalTokens.TokenNameWHITESPACE: + break; + case TerminalTokens.TokenNameRBRACKET: + int endDim = this.scanner.currentPosition - 1; + dim.setSourceRange(start, endDim - start + 1); + return; + default: + if (!startSet) { + start = this.scanner.startPosition; + startSet = true; + } + break; + } + } + } catch(InvalidInputException e) { + // ignore + } + } protected void retrieveIdentifierAndSetPositions(int start, int end, Name name) { this.scanner.resetTo(start, end); int token; @@ -5354,12 +5602,7 @@ class ASTConverter { } protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, org.eclipse.jdt.internal.compiler.ast.ASTNode node) { - return setQualifiedNameNameAndSourceRanges(typeName, positions, node, null); - } - - protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, org.eclipse.jdt.internal.compiler.ast.ASTNode node, org.eclipse.jdt.internal.compiler.ast.Annotation[][] annotations) { - org.eclipse.jdt.internal.compiler.ast.Annotation[] typeAnnotations; - int length = typeName.length; + int length = typeName.length; final SimpleName firstToken = new SimpleName(this.ast); firstToken.internalSetIdentifier(new String(typeName[0])); firstToken.index = 1; @@ -5367,9 +5610,6 @@ class ASTConverter { int start = start0; int end = (int)(positions[0] & 0xFFFFFFFF); firstToken.setSourceRange(start, end - start + 1); - if (annotations != null && (typeAnnotations = annotations[0]) != null) { - annotateName(firstToken, typeAnnotations); - } final SimpleName secondToken = new SimpleName(this.ast); secondToken.internalSetIdentifier(new String(typeName[1])); secondToken.index = 2; @@ -5379,9 +5619,6 @@ class ASTConverter { QualifiedName qualifiedName = new QualifiedName(this.ast); qualifiedName.setQualifier(firstToken); qualifiedName.setName(secondToken); - if (annotations != null && (typeAnnotations = annotations[1]) != null) { - annotateName(qualifiedName, typeAnnotations); - } if (this.resolveBindings) { recordNodes(qualifiedName, node); recordPendingNameScopeResolution(qualifiedName); @@ -5406,9 +5643,6 @@ class ASTConverter { qualifiedName = qualifiedName2; qualifiedName.index = newPart.index; qualifiedName.setSourceRange(start0, end - start0 + 1); - if (annotations != null && (typeAnnotations = annotations[i]) != null) { - annotateName(qualifiedName, typeAnnotations); - } if (this.resolveBindings) { recordNodes(qualifiedName, node); recordNodes(newPart, node); @@ -5425,7 +5659,6 @@ class ASTConverter { } protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, int endingIndex, org.eclipse.jdt.internal.compiler.ast.TypeReference node) { - org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations; int length = endingIndex + 1; final SimpleName firstToken = new SimpleName(this.ast); firstToken.internalSetIdentifier(new String(typeName[0])); @@ -5434,9 +5667,6 @@ class ASTConverter { int start = start0; int end = (int) positions[0]; firstToken.setSourceRange(start, end - start + 1); - if (node.annotations != null && (annotations = node.annotations[0]) != null) { - annotateName(firstToken, annotations); - } final SimpleName secondToken = new SimpleName(this.ast); secondToken.internalSetIdentifier(new String(typeName[1])); secondToken.index = 2; @@ -5446,9 +5676,6 @@ class ASTConverter { QualifiedName qualifiedName = new QualifiedName(this.ast); qualifiedName.setQualifier(firstToken); qualifiedName.setName(secondToken); - if (node.annotations != null && (annotations = node.annotations[1]) != null) { - annotateName(qualifiedName, annotations); - } if (this.resolveBindings) { recordNodes(qualifiedName, node); recordPendingNameScopeResolution(qualifiedName); @@ -5473,9 +5700,6 @@ class ASTConverter { qualifiedName = qualifiedName2; qualifiedName.index = newPart.index; qualifiedName.setSourceRange(start0, end - start0 + 1); - if (node.annotations != null && (annotations = node.annotations[i]) != null) { - annotateName(qualifiedName, annotations); - } if (this.resolveBindings) { recordNodes(qualifiedName, node); recordNodes(newPart, node); @@ -5592,7 +5816,7 @@ class ASTConverter { break; default : methodDeclaration.setReturnType2(subarrayType); - break; + break; } this.ast.getBindingResolver().updateKey(type, subarrayType); } @@ -6329,8 +6553,12 @@ public BaseConstructorInvocation convert( String realName = tokens[tokens.length - 1]; SimpleName fieldName = this.ast.newSimpleName(realName); int start = fieldAccessSpec.sourceStart; - int end = retrieveEndOfElementTypeNamePosition(start, + int[] positions = retrieveEndOfElementTypeNamePosition(start, fieldAccessSpec.sourceEnd); + if (positions[0] != -1) + start = positions[0]; + int end = positions[1]; + fieldName.setSourceRange(start, end - start + 1); result.setName(fieldName); @@ -6359,7 +6587,10 @@ public BaseConstructorInvocation convert( SimpleName methodName = this.ast.newSimpleName(new String(methodSpec.selector)); int start = methodSpec.sourceStart; - int end = retrieveEndOfElementTypeNamePosition(start, methodSpec.sourceEnd); + int[] positions = retrieveEndOfElementTypeNamePosition(start, methodSpec.sourceEnd); + if (positions[0] != -1) + start = positions[0]; + int end = positions[1]; methodName.setSourceRange(start, end - start + 1); result.setName(methodName); diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java index ec59d5aed..10a801d94 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -357,6 +357,28 @@ public class ASTMatcher { * @return <code>true</code> if the subtree matches, or * <code>false</code> if they do not match or the other object has a * different node type or is <code>null</code> + * @since 3.9 + */ + public boolean match(ExtraDimension node, Object other) { + if (!(other instanceof ExtraDimension)) + return false; + ExtraDimension o = (ExtraDimension) other; + return safeSubtreeListMatch(node.annotations(), o.annotations()); + } + + /** + * Returns whether the given node and the other object match. + * <p> + * The default implementation provided by this class tests whether the + * other object is a node of the same type with structurally isomorphic + * child subtrees. Subclasses may override this method as needed. + * </p> + * + * @param node the node + * @param other the other object, or <code>null</code> + * @return <code>true</code> if the subtree matches, or + * <code>false</code> if they do not match or the other object has a + * different node type or is <code>null</code> */ public boolean match(AssertStatement node, Object other) { if (!(other instanceof AssertStatement)) { @@ -1389,13 +1411,24 @@ public class ASTMatcher { return false; } } + if (level >= AST.JLS8) { + if (!safeSubtreeMatch(node.getReceiverType(), o.getReceiverType())) { + return false; + } + if (!safeSubtreeMatch(node.getReceiverQualifier(), o.getReceiverQualifier())) { + return false; + } + } return ((node.isConstructor() == o.isConstructor()) && safeSubtreeMatch(node.getJavadoc(), o.getJavadoc()) && safeSubtreeMatch(node.getName(), o.getName()) // n.b. compare return type even for constructors && safeSubtreeListMatch(node.parameters(), o.parameters()) - && node.getExtraDimensions() == o.getExtraDimensions() - && safeSubtreeListMatch(node.thrownExceptions(), o.thrownExceptions()) + && ((node.getAST().apiLevel < AST.JLS8) ? + (node.getExtraDimensions() == o.getExtraDimensions() + && safeSubtreeListMatch(node.thrownExceptions(), o.thrownExceptions())) : + (safeSubtreeListMatch(node.extraDimensionInfos(), o.extraDimensionInfos()) + && safeSubtreeListMatch(node.thrownExceptionTypes(), o.thrownExceptionTypes()))) //{ObjectTeams: && safeSubtreeMatch(node.getGuardPredicate(), o.getGuardPredicate()) // SH} @@ -1695,17 +1728,9 @@ public class ASTMatcher { return false; } QualifiedName o = (QualifiedName) other; - switch(node.getAST().apiLevel) { - case AST.JLS2_INTERNAL : - case AST.JLS3_INTERNAL : - case AST.JLS4: - return safeSubtreeMatch(node.getQualifier(), o.getQualifier()) - && safeSubtreeMatch(node.getName(), o.getName()); - default: - return safeSubtreeMatch(node.getQualifier(), o.getQualifier()) - && safeSubtreeMatch(node.getName(), o.getName()) && - safeSubtreeListMatch(node.annotations(), o.annotations()); - } + + return safeSubtreeMatch(node.getQualifier(), o.getQualifier()) + && safeSubtreeMatch(node.getName(), o.getName()); } /** @@ -1785,15 +1810,7 @@ public class ASTMatcher { return false; } SimpleName o = (SimpleName) other; - switch(node.getAST().apiLevel) { - case AST.JLS2_INTERNAL : - case AST.JLS3_INTERNAL : - case AST.JLS4: - return node.getIdentifier().equals(o.getIdentifier()); - default: - return (node.getIdentifier().equals(o.getIdentifier())) && - safeSubtreeListMatch(node.annotations(), o.annotations()); - } + return node.getIdentifier().equals(o.getIdentifier()); } /** @@ -1890,8 +1907,11 @@ public class ASTMatcher { return safeSubtreeMatch(node.getType(), o.getType()) && safeSubtreeMatch(node.getName(), o.getName()) - && node.getExtraDimensions() == o.getExtraDimensions() - && safeSubtreeMatch(node.getInitializer(), o.getInitializer()); + && ((node.getAST().apiLevel < AST.JLS8) ? + node.getExtraDimensions() == o.getExtraDimensions() : + safeSubtreeListMatch(node.extraDimensionInfos(), o.extraDimensionInfos())) + && safeSubtreeMatch(node.getInitializer(), o.getInitializer()) + && (level >= AST.JLS8 && node.isVarargs()) ? safeSubtreeListMatch(node.varargsAnnotations(), o.varargsAnnotations()) : true; } /** @@ -2395,7 +2415,9 @@ public class ASTMatcher { } VariableDeclarationFragment o = (VariableDeclarationFragment) other; return safeSubtreeMatch(node.getName(), o.getName()) - && node.getExtraDimensions() == o.getExtraDimensions() + && ((node.getAST().apiLevel < AST.JLS8) ? + node.getExtraDimensions() == o.getExtraDimensions() : + safeSubtreeListMatch(node.extraDimensionInfos(), o.extraDimensionInfos())) && safeSubtreeMatch(node.getInitializer(), o.getInitializer()); } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java index 54a136e4e..c7bcf321c 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -774,6 +774,15 @@ public abstract class ASTNode { */ public static final int UNION_TYPE = 84; + /** + * Node type constant indicating a node of type + * <code>ExtraDimension</code>. + * + * @see ExtraDimension + * @since 3.9 + */ + public static final int EXTRA_DIMENSION = 85; + //{ObjectTeams: required OT specific node type constants added /** @@ -781,93 +790,93 @@ public abstract class ASTNode { * <code>MethodSpec</code>. * @see MethodSpec */ - public static final int METHOD_SPEC = 85; + public static final int METHOD_SPEC = 86; /** * Node type constant indicating a node of type * <code>CallinMappingDeclaration</code>. * @see CallinMappingDeclaration */ - public static final int CALLIN_MAPPING_DECLARATION = 86; + public static final int CALLIN_MAPPING_DECLARATION = 87; /** * Node type constant indicating a node of type * <code>CalloutMappingDeclaration</code>. * @see CalloutMappingDeclaration */ - public static final int CALLOUT_MAPPING_DECLARATION = 87; + public static final int CALLOUT_MAPPING_DECLARATION = 88; /** * Node type constant indicating a node of type * <code>LiftingType</code>. * @see LiftingType */ - public static final int LIFTING_TYPE = 88; + public static final int LIFTING_TYPE = 89; /** * Node type constant indicating a node of type * <code>WithinStatement</code>. * @see WithinStatement */ - public static final int WITHIN_STATEMENT = 89; + public static final int WITHIN_STATEMENT = 90; /** * Node type constant indicating a node of type * <code>BaseConstructorMessageSend</code>. * @see BaseConstructorInvocation */ - public static final int BASE_CONSTRUCTOR_INVOCATION = 90; + public static final int BASE_CONSTRUCTOR_INVOCATION = 91; /** * Node type constant indicating a node of type * <code>ParameterMapping</code>. * @see ParameterMapping */ - public static final int PARAMETER_MAPPING = 91; + public static final int PARAMETER_MAPPING = 92; /** * Node type constant indicating a node of type * <code>BaseCallMessageSend</code>. * @see BaseCallMessageSend */ - public static final int BASE_CALL_MESSAGE_SEND = 92; + public static final int BASE_CALL_MESSAGE_SEND = 93; /** * Node type constant indicating a node of type * <code>FieldAccessSpec</code>. * @see FieldAccessSpec */ - public static final int FIELD_ACCESS_SPEC = 93; + public static final int FIELD_ACCESS_SPEC = 94; /** * Node type constant indicating a node of type * <code>RoleTypeDelaration</code>. * @see RoleTypeDeclaration */ - public static final int ROLE_TYPE_DECLARATION = 94; + public static final int ROLE_TYPE_DECLARATION = 95; /** * Node type constant indicating a node of type * <code>TSuperMessageSend</code>. * @see TSuperMessageSend */ - public static final int TSUPER_MESSAGE_SEND = 95; + public static final int TSUPER_MESSAGE_SEND = 96; /** * Node type constant indicating a node of type * <code>TSuperCallMessageSend</code>. * @see TSuperMessageSend */ - public static final int TSUPER_CONSTRUCTOR_INVOCATION = 96; + public static final int TSUPER_CONSTRUCTOR_INVOCATION = 97; - public static final int TYPE_ANCHOR = 97; + public static final int TYPE_ANCHOR = 98; - public static final int PRECEDENCE_DECLARATION = 98; + public static final int PRECEDENCE_DECLARATION = 99; - public static final int GUARD_PREDICATE_DECLARATION = 99; + public static final int GUARD_PREDICATE_DECLARATION = 100; /** @since 1.3.1 */ - public static final int METHOD_BINDING_OPERATOR = 100; + public static final int METHOD_BINDING_OPERATOR = 101; //gbr} /** @@ -1050,6 +1059,8 @@ public abstract class ASTNode { return WhileStatement.class; case WILDCARD_TYPE : return WildcardType.class; + case EXTRA_DIMENSION: + return ExtraDimension.class; //{ObjectTeams: entries for OT specific node types added case METHOD_SPEC : return MethodSpec.class; @@ -1974,6 +1985,22 @@ public abstract class ASTNode { } /** + * Checks that this AST operation is only used when + * building JLS2, JLS3 or JLS4 level ASTs. + * <p> + * Use this method to prevent access to deprecated properties (deprecated in JLS8). + * </p> + * + * @exception UnsupportedOperationException + * @since 3.9 + */ + final void supportedOnlyIn2_3_4() { + if (this.ast.apiLevel >= AST.JLS8) { + throw new UnsupportedOperationException("Operation only supported in JLS2, JLS3 and JLS4 ASTs"); //$NON-NLS-1$ + } + } + + /** * Sets or clears this node's parent node and location. * <p> * Note that this method is package-private. The pointer from a node diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java index 7633b0449..835a9edeb 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 * Fraunhofer FIRST - extended API and implementation @@ -201,6 +205,22 @@ public abstract class ASTVisitor { return true; } + /** + * Visits the given type-specific AST node. + * <p> + * The default implementation does nothing and return true. + * Subclasses may reimplement. + * </p> + * + * @param node the node to visit + * @return <code>true</code> if the children of this node should be + * visited, and <code>false</code> if the children of this node should + * be skipped + * @since 3.9 + */ + public boolean visit(ExtraDimension node) { + return true; + } /** * Visits the given type-specific AST node. @@ -1863,6 +1883,19 @@ public abstract class ASTVisitor { * </p> * * @param node the node to visit + * @since 3.9 + */ + public void endVisit(ExtraDimension node) { + // do nothing by default + } + + /** + * End of visit the given type-specific AST node. + * <p> + * The default implementation does nothing. Subclasses may reimplement. + * </p> + * + * @param node the node to visit * @since 3.1 */ public void endVisit(AnnotationTypeMemberDeclaration node) { diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotatableType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotatableType.java new file mode 100644 index 000000000..3f3cb2d8d --- /dev/null +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotatableType.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2000, 2013 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 + *******************************************************************************/ +package org.eclipse.jdt.core.dom; + +import java.util.List; + +/** + * Type node for an annotatable type. + * <p> + * Introduced in JLS8, type references that can be annotated are represented by + * AnnotatableType. For the list of types extending AnnotatableType, see {@link Type}</p> + * + * @since 3.9 + */ +public abstract class AnnotatableType extends Type { + + /** + * Creates a new unparented node for an annotatable type owned by the given AST. + * <p> + * N.B. This constructor is package-private. + * </p> + * + * @param ast the AST that is to own this node + */ + AnnotatableType(AST ast) { + super(ast); + } + + ASTNode.NodeList annotations = null; + + /** + * Returns the live ordered list of annotations for this Type node. + * + * @return the live list of annotations (element type: {@link Annotation}) + * @exception UnsupportedOperationException if this operation is used + * in a JLS2, JLS3 or JLS4 AST + * @since 3.9 + */ + public List annotations() { + if (this.annotations == null) { + unsupportedIn2_3_4(); + } + return this.annotations; + } +} diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java index 3e87e6fa2..a01d95214 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -37,7 +37,7 @@ import java.util.List; * @since 2.0 * @noinstantiate This class is not intended to be instantiated by clients. */ -public class ArrayType extends Type { +public class ArrayType extends AnnotatableType { /** * The "componentType" structural property of this node type (child type: {@link Type}). @@ -172,7 +172,6 @@ public class ArrayType extends Type { result.setSourceRange(getStartPosition(), getLength()); result.setComponentType((Type) getComponentType().clone(target)); if (this.ast.apiLevel >= AST.JLS8) { - result.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY); result.annotations.addAll( ASTNode.copySubtrees(target, annotations())); } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java index 84fb0ca66..91c083656 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java @@ -1,11 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2013 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: DefaultBindingResolver.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 * Stephan Herrmann - Contribution for Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding @@ -42,6 +45,7 @@ import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.Receiver; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.ThisReference; @@ -320,11 +324,14 @@ class DefaultBindingResolver extends BindingResolver { this.bindingTables.compilerBindingsToASTBindings.put(packageBinding, binding); return binding; } - private int getTypeArguments(ParameterizedQualifiedTypeReference typeReference) { + private int getTypeCount(ParameterizedQualifiedTypeReference typeReference) { TypeReference[][] typeArguments = typeReference.typeArguments; int value = 0; - for (int i = 0, max = typeArguments.length; i < max; i++) { - if ((typeArguments[i] != null) || (value != 0)) { + org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations = typeReference.annotations; + int length = typeReference.tokens.length; + for (int i = 0; i < length; ++i) { + if (value != 0 || (typeArguments != null && typeArguments[i] != null) || + (typeAnnotations != null && typeAnnotations[i] != null )) { value++; } } @@ -1727,6 +1734,9 @@ class DefaultBindingResolver extends BindingResolver { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(type); org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding = null; if (node != null) { + if (node instanceof Receiver) { + node = ((Receiver) node).type; + } if (node instanceof ParameterizedQualifiedTypeReference) { ParameterizedQualifiedTypeReference typeReference = (ParameterizedQualifiedTypeReference) node; org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = typeReference.resolvedType; @@ -1750,7 +1760,7 @@ class DefaultBindingResolver extends BindingResolver { } else { index = 1; } - final int numberOfTypeArgumentsNotNull = getTypeArguments(typeReference); + final int numberOfTypeArgumentsNotNull = getTypeCount(typeReference); if (index != numberOfTypeArgumentsNotNull) { int i = numberOfTypeArgumentsNotNull; while (i != index) { diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExtraDimension.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExtraDimension.java new file mode 100644 index 000000000..e67dcafae --- /dev/null +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExtraDimension.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + *******************************************************************************/ +package org.eclipse.jdt.core.dom; + +import java.util.ArrayList; +import java.util.List; + +/** + * The extra dimension node. The extra dimensions, represented as <b>[]</b>, are allowed to have + * type annotations. This node type is supported only in JLS8 or later. + * <p> + * The extra dimension node is used to represent extra dimensions in the following nodes: + * <pre> + * SingleVariableDeclaration + * VariableDeclarationFragment + * MethodDeclaration + * </pre> + * For JLS8: + * <pre> + * ExtraDimension: + * { Annotations } <b>[]</b> + * </pre> + *</p> + * @see AST#newExtraDimension() + * @since 3.9 + */ +public class ExtraDimension extends ASTNode { + + + /** + * The "annotations" structural property of this node type (child type: {@link Annotation}). + * @since 3.9 + */ + public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY = + new ChildListPropertyDescriptor(ExtraDimension.class, "annotations", Annotation.class, NO_CYCLE_RISK); //$NON-NLS-1$ + + /** + * A list of property descriptors (element type: + * {@link StructuralPropertyDescriptor}), + * or null if uninitialized. + * @since 3.9 + */ + private static final List PROPERTY_DESCRIPTORS_8_0; + + static { + List propertyList = new ArrayList(3); + createPropertyList(ExtraDimension.class, propertyList); + addProperty(ANNOTATIONS_PROPERTY, propertyList); + PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList); + } + + /** + * Returns a list of structural property descriptors for this node type. + * Clients must not modify the result. + * + * @param apiLevel the API level; one of the + * <code>AST.JLS*</code> constants + * @return a list of property descriptors (element type: + * {@link StructuralPropertyDescriptor}) + * @since 3.9 + */ + public static List propertyDescriptors(int apiLevel) { + return PROPERTY_DESCRIPTORS_8_0; + } + + /** + * Create a new instance of ExtraDimension node (Supported only in level + * JLS8 or above). + * + * @param ast + * @exception UnsupportedOperationException if this operation is used + * in a JLS2, JLS3 or JLS4 AST + * @since 3.9 + */ + ExtraDimension(AST ast) { + super(ast); + unsupportedIn2_3_4(); + this.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY); + } + + /** + * The list of annotations for this dimension (element type: + * {@link Annotation}). + */ + ASTNode.NodeList annotations = null; + + /** + * Returns the live ordered list of annotations for this dimension. + * + * @return the live list of annotations (element type: {@link Annotation}) + * @since 3.9 + */ + public List annotations() { + return this.annotations; + } + + List internalStructuralPropertiesForType(int apiLevel) { + return propertyDescriptors(apiLevel); + } + + /* (omit javadoc for this method) + * Method declared on ASTNode. + */ + final List internalGetChildListProperty(ChildListPropertyDescriptor property) { + if (property == ANNOTATIONS_PROPERTY) { + return annotations(); + } + // allow default implementation to flag the error + return super.internalGetChildListProperty(property); + } + + int getNodeType0() { + return EXTRA_DIMENSION; + } + + boolean subtreeMatch0(ASTMatcher matcher, Object other) { + return matcher.match(this, other); + } + + ASTNode clone0(AST target) { + ExtraDimension result = new ExtraDimension(target); + result.annotations.addAll( + ASTNode.copySubtrees(target, annotations())); + return result; + } + + void accept0(ASTVisitor visitor) { + boolean visitChildren = visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor, this.annotations); + } + visitor.endVisit(this); + } + + int treeSize() { + int size = memSize() + + this.annotations.listSize(); + return size; + } + + int memSize() { + return BASE_NODE_SIZE + 4; + } +} diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java index 1548d203c..bd65469f3 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java @@ -5,6 +5,10 @@ * 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 * Technical University Berlin - extended API and implementation @@ -50,6 +54,24 @@ import java.util.List; * { <b>,</b> FormalParameter } ] <b>)</b> * [<b>throws</b> TypeName { <b>,</b> TypeName } ] Block * </pre> + * For JLS8 optional receiver parameter is added and extra dimensions are allowed to have + * type annotations. The annotatable extra dimensions are represented by {@link ExtraDimension}. + * <pre> + * MethodDeclaration: + * [ Javadoc ] { ExtendedModifier } + * [ <b><</b> TypeParameter { <b>,</b> TypeParameter } <b>></b> ] + * ( Type | <b>void</b> ) Identifier <b>(</b> + * [ ReceiverParameter ] + * [ <b>, </b> FormalParameter { <b>,</b> FormalParameter } ] <b>)</b> { ExtraDimension } + * [ <b>throws</b> TypeName { <b>,</b> TypeName } ] ( Block | <b>;</b> ) + * ConstructorDeclaration: + * [ Javadoc ] { ExtendedModifier } + * [ <b><</b> TypeParameter { <b>,</b> TypeParameter } <b>></b> ] + * Identifier <b>(</b> + * [ ReceiverParameter ] + * [ <b>, </b> FormalParameter { <b>,</b> FormalParameter } ] <b>)</b> + * [<b>throws</b> TypeName { <b>,</b> TypeName } ] Block + * </pre> * <p> * When a Javadoc comment is present, the source * range begins with the first character of the "/**" comment delimiter. @@ -123,10 +145,19 @@ public class MethodDeclaration extends BodyDeclaration /** * The "extraDimensions" structural property of this node type (type: {@link Integer}). + * * @since 3.0 + * @deprecated in JLS8, use {@link MethodDeclaration#EXTRA_DIMENSION_INFOS_PROPERTY} instead. */ public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY = new SimplePropertyDescriptor(MethodDeclaration.class, "extraDimensions", int.class, MANDATORY); //$NON-NLS-1$ + + /** + * The "extraDimensionInfos" structural property of this node type (child type: {@link ExtraDimension}) (added in JLS8 API). + * @since 3.9 + */ + public static final ChildListPropertyDescriptor EXTRA_DIMENSION_INFOS_PROPERTY = + new ChildListPropertyDescriptor(MethodDeclaration.class, "extraDimensionInfos", ExtraDimension.class, NO_CYCLE_RISK); //$NON-NLS-1$ /** * The "typeParameters" structural property of this node type (element type: {@link TypeParameter}) (added in JLS3 API). @@ -143,12 +174,35 @@ public class MethodDeclaration extends BodyDeclaration new ChildListPropertyDescriptor(MethodDeclaration.class, "parameters", SingleVariableDeclaration.class, CYCLE_RISK); //$NON-NLS-1$ /** - * The "thrownExceptions" structural property of this node type (element type: {@link Name}). + * The "receiverType" structural property of this node type (element type: + * {@link AnnotatableType}) (added in JLS8 API). + * @since 3.9 + */ + public static final ChildPropertyDescriptor RECEIVER_TYPE_PROPERTY = + new ChildPropertyDescriptor(MethodDeclaration.class, "receiverType", AnnotatableType.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$ + + /** + * The "receiverQualifier" structural property of this node type (element type: + * {@link SimpleName}) (added in JLS8 API). + * @since 3.9 + */ + public static final ChildPropertyDescriptor RECEIVER_QUALIFIER_PROPERTY = + new ChildPropertyDescriptor(MethodDeclaration.class, "receiverQualifier", SimpleName.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$ + + /** + * The "thrownExceptions" structural property of this node type (element type: {@link Name}) (Available in JLS2, JLS3, and JLS4 Only). * @since 3.0 */ public static final ChildListPropertyDescriptor THROWN_EXCEPTIONS_PROPERTY = new ChildListPropertyDescriptor(MethodDeclaration.class, "thrownExceptions", Name.class, NO_CYCLE_RISK); //$NON-NLS-1$ + /** + * The "thrownExceptionTypes" structural property of this node type (element type: {@link Type}) (added in JLS8 API). + * @since 3.9 + */ + public static final ChildListPropertyDescriptor THROWN_EXCEPTION_TYPES_PROPERTY = + new ChildListPropertyDescriptor(MethodDeclaration.class, "thrownExceptionTypes", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$ + //{ObjectTeams: new element: /** * The "guardPredicate" structural property of this node type. @@ -181,6 +235,14 @@ public class MethodDeclaration extends BodyDeclaration */ private static final List PROPERTY_DESCRIPTORS_3_0; + /** + * A list of property descriptors (element type: + * {@link StructuralPropertyDescriptor}), + * or null if uninitialized. + * @since 3.9 + */ + private static final List PROPERTY_DESCRIPTORS_8_0; + static { List propertyList = new ArrayList(10); createPropertyList(MethodDeclaration.class, propertyList); @@ -198,7 +260,7 @@ public class MethodDeclaration extends BodyDeclaration addProperty(BODY_PROPERTY, propertyList); PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList); - propertyList = new ArrayList(12); + propertyList = new ArrayList(11); createPropertyList(MethodDeclaration.class, propertyList); addProperty(JAVADOC_PROPERTY, propertyList); addProperty(MODIFIERS2_PROPERTY, propertyList); @@ -214,6 +276,25 @@ public class MethodDeclaration extends BodyDeclaration // SH} addProperty(BODY_PROPERTY, propertyList); PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList); + + propertyList = new ArrayList(13); + createPropertyList(MethodDeclaration.class, propertyList); + addProperty(JAVADOC_PROPERTY, propertyList); + addProperty(MODIFIERS2_PROPERTY, propertyList); + addProperty(CONSTRUCTOR_PROPERTY, propertyList); + addProperty(TYPE_PARAMETERS_PROPERTY, propertyList); + addProperty(RETURN_TYPE2_PROPERTY, propertyList); + addProperty(NAME_PROPERTY, propertyList); + addProperty(RECEIVER_TYPE_PROPERTY, propertyList); + addProperty(RECEIVER_QUALIFIER_PROPERTY, propertyList); + addProperty(PARAMETERS_PROPERTY, propertyList); + addProperty(EXTRA_DIMENSION_INFOS_PROPERTY, propertyList); + addProperty(THROWN_EXCEPTION_TYPES_PROPERTY, propertyList); +//{ObjectTeams: + addProperty(GUARD_PROPERTY, propertyList); +// SH} + addProperty(BODY_PROPERTY, propertyList); + PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList); } /** @@ -228,8 +309,10 @@ public class MethodDeclaration extends BodyDeclaration public static List propertyDescriptors(int apiLevel) { if (apiLevel == AST.JLS2_INTERNAL) { return PROPERTY_DESCRIPTORS_2_0; - } else { + } else if (apiLevel < AST.JLS8) { return PROPERTY_DESCRIPTORS_3_0; + } else { + return PROPERTY_DESCRIPTORS_8_0; } } @@ -246,6 +329,16 @@ public class MethodDeclaration extends BodyDeclaration private SimpleName methodName = null; /** + * The explicit receiver type. + */ + private AnnotatableType receiverType = null; + + /** + * Qualifying name if any of the explicit </code>this</code> parameter. + */ + private SimpleName receiverQualifier = null; + + /** * The parameter declarations * (element type: {@link SingleVariableDeclaration}). * Defaults to an empty list. @@ -284,11 +377,23 @@ public class MethodDeclaration extends BodyDeclaration private int extraArrayDimensions = 0; /** + * The extra dimensions this node has with optional annotations. + * + * @since 3.9 + */ + protected ASTNode.NodeList extraDimensionInfos = null; + + /** * The list of thrown exception names (element type: {@link Name}). - * Defaults to an empty list. + * Defaults to an empty list for api levels below JLS8. */ - private ASTNode.NodeList thrownExceptions = - new ASTNode.NodeList(THROWN_EXCEPTIONS_PROPERTY); + private ASTNode.NodeList thrownExceptions = null; + + /** + * The list of thrown exception Types (element type: {@link Type}). + * Defaults to an empty list at JLS8 and above. + */ + private ASTNode.NodeList thrownExceptionTypes = null; //{ObjectTeams: new element: GuardPredicateDeclaration optionalGuardPredicate = null; @@ -319,6 +424,12 @@ public class MethodDeclaration extends BodyDeclaration if (ast.apiLevel >= AST.JLS3_INTERNAL) { this.typeParameters = new ASTNode.NodeList(TYPE_PARAMETERS_PROPERTY); } + if (ast.apiLevel < AST.JLS8) { + this.thrownExceptions = new ASTNode.NodeList(THROWN_EXCEPTIONS_PROPERTY); + } else { + this.extraDimensionInfos = new ASTNode.NodeList(EXTRA_DIMENSION_INFOS_PROPERTY); + this.thrownExceptionTypes = new ASTNode.NodeList(THROWN_EXCEPTION_TYPES_PROPERTY); + } } /* (omit javadoc for this method) @@ -405,6 +516,20 @@ public class MethodDeclaration extends BodyDeclaration return null; } } + if (property == RECEIVER_TYPE_PROPERTY) { + if (get) { + return this.receiverType; + } else { + setReceiverType((AnnotatableType) child); + } + } + if (property == RECEIVER_QUALIFIER_PROPERTY) { + if (get) { + return this.receiverQualifier; + } else { + setReceiverQualifier((SimpleName) child); + } + } //{ObjectTeams: if (property == GUARD_PROPERTY) { if (get) { @@ -443,6 +568,12 @@ public class MethodDeclaration extends BodyDeclaration if (property == THROWN_EXCEPTIONS_PROPERTY) { return thrownExceptions(); } + if (property == THROWN_EXCEPTION_TYPES_PROPERTY) { + return thrownExceptionTypes(); + } + if (property == EXTRA_DIMENSION_INFOS_PROPERTY) { + return extraDimensionInfos(); + } // allow default implementation to flag the error return super.internalGetChildListProperty(property); } @@ -496,12 +627,25 @@ public class MethodDeclaration extends BodyDeclaration (Type) ASTNode.copySubtree(target, getReturnType2())); } result.setConstructor(isConstructor()); + if (this.ast.apiLevel >= AST.JLS8) { + result.setReceiverType((AnnotatableType) ASTNode.copySubtree(target, this.receiverType)); + result.setReceiverQualifier((SimpleName) ASTNode.copySubtree(target, this.receiverQualifier)); + result.extraDimensionInfos.addAll( + ASTNode.copySubtrees(target, this.extraDimensionInfos)); + } else { result.setExtraDimensions(getExtraDimensions()); + } result.setName((SimpleName) getName().clone(target)); result.parameters().addAll( ASTNode.copySubtrees(target, parameters())); - result.thrownExceptions().addAll( + if (this.ast.apiLevel() < AST.JLS8) { + result.thrownExceptions().addAll( ASTNode.copySubtrees(target, thrownExceptions())); + } else { + result.thrownExceptionTypes().addAll( + ASTNode.copySubtrees(target, thrownExceptionTypes())); + + } //{ObjectTeams: result.setGuardPredicate((GuardPredicateDeclaration)ASTNode.copySubtree(target, getGuardPredicate())); // SH} @@ -538,8 +682,17 @@ public class MethodDeclaration extends BodyDeclaration } // n.b. visit return type even for constructors acceptChild(visitor, getName()); + if (this.ast.apiLevel >= AST.JLS8) { + acceptChild(visitor, this.receiverType); + acceptChild(visitor, this.receiverQualifier); + } acceptChildren(visitor, this.parameters); - acceptChildren(visitor, this.thrownExceptions); + if (this.ast.apiLevel() < AST.JLS8) { + acceptChildren(visitor, this.thrownExceptions); + } else { + acceptChildren(visitor, this.extraDimensionInfos); + acceptChildren(visitor, this.thrownExceptionTypes); + } acceptChild(visitor, getBody()); } visitor.endVisit(this); @@ -629,6 +782,68 @@ public class MethodDeclaration extends BodyDeclaration } /** + * Returns the receiver type explicitly declared in the method or constructor + * declaration (JLS8 API only). + * + * If the receiver is not explicitly declared in the method or constructor + * declaration, <code>null</code> is returned. + * + * @return the receiver type or <code>null</code> if receiver is not declared explicitly + * @exception UnsupportedOperationException if this operation is used below JLS8 + * @since 3.9 + */ + public AnnotatableType getReceiverType() { + unsupportedIn2_3_4(); + return this.receiverType; + } + + /** + * Sets the given type as the type of explicit receiver parameter. (JLS8 API only). + * + * @param receiverType type of explicit receiver parameter to be added to the method declaration + * @exception UnsupportedOperationException if this operation is used below JLS8 + * @since 3.9 + + */ + public void setReceiverType(AnnotatableType receiverType) { + unsupportedIn2_3_4(); + ASTNode oldChild = this.receiverType; + preReplaceChild(oldChild, receiverType, RECEIVER_TYPE_PROPERTY); + this.receiverType = receiverType; + postReplaceChild(oldChild, receiverType, RECEIVER_TYPE_PROPERTY); + } + + /** + * Returns the qualifying name, if any, for the explicit receiver or null if not used. This method + * always returns <code>null</code> for a non-constructor. + * This API is supported in JLS8 only. + * + * @returns the qualifying name or <code>null</code> if a qualifier was not specified + * @exception UnsupportedOperationException if this operation is used below JLS8 + * @since 3.9 + */ + public SimpleName getReceiverQualifier() { + unsupportedIn2_3_4(); + return this.receiverQualifier; + } + + /** + * Sets the given simple name as the qualifier for the receiver. + * This API is supported in JLS8 only. + * + * @param receiverQualifier explicit receiver parameter to be added to the method declaration + * @exception UnsupportedOperationException if this operation is used below JLS8 + * @since 3.9 + */ + public void setReceiverQualifier(SimpleName receiverQualifier) { + unsupportedIn2_3_4(); + ASTNode oldChild = this.receiverQualifier; + preReplaceChild(oldChild, receiverQualifier, RECEIVER_QUALIFIER_PROPERTY); + this.receiverQualifier = receiverQualifier; + postReplaceChild(oldChild, receiverQualifier, RECEIVER_QUALIFIER_PROPERTY); + } + + /** * Returns the live ordered list of method parameter declarations for this * method declaration. * @@ -672,10 +887,30 @@ public class MethodDeclaration extends BodyDeclaration * (element type: {@link Name}) */ public List thrownExceptions() { + if (this.thrownExceptions == null) { + supportedOnlyIn2_3_4(); + } return this.thrownExceptions; } /** + * Returns the live ordered list of thrown exception types in this method + * declaration. + * + * @return the live list of exception types + * (element type: {@link Type}) + * @exception UnsupportedOperationException if this operation is used + * in a JLS2, JLS3 or JLS4 AST + * @since 3.9 + */ + public List thrownExceptionTypes() { + if (this.thrownExceptionTypes == null) { + unsupportedIn2_3_4(); + } + return this.thrownExceptionTypes; + } + + /** * Returns the return type of the method declared in this method * declaration, exclusive of any extra array dimensions (JLS2 API only). * This is one of the few places where the void type is meaningful. @@ -837,6 +1072,9 @@ public class MethodDeclaration extends BodyDeclaration * @since 2.1 */ public int getExtraDimensions() { + if (this.ast.apiLevel >= AST.JLS8) { + return this.extraDimensionInfos.size(); + } return this.extraArrayDimensions; } @@ -856,8 +1094,10 @@ public class MethodDeclaration extends BodyDeclaration * @exception IllegalArgumentException if the number of dimensions is * negative * @since 2.1 + * @deprecated In the JLS8 API, use: {@link #extraDimensionInfos()}. */ public void setExtraDimensions(int dimensions) { + supportedOnlyIn2_3_4(); if (dimensions < 0) { throw new IllegalArgumentException(); } @@ -865,6 +1105,18 @@ public class MethodDeclaration extends BodyDeclaration this.extraArrayDimensions = dimensions; postValueChange(EXTRA_DIMENSIONS_PROPERTY); } + + /** + * Returns the live ordered list of extra dimensions with optional annotations (JLS8 API only). + * + * @return the live list of extra dimensions with optional annotations (element type: {@link ExtraDimension}) + * @since 3.9 + */ + public List extraDimensionInfos() { + unsupportedIn2_3_4(); + return this.extraDimensionInfos; + } + //{ObjectTeams: accessors for new element public void setGuardPredicate(GuardPredicateDeclaration predicate) { ASTNode oldChild = this.optionalGuardPredicate; @@ -937,7 +1189,7 @@ public class MethodDeclaration extends BodyDeclaration * Method declared on ASTNode. */ int memSize() { - return super.memSize() + 9 * 4; + return super.memSize() + 13 * 4; } /* (omit javadoc for this method) @@ -950,9 +1202,13 @@ public class MethodDeclaration extends BodyDeclaration + (this.modifiers == null ? 0 : this.modifiers.listSize()) + (this.typeParameters == null ? 0 : this.typeParameters.listSize()) + (this.methodName == null ? 0 : getName().treeSize()) + + (this.receiverType == null ? 0 : this.receiverType.treeSize()) + + (this.receiverQualifier == null ? 0 : this.receiverQualifier.treeSize()) + (this.returnType == null ? 0 : this.returnType.treeSize()) + this.parameters.listSize() - + this.thrownExceptions.listSize() + + (this.ast.apiLevel < AST.JLS8 ? + this.thrownExceptions.listSize() + : this.extraDimensionInfos.listSize() + this.thrownExceptionTypes.listSize()) + (this.optionalBody == null ? 0 : getBody().treeSize()); } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java index e7d072662..65430ed08 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java @@ -1,60 +1,28 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2008 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 *******************************************************************************/ package org.eclipse.jdt.core.dom; -import java.util.List; - /** * Abstract base class for all AST nodes that represent names. * There are exactly two kinds of name: simple ones * (<code>SimpleName</code>) and qualified ones (<code>QualifiedName</code>). * <p> - * For JLS2, JLS3 or JLS4: * <pre> * Name: * SimpleName * QualifiedName * </pre> - * <p> - * For JLS8, the Name may be preceded by optional type annotations. - * While the additional locations where Java SE8 allows annotations - * to be written are only in type references and type parameters, there - * are various situations in which a parser is unable to decide whether - * a name it sees constitutes a type name or not and ends up creating - * Name nodes. - * </p> - * <p> - * For example, given the qualified type reference java.util.List, - * the ASTParser cannot decide when bindings resolution is NOT requested - * via {@link ASTParser#setResolveBindings}, whether java constitutes a - * type name or a non-type name (i.e., a package name) - * </p> - * <p> - * Note also that the parser cannot disambiguate on the basis of the - * presence of type annotations at a certain place. - * In @NonNull java.util.List, java is still a package name even though - * it is preceded by annotations. - * </p> - * For JLS8: - * <pre> - * Name: - * {Annotation} SimpleName - * {Annotation} QualifiedName - * </pre> * </p> + * * @since 2.0 * @noextend This class is not intended to be subclassed by clients. */ @@ -64,18 +32,12 @@ public abstract class Name extends Expression implements IDocElement { * Approximate base size of an expression node instance in bytes, * including object header and instance fields. */ - static final int BASE_NAME_NODE_SIZE = BASE_NODE_SIZE + 2 * 4; + static final int BASE_NAME_NODE_SIZE = BASE_NODE_SIZE + 1 * 4; /** * This index represents the position inside a qualified name. */ int index; - - /** - * The type annotations (element type: {@link Annotation}). - * @since 3.9 - */ - protected ASTNode.NodeList annotations = null; /** * Creates a new AST node for a name owned by the given AST. @@ -154,19 +116,4 @@ public abstract class Name extends Expression implements IDocElement { * @since 3.0 */ abstract void appendName(StringBuffer buffer); - - /** - * Returns the live ordered list of annotations for this Name node. - * - * @return the live list of annotations (element type: {@link Annotation}) - * @exception UnsupportedOperationException if this operation is used - * in a JLS2, JLS3 or JLS4 AST - * @since 3.9 - */ - public List annotations() { - if (this.annotations == null) { - unsupportedIn2_3_4(); - } - return this.annotations; - } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java index 501e8695b..3320e9ea8 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -44,7 +44,7 @@ import java.util.Map; * @since 2.0 * @noinstantiate This class is not intended to be instantiated by clients. */ -public class PrimitiveType extends Type { +public class PrimitiveType extends AnnotatableType { /** * Primitive type codes (typesafe enumeration). @@ -285,7 +285,6 @@ public class PrimitiveType extends Type { result.setSourceRange(getStartPosition(), getLength()); result.setPrimitiveTypeCode(getPrimitiveTypeCode()); if (this.ast.apiLevel >= AST.JLS8) { - result.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY); result.annotations.addAll( ASTNode.copySubtrees(target, annotations())); } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java index 1f0e27272..c7753b2ed 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java @@ -1,14 +1,10 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 *******************************************************************************/ @@ -23,19 +19,11 @@ import java.util.List; * AST node for a qualified name. A qualified name is defined recursively * as a simple name preceded by a name, which qualifies it. Expressing it this * way means that the qualifier and the simple name get their own AST nodes. - * For JLS2, JLS3 or JLS4: * <pre> * QualifiedName: * Name <b>.</b> SimpleName * </pre> * <p> - * For JLS8: - * <pre> - * QualifiedName: - * Name <b>.</b> {Annotation} SimpleName - * </pre> - * </p> - * <p> * See <code>FieldAccess</code> for guidelines on handling other expressions * that resemble qualified names. * </p> @@ -61,25 +49,11 @@ public class QualifiedName extends Name { new ChildPropertyDescriptor(QualifiedName.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$ /** - * The "annotations" structural property of this node type (child type: {@link Annotation}). - * @since 3.9 - */ - public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY = - new ChildListPropertyDescriptor(QualifiedName.class, "annotations", Annotation.class, CYCLE_RISK); //$NON-NLS-1$ - /** * A list of property descriptors (element type: * {@link StructuralPropertyDescriptor}), * or null if uninitialized. */ private static final List PROPERTY_DESCRIPTORS; - - /** - * A list of property descriptors (element type: - * {@link StructuralPropertyDescriptor}), - * or null if uninitialized. - * @since 3.9 - */ - private static final List PROPERTY_DESCRIPTORS_8_0; static { List propertyList = new ArrayList(3); @@ -87,13 +61,6 @@ public class QualifiedName extends Name { addProperty(QUALIFIER_PROPERTY, propertyList); addProperty(NAME_PROPERTY, propertyList); PROPERTY_DESCRIPTORS = reapPropertyList(propertyList); - - propertyList = new ArrayList(4); - createPropertyList(QualifiedName.class, propertyList); - addProperty(QUALIFIER_PROPERTY, propertyList); - addProperty(NAME_PROPERTY, propertyList); - addProperty(ANNOTATIONS_PROPERTY, propertyList); - PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList); } /** @@ -107,14 +74,7 @@ public class QualifiedName extends Name { * @since 3.0 */ public static List propertyDescriptors(int apiLevel) { - switch (apiLevel) { - case AST.JLS2_INTERNAL : - case AST.JLS3_INTERNAL : - case AST.JLS4: - return PROPERTY_DESCRIPTORS; - default : - return PROPERTY_DESCRIPTORS_8_0; - } + return PROPERTY_DESCRIPTORS; } /** @@ -141,9 +101,6 @@ public class QualifiedName extends Name { */ QualifiedName(AST ast) { super(ast); - if (ast.apiLevel >= AST.JLS8) { - this.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY); - } } /* (omit javadoc for this method) @@ -152,17 +109,6 @@ public class QualifiedName extends Name { final List internalStructuralPropertiesForType(int apiLevel) { return propertyDescriptors(apiLevel); } - - /* (omit javadoc for this method) - * Method declared on ASTNode. - */ - final List internalGetChildListProperty(ChildListPropertyDescriptor property) { - if (property == ANNOTATIONS_PROPERTY) { - return annotations(); - } - // allow default implementation to flag the error - return super.internalGetChildListProperty(property); - } /* (omit javadoc for this method) * Method declared on ASTNode. @@ -203,11 +149,6 @@ public class QualifiedName extends Name { result.setSourceRange(getStartPosition(), getLength()); result.setQualifier((Name) getQualifier().clone(target)); result.setName((SimpleName) getName().clone(target)); - if (this.ast.apiLevel >= AST.JLS8) { - result.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY); - result.annotations.addAll( - ASTNode.copySubtrees(target, annotations())); - } return result; } @@ -227,9 +168,6 @@ public class QualifiedName extends Name { if (visitChildren) { // visit children in normal left to right reading order acceptChild(visitor, getQualifier()); - if (this.ast.apiLevel >= AST.JLS8) { - acceptChildren(visitor, this.annotations); - } acceptChild(visitor, getName()); } visitor.endVisit(this); @@ -327,7 +265,7 @@ public class QualifiedName extends Name { * Method declared on ASTNode. */ int memSize() { - return BASE_NAME_NODE_SIZE + 2 * 4; + return BASE_NAME_NODE_SIZE + 3 * 4; } /* (omit javadoc for this method) @@ -337,8 +275,7 @@ public class QualifiedName extends Name { return memSize() + (this.name == null ? 0 : getName().treeSize()) - + (this.qualifier == null ? 0 : getQualifier().treeSize()) - + (this.annotations == null ? 0 : this.annotations.listSize()); + + (this.qualifier == null ? 0 : getQualifier().treeSize()); } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java index 22e01e0cd..2eed89eaa 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2012 IBM Corporation and others. + * Copyright (c) 2003, 2013 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 @@ -55,7 +55,7 @@ import java.util.List; * @since 3.1 * @noinstantiate This class is not intended to be instantiated by clients. */ -public class QualifiedType extends Type { +public class QualifiedType extends AnnotatableType { /** * This index represents the position inside a parameterized qualified type. */ @@ -216,7 +216,6 @@ public class QualifiedType extends Type { result.setQualifier((Type) ((ASTNode) getQualifier()).clone(target)); result.setName((SimpleName) ((ASTNode) getName()).clone(target)); if (this.ast.apiLevel >= AST.JLS8) { - result.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY); result.annotations.addAll( ASTNode.copySubtrees(target, annotations())); } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java index 23718531a..b28a63e48 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java @@ -1,14 +1,10 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 * Fraunhofer FIRST - extended API and implementation @@ -45,13 +41,6 @@ public class SimpleName extends Name { */ public static final SimplePropertyDescriptor IDENTIFIER_PROPERTY = new SimplePropertyDescriptor(SimpleName.class, "identifier", String.class, MANDATORY); //$NON-NLS-1$ - - /** - * The "annotations" structural property of this node type (child type: {@link Annotation}). - * @since 3.9 - */ - public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY = - new ChildListPropertyDescriptor(SimpleName.class, "annotations", Annotation.class, CYCLE_RISK); //$NON-NLS-1$ /** * A list of property descriptors (element type: @@ -60,26 +49,12 @@ public class SimpleName extends Name { * @since 3.0 */ private static final List PROPERTY_DESCRIPTORS; - - /** - * A list of property descriptors (element type: - * {@link StructuralPropertyDescriptor}), - * or null if uninitialized. - * @since 3.9 - */ - private static final List PROPERTY_DESCRIPTORS_8_0; static { List propertyList = new ArrayList(2); createPropertyList(SimpleName.class, propertyList); addProperty(IDENTIFIER_PROPERTY, propertyList); PROPERTY_DESCRIPTORS = reapPropertyList(propertyList); - - propertyList = new ArrayList(3); - createPropertyList(SimpleName.class, propertyList); - addProperty(IDENTIFIER_PROPERTY, propertyList); - addProperty(ANNOTATIONS_PROPERTY, propertyList); - PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList); } /** @@ -92,14 +67,7 @@ public class SimpleName extends Name { * @since 3.0 */ public static List propertyDescriptors(int apiLevel) { - switch (apiLevel) { - case AST.JLS2_INTERNAL : - case AST.JLS3_INTERNAL : - case AST.JLS4: - return PROPERTY_DESCRIPTORS; - default : - return PROPERTY_DESCRIPTORS_8_0; - } + return PROPERTY_DESCRIPTORS; } /** @@ -125,9 +93,6 @@ public class SimpleName extends Name { */ SimpleName(AST ast) { super(ast); - if (ast.apiLevel >= AST.JLS8) { - this.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY); - } } /* (omit javadoc for this method) @@ -137,17 +102,6 @@ public class SimpleName extends Name { final List internalStructuralPropertiesForType(int apiLevel) { return propertyDescriptors(apiLevel); } - - /* (omit javadoc for this method) - * Method declared on ASTNode. - */ - final List internalGetChildListProperty(ChildListPropertyDescriptor property) { - if (property == ANNOTATIONS_PROPERTY) { - return annotations(); - } - // allow default implementation to flag the error - return super.internalGetChildListProperty(property); - } /* (omit javadoc for this method) * Method declared on ASTNode. @@ -179,11 +133,6 @@ public class SimpleName extends Name { SimpleName result = new SimpleName(target); result.setSourceRange(getStartPosition(), getLength()); result.setIdentifier(getIdentifier()); - if (this.ast.apiLevel >= AST.JLS8) { - result.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY); - result.annotations.addAll( - ASTNode.copySubtrees(target, annotations())); - } return result; } @@ -199,12 +148,7 @@ public class SimpleName extends Name { * Method declared on ASTNode. */ void accept0(ASTVisitor visitor) { - boolean visitChildren = visitor.visit(this); - if (visitChildren) { - if (this.ast.apiLevel >= AST.JLS8) { - acceptChildren(visitor, this.annotations); - } - } + visitor.visit(this); visitor.endVisit(this); } @@ -363,7 +307,7 @@ public class SimpleName extends Name { * Method declared on ASTNode. */ int memSize() { - int size = BASE_NAME_NODE_SIZE + 1 * 4; + int size = BASE_NAME_NODE_SIZE + 2 * 4; if (this.identifier != MISSING_IDENTIFIER) { // everything but our missing id costs size += stringSize(this.identifier); @@ -375,7 +319,7 @@ public class SimpleName extends Name { * Method declared on ASTNode. */ int treeSize() { - return memSize() + (this.annotations == null ? 0 : this.annotations.listSize()); + return memSize(); } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java index 819c9051d..aff2b9afc 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -30,7 +30,7 @@ import java.util.List; * @since 2.0 * @noinstantiate This class is not intended to be instantiated by clients. */ -public class SimpleType extends Type { +public class SimpleType extends AnnotatableType { /** * The "name" structural property of this node type (child type: {@link Name}). @@ -165,7 +165,6 @@ public class SimpleType extends Type { result.setSourceRange(getStartPosition(), getLength()); result.setName((Name) (getName()).clone(target)); if (this.ast.apiLevel >= AST.JLS8) { - result.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY); result.annotations.addAll( ASTNode.copySubtrees(target, annotations())); } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java index 2f1e493c0..8c2e4e04e 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 *******************************************************************************/ @@ -32,6 +36,12 @@ import java.util.List; * SingleVariableDeclaration: * { ExtendedModifier } Type [ <b>...</b> ] Identifier { <b>[</b><b>]</b> } [ <b>=</b> Expression ] * </pre> + * For JLS8, variable declarations and extra dimensions on variable declarations are allowed to + * have optional annotations. The annotatable extra dimensions are represented by {@link ExtraDimension}. + * <pre> + * SingleVariableDeclaration: + * { ExtendedModifier } Type {Annotation} [ <b>...</b> ] Identifier { ExtraDimension } [ <b>=</b> Expression ] + * </pre> * * @since 2.0 * @noinstantiate This class is not intended to be instantiated by clients. @@ -72,15 +82,31 @@ public class SingleVariableDeclaration extends VariableDeclaration { */ public static final SimplePropertyDescriptor VARARGS_PROPERTY = new SimplePropertyDescriptor(SingleVariableDeclaration.class, "varargs", boolean.class, MANDATORY); //$NON-NLS-1$ + + /** + * The "varargsAnnotations" structural property of variable arguments of this node type (child type: {@link Annotation}). + * @since 3.9 + */ + public static final ChildListPropertyDescriptor VARARGS_ANNOTATIONS_PROPERTY = + new ChildListPropertyDescriptor(SingleVariableDeclaration.class, "varargsAnnotations", Annotation.class, NO_CYCLE_RISK); //$NON-NLS-1$ /** * The "extraDimensions" structural property of this node type (type: {@link Integer}). + * * @since 3.0 + * @deprecated in JLS8, use {@link SingleVariableDeclaration#EXTRA_DIMENSION_INFOS_PROPERTY} instead. */ public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY = new SimplePropertyDescriptor(SingleVariableDeclaration.class, "extraDimensions", int.class, MANDATORY); //$NON-NLS-1$ /** + * The "extraDimensionInfos" structural property of this node type (child type: {@link ExtraDimension}) (added in JLS8 API). + * @since 3.9 + */ + public static final ChildListPropertyDescriptor EXTRA_DIMENSION_INFOS_PROPERTY = + new ChildListPropertyDescriptor(SingleVariableDeclaration.class, "extraDimensionInfos", ExtraDimension.class, NO_CYCLE_RISK); //$NON-NLS-1$ + + /** * The "initializer" structural property of this node type (child type: {@link Expression}). * @since 3.0 */ @@ -102,7 +128,15 @@ public class SingleVariableDeclaration extends VariableDeclaration { * @since 3.1 */ private static final List PROPERTY_DESCRIPTORS_3_0; - + + /** + * A list of property descriptors (element type: + * {@link StructuralPropertyDescriptor}), + * or null if uninitialized. + * @since 3.9 + */ + private static final List PROPERTY_DESCRIPTORS_8_0; + static { List propertyList = new ArrayList(6); createPropertyList(SingleVariableDeclaration.class, propertyList); @@ -122,7 +156,20 @@ public class SingleVariableDeclaration extends VariableDeclaration { addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList); addProperty(INITIALIZER_PROPERTY, propertyList); PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList); - } + + + propertyList = new ArrayList(8); + createPropertyList(SingleVariableDeclaration.class, propertyList); + addProperty(MODIFIERS2_PROPERTY, propertyList); + addProperty(TYPE_PROPERTY, propertyList); + addProperty(VARARGS_ANNOTATIONS_PROPERTY, propertyList); + addProperty(VARARGS_PROPERTY, propertyList); + addProperty(NAME_PROPERTY, propertyList); + addProperty(EXTRA_DIMENSION_INFOS_PROPERTY, propertyList); + addProperty(INITIALIZER_PROPERTY, propertyList); + PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList); + + } /** * Returns a list of structural property descriptors for this node type. @@ -137,8 +184,10 @@ public class SingleVariableDeclaration extends VariableDeclaration { public static List propertyDescriptors(int apiLevel) { if (apiLevel == AST.JLS2_INTERNAL) { return PROPERTY_DESCRIPTORS_2_0; - } else { + } else if (apiLevel < AST.JLS8) { return PROPERTY_DESCRIPTORS_3_0; + } else { + return PROPERTY_DESCRIPTORS_8_0; } } @@ -186,11 +235,24 @@ public class SingleVariableDeclaration extends VariableDeclaration { private int extraArrayDimensions = 0; /** + * List of extra dimensions this node has with optional annotations. + * + * @since 3.9 + */ + protected ASTNode.NodeList extraDimensionInfos = null; + + /** * The initializer expression, or <code>null</code> if none; * defaults to none. */ private Expression optionalInitializer = null; + /** + * The type annotations (element type: {@link Annotation}). + * @since 3.9 + */ + private ASTNode.NodeList varargsAnnotations = null; + //{ObjectTeams: emulation for declared lifting: private SingleVariableDeclaration fakedRoleVariable; public static final ChildPropertyDescriptor FAKED_ROLE_VARIABLE = @@ -240,6 +302,10 @@ public class SingleVariableDeclaration extends VariableDeclaration { super(ast); if (ast.apiLevel >= AST.JLS3_INTERNAL) { this.modifiers = new ASTNode.NodeList(MODIFIERS2_PROPERTY); + if (ast.apiLevel >= AST.JLS8) { + this.varargsAnnotations = new ASTNode.NodeList(VARARGS_ANNOTATIONS_PROPERTY); + this.extraDimensionInfos = new ASTNode.NodeList(EXTRA_DIMENSION_INFOS_PROPERTY); + } } } @@ -353,6 +419,12 @@ public class SingleVariableDeclaration extends VariableDeclaration { if (property == MODIFIERS2_PROPERTY) { return modifiers(); } + if (property == VARARGS_ANNOTATIONS_PROPERTY) { + return varargsAnnotations(); + } + if (property == EXTRA_DIMENSION_INFOS_PROPERTY) { + return extraDimensionInfos(); + } // allow default implementation to flag the error return super.internalGetChildListProperty(property); } @@ -377,10 +449,20 @@ public class SingleVariableDeclaration extends VariableDeclaration { result.setVarargs(isVarargs()); } result.setType((Type) getType().clone(target)); - result.setExtraDimensions(getExtraDimensions()); + if (this.ast.apiLevel >= AST.JLS8) { + result.extraDimensionInfos.addAll( + ASTNode.copySubtrees(target, this.extraDimensionInfos)); + } else { + result.setExtraDimensions(getExtraDimensions()); + } result.setName((SimpleName) getName().clone(target)); result.setInitializer( (Expression) ASTNode.copySubtree(target, getInitializer())); + if (this.ast.apiLevel >= AST.JLS8) { + result.varargsAnnotations = new ASTNode.NodeList(VARARGS_ANNOTATIONS_PROPERTY); + result.varargsAnnotations().addAll( + ASTNode.copySubtrees(target, varargsAnnotations())); + } return result; } @@ -403,7 +485,13 @@ public class SingleVariableDeclaration extends VariableDeclaration { acceptChildren(visitor, this.modifiers); } acceptChild(visitor, getType()); + if (this.ast.apiLevel >= AST.JLS8 && isVarargs()) { + acceptChildren(visitor, this.varargsAnnotations); + } acceptChild(visitor, getName()); + if (this.ast.apiLevel >= AST.JLS8){ + acceptChildren(visitor, this.extraDimensionInfos); + } acceptChild(visitor, getInitializer()); } visitor.endVisit(this); @@ -608,19 +696,32 @@ public class SingleVariableDeclaration extends VariableDeclaration { postValueChange(VARARGS_PROPERTY); } - /* (omit javadoc for this method) - * Method declared on VariableDeclaration. + /** + * Returns the number of extra array dimensions over and above the + * explicitly-specified type. + * + * @return the number of extra array dimensions * @since 2.1 */ public int getExtraDimensions() { + if (this.ast.apiLevel >= AST.JLS8) { + return this.extraDimensionInfos.size(); + } return this.extraArrayDimensions; } - /* (omit javadoc for this method) - * Method declared on VariableDeclaration. + /** + * Sets the number of extra array dimensions over and above the + * explicitly-specified type (Not supported in JLS8 and above). + * + * @param dimensions the number of array dimensions + * @exception IllegalArgumentException if the number of dimensions is + * negative * @since 2.1 + * @deprecated In the JLS8 API, see: {@link #extraDimensionInfos()}. */ public void setExtraDimensions(int dimensions) { + supportedOnlyIn2_3_4(); if (dimensions < 0) { throw new IllegalArgumentException(); } @@ -629,6 +730,17 @@ public class SingleVariableDeclaration extends VariableDeclaration { postValueChange(EXTRA_DIMENSIONS_PROPERTY); } + /** + * Returns the live ordered list of extra dimensions with optional annotations (JLS8 API only). + * + * @return the live list of extra dimensions with optional annotations (element type: {@link ExtraDimension}) + * @since 3.9 + */ + public List extraDimensionInfos() { + unsupportedIn2_3_4(); + return this.extraDimensionInfos; + } + /* (omit javadoc for this method) * Method declared on VariableDeclaration. */ @@ -647,13 +759,28 @@ public class SingleVariableDeclaration extends VariableDeclaration { this.optionalInitializer = initializer; postReplaceChild(oldChild, initializer,INITIALIZER_PROPERTY); } - + + /** + * Returns the ordered list of annotations of variable arguments. + * + * @return the list of annotations of the varargs (element type: {@link Annotation}) + * @exception UnsupportedOperationException if this operation is used + * in a JLS2, JLS3 or JLS4 AST + * @since 3.9 + */ + public List varargsAnnotations() { + if (this.varargsAnnotations == null) { + unsupportedIn2_3_4(); + } + return this.varargsAnnotations; + } + /* (omit javadoc for this method) * Method declared on ASTNode. */ int memSize() { // treat Operator as free - return BASE_NODE_SIZE + 7 * 4; + return BASE_NODE_SIZE + 9 * 4; } /* (omit javadoc for this method) @@ -662,7 +789,9 @@ public class SingleVariableDeclaration extends VariableDeclaration { int treeSize() { return memSize() + + (this.varargsAnnotations == null ? 0 : this.varargsAnnotations.listSize()) + (this.modifiers == null ? 0 : this.modifiers.listSize()) + + (this.extraDimensionInfos == null ? 0 : this.extraDimensionInfos.listSize()) + (this.type == null ? 0 : getType().treeSize()) + (this.variableName == null ? 0 : getName().treeSize()) + (this.optionalInitializer == null ? 0 : getInitializer().treeSize()); diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java index af18af89b..e9860ee82 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -15,7 +15,6 @@ package org.eclipse.jdt.core.dom; -import java.util.List; /** * Abstract base class of all type AST node types. A type node represents a @@ -30,26 +29,27 @@ import java.util.List; * <p> * <pre> * Type: - * PrimitiveType - * ArrayType - * SimpleType - * QualifiedType + * AnnotatableType: + * PrimitiveType + * ArrayType + * SimpleType + * QualifiedType + * WildcardType * ParameterizedType - * WildcardType * UnionType * * PrimitiveType: - * <b>{Annotation} byte</b> - * <b>{Annotation} short</b> - * <b>{Annotation} char</b> - * <b>{Annotation} int</b> - * <b>{Annotation} long</b> - * <b>{Annotation} float</b> - * <b>{Annotation} double</b> - * <b>{Annotation} boolean</b> - * <b>{Annotation} void</b> + * {Annotation} <b>byte</b> + * {Annotation} <b>short</b> + * {Annotation} <b>char</b> + * {Annotation} <b>int</b> + * {Annotation} <b>long</b> + * {Annotation} <b>float</b> + * {Annotation} <b>double</b> + * {Annotation} <b>boolean</b> + * {Annotation} <b>void</b> * ArrayType: - * Type <b>{Annotation} [</b> <b>]</b> + * Type {Annotation} <b>'['</b> <b>']'</b> * SimpleType: * {Annotation} TypeName * ParameterizedType: @@ -64,12 +64,6 @@ import java.util.List; * @since 2.0 */ public abstract class Type extends ASTNode { - - /** - * The type annotations (element type: {@link Annotation}). - * @since 3.9 - */ - protected ASTNode.NodeList annotations = null; /** * Creates a new AST node for a type owned by the given AST. @@ -183,6 +177,19 @@ public abstract class Type extends ASTNode { public final boolean isWildcardType() { return (this instanceof WildcardType); } + + /** + * Returns whether this type can be annotated. All sub-classes of + * {@link AnnotatableType} can be annotated. + * + * @return <code>true</code> if this type is an instance of {@link AnnotatableType}, and + * <code>false</code> otherwise + * + * @since 3.9 + */ + public boolean isAnnotatable() { + return (this instanceof AnnotatableType); + } /** * Resolves and returns the binding for this type. @@ -197,19 +204,4 @@ public abstract class Type extends ASTNode { public final ITypeBinding resolveBinding() { return this.ast.getBindingResolver().resolveType(this); } - - /** - * Returns the live ordered list of annotations for this Type node. - * - * @return the live list of annotations (element type: {@link Annotation}) - * @exception UnsupportedOperationException if this operation is used - * in a JLS2, JLS3 or JLS4 AST - * @since 3.9 - */ - public List annotations() { - if (this.annotations == null) { - unsupportedIn2_3_4(); - } - return this.annotations; - } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java index e9de7c892..20668d101 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java @@ -25,7 +25,12 @@ import java.util.List; * VariableDeclarationFragment: * Identifier { <b>[</b><b>]</b> } [ <b>=</b> Expression ] * </pre> - * + * For JLS8, variable fragments and extra dimensions on fragments are allowed to have optional + * annotations. The annotatable extra dimensions are represented by {@link ExtraDimension}. + * <pre> + * VariableDeclarationFragment: + * Identifier { ExtraDimension } [ <b>=</b> Expression ] + * </pre> * @since 2.0 * @noinstantiate This class is not intended to be instantiated by clients. */ @@ -40,12 +45,21 @@ public class VariableDeclarationFragment extends VariableDeclaration { /** * The "extraDimensions" structural property of this node type (type: {@link Integer}). + * * @since 3.0 + * @deprecated in JLS8, use {@link VariableDeclarationFragment#EXTRA_DIMENSION_INFOS_PROPERTY} instead. */ public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY = new SimplePropertyDescriptor(VariableDeclarationFragment.class, "extraDimensions", int.class, MANDATORY); //$NON-NLS-1$ /** + * The "extraDimensionInfos" structural property of this node type (child type: {@link ExtraDimension}) (Added in JLS8 API). + * @since 3.9 + */ + public static final ChildListPropertyDescriptor EXTRA_DIMENSION_INFOS_PROPERTY = + new ChildListPropertyDescriptor(VariableDeclarationFragment.class, "extraDimensionInfos", ExtraDimension.class, NO_CYCLE_RISK); //$NON-NLS-1$ + + /** * The "initializer" structural property of this node type (child type: {@link Expression}). * @since 3.0 */ @@ -60,6 +74,14 @@ public class VariableDeclarationFragment extends VariableDeclaration { */ private static final List PROPERTY_DESCRIPTORS; + /** + * A list of property descriptors (element type: + * {@link StructuralPropertyDescriptor}), + * or null if uninitialized. + * @since 3.9 + */ + private static final List PROPERTY_DESCRIPTORS_8_0; + static { List propertyList = new ArrayList(4); createPropertyList(VariableDeclarationFragment.class, propertyList); @@ -67,6 +89,13 @@ public class VariableDeclarationFragment extends VariableDeclaration { addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList); addProperty(INITIALIZER_PROPERTY, propertyList); PROPERTY_DESCRIPTORS = reapPropertyList(propertyList); + + propertyList = new ArrayList(4); + createPropertyList(VariableDeclarationFragment.class, propertyList); + addProperty(NAME_PROPERTY, propertyList); + addProperty(EXTRA_DIMENSION_INFOS_PROPERTY, propertyList); + addProperty(INITIALIZER_PROPERTY, propertyList); + PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList); } /** @@ -80,7 +109,11 @@ public class VariableDeclarationFragment extends VariableDeclaration { * @since 3.0 */ public static List propertyDescriptors(int apiLevel) { - return PROPERTY_DESCRIPTORS; + if (apiLevel >= AST.JLS8) { + return PROPERTY_DESCRIPTORS_8_0; + } else { + return PROPERTY_DESCRIPTORS; + } } /** @@ -96,6 +129,13 @@ public class VariableDeclarationFragment extends VariableDeclaration { private int extraArrayDimensions = 0; /** + * The extra dimensions this node has with optional annotations. + * + * @since 3.9 + */ + protected ASTNode.NodeList extraDimensionInfos = null; + + /** * The initializer expression, or <code>null</code> if none; * defaults to none. */ @@ -113,6 +153,9 @@ public class VariableDeclarationFragment extends VariableDeclaration { */ VariableDeclarationFragment(AST ast) { super(ast); + if (ast.apiLevel >= AST.JLS8) { + this.extraDimensionInfos = new ASTNode.NodeList(EXTRA_DIMENSION_INFOS_PROPERTY); + } } /* (omit javadoc for this method) @@ -189,6 +232,17 @@ public class VariableDeclarationFragment extends VariableDeclaration { /* (omit javadoc for this method) * Method declared on ASTNode. */ + final List internalGetChildListProperty(ChildListPropertyDescriptor property) { + if (property == EXTRA_DIMENSION_INFOS_PROPERTY) { + return extraDimensionInfos(); + } + // allow default implementation to flag the error + return super.internalGetChildListProperty(property); + } + + /* (omit javadoc for this method) + * Method declared on ASTNode. + */ final int getNodeType0() { return VARIABLE_DECLARATION_FRAGMENT; } @@ -200,7 +254,12 @@ public class VariableDeclarationFragment extends VariableDeclaration { VariableDeclarationFragment result = new VariableDeclarationFragment(target); result.setSourceRange(getStartPosition(), getLength()); result.setName((SimpleName) getName().clone(target)); - result.setExtraDimensions(getExtraDimensions()); + if (this.ast.apiLevel >= AST.JLS8) { + result.extraDimensionInfos.addAll( + ASTNode.copySubtrees(target, this.extraDimensionInfos)); + } else { + result.setExtraDimensions(getExtraDimensions()); + } result.setInitializer( (Expression) ASTNode.copySubtree(target, getInitializer())); return result; @@ -222,6 +281,9 @@ public class VariableDeclarationFragment extends VariableDeclaration { if (visitChildren) { // visit children in normal left to right reading order acceptChild(visitor, getName()); + if (this.ast.apiLevel >= AST.JLS8) { + acceptChildren(visitor, this.extraDimensionInfos); + } acceptChild(visitor, getInitializer()); } visitor.endVisit(this); @@ -272,6 +334,9 @@ public class VariableDeclarationFragment extends VariableDeclaration { * @since 2.0 */ public int getExtraDimensions() { + if (this.ast.apiLevel >= AST.JLS8) { + return this.extraDimensionInfos.size(); + } return this.extraArrayDimensions; } @@ -287,8 +352,10 @@ public class VariableDeclarationFragment extends VariableDeclaration { * * @param dimensions the given dimensions * @since 2.0 + * @deprecated In the JLS8 API, see: {@link #extraDimensionInfos()}. */ public void setExtraDimensions(int dimensions) { + supportedOnlyIn2_3_4(); if (dimensions < 0) { throw new IllegalArgumentException(); } @@ -297,6 +364,18 @@ public class VariableDeclarationFragment extends VariableDeclaration { postValueChange(EXTRA_DIMENSIONS_PROPERTY); } + /** + * Returns the live ordered list of extra dimensions with optional annotations (JLS8 API only). + * + * @return the live list of extra dimensions with optional annotations (element type: {@link ExtraDimension}) + * @see AST#newExtraDimension() + * @since 3.9 + */ + public List extraDimensionInfos() { + unsupportedIn2_3_4(); + return this.extraDimensionInfos; + } + /* (omit javadoc for this method) * Method declared on VariableDeclaration. */ @@ -319,7 +398,7 @@ public class VariableDeclarationFragment extends VariableDeclaration { */ int memSize() { // treat Operator as free - return BASE_NODE_SIZE + 3 * 4; + return BASE_NODE_SIZE + 4 * 4; } /* (omit javadoc for this method) @@ -329,6 +408,7 @@ public class VariableDeclarationFragment extends VariableDeclaration { return memSize() + (this.variableName == null ? 0 : getName().treeSize()) - + (this.optionalInitializer == null ? 0 : getInitializer().treeSize()); + + (this.optionalInitializer == null ? 0 : getInitializer().treeSize()) + + (this.extraDimensionInfos == null ? 0 : extraDimensionInfos().size()); } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java index 8a4d92b43..9f222236d 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2012 IBM Corporation and others. + * Copyright (c) 2003, 2013 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 @@ -39,7 +39,7 @@ import java.util.List; * @since 3.1 * @noinstantiate This class is not intended to be instantiated by clients. */ -public class WildcardType extends Type { +public class WildcardType extends AnnotatableType { /** * The "bound" structural property of this node type (child type: {@link Type}). @@ -205,7 +205,6 @@ public class WildcardType extends Type { result.setSourceRange(getStartPosition(), getLength()); result.setBound((Type) ASTNode.copySubtree(target, getBound()), isUpperBound()); if (this.ast.apiLevel >= AST.JLS8) { - result.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY); result.annotations.addAll( ASTNode.copySubtrees(target, annotations())); } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java index 48fc6eed0..c39700079 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -324,6 +324,12 @@ public class NaiveASTFlattener extends ASTVisitor { return false; } + public boolean visit(ExtraDimension node) { + visitAnnotationsList(node.annotations()); + this.buffer.append("[]"); //$NON-NLS-1$ + return false; + } + /* * @see ASTVisitor#visit(AssertStatement) */ @@ -928,6 +934,22 @@ public class NaiveASTFlattener extends ASTVisitor { } node.getName().accept(this); this.buffer.append("(");//$NON-NLS-1$ + if (node.getAST().apiLevel() >= AST.JLS8) { + AnnotatableType receiverType = node.getReceiverType(); + if (receiverType != null) { + receiverType.accept(this); + this.buffer.append(' '); + SimpleName qualifier = node.getReceiverQualifier(); + if (qualifier != null) { + qualifier.accept(this); + this.buffer.append('.'); + } + this.buffer.append("this"); //$NON-NLS-1$ + if (node.parameters().size() > 0) { + this.buffer.append(','); + } + } + } for (Iterator it = node.parameters().iterator(); it.hasNext(); ) { SingleVariableDeclaration v = (SingleVariableDeclaration) it.next(); v.accept(this); @@ -936,19 +958,41 @@ public class NaiveASTFlattener extends ASTVisitor { } } this.buffer.append(")");//$NON-NLS-1$ - for (int i = 0; i < node.getExtraDimensions(); i++) { - this.buffer.append("[]"); //$NON-NLS-1$ - } - if (!node.thrownExceptions().isEmpty()) { - this.buffer.append(" throws ");//$NON-NLS-1$ - for (Iterator it = node.thrownExceptions().iterator(); it.hasNext(); ) { - Name n = (Name) it.next(); - n.accept(this); - if (it.hasNext()) { - this.buffer.append(", ");//$NON-NLS-1$ - } + int size = node.getExtraDimensions(); + if (node.getAST().apiLevel() >= AST.JLS8) { + List dimensions = node.extraDimensionInfos(); + for (int i = 0; i < size; i++) { + visit((ExtraDimension) dimensions.get(i)); + } + } else { + for (int i = 0; i < size; i++) { + this.buffer.append("[]"); //$NON-NLS-1$ + } + } + if (node.getAST().apiLevel() < AST.JLS8) { + if (!node.thrownExceptions().isEmpty()) { + this.buffer.append(" throws ");//$NON-NLS-1$ + for (Iterator it = node.thrownExceptions().iterator(); it.hasNext(); ) { + Name n = (Name) it.next(); + n.accept(this); + if (it.hasNext()) { + this.buffer.append(", ");//$NON-NLS-1$ + } + } + this.buffer.append(" ");//$NON-NLS-1$ + } + } else { + if (!node.thrownExceptionTypes().isEmpty()) { + this.buffer.append(" throws ");//$NON-NLS-1$ + for (Iterator it = node.thrownExceptionTypes().iterator(); it.hasNext(); ) { + Type n = (Type) it.next(); + n.accept(this); + if (it.hasNext()) { + this.buffer.append(", ");//$NON-NLS-1$ + } + } + this.buffer.append(" ");//$NON-NLS-1$ } - this.buffer.append(" ");//$NON-NLS-1$ } if (node.getBody() == null) { this.buffer.append(";\n");//$NON-NLS-1$ @@ -1158,7 +1202,6 @@ public class NaiveASTFlattener extends ASTVisitor { public boolean visit(QualifiedName node) { node.getQualifier().accept(this); this.buffer.append(".");//$NON-NLS-1$ - visitTypeAnnotations(node); node.getName().accept(this); return false; } @@ -1193,7 +1236,6 @@ public class NaiveASTFlattener extends ASTVisitor { * @see ASTVisitor#visit(SimpleName) */ public boolean visit(SimpleName node) { - visitTypeAnnotations(node); this.buffer.append(node.getIdentifier()); return false; } @@ -1202,8 +1244,17 @@ public class NaiveASTFlattener extends ASTVisitor { * @see ASTVisitor#visit(SimpleType) */ public boolean visit(SimpleType node) { - visitTypeAnnotations(node); - node.getName().accept(this); + Name name = node.getName(); + if (name.isQualifiedName()) { + QualifiedName qualifiedName = (QualifiedName) name; + qualifiedName.getQualifier().accept(this); + this.buffer.append(".");//$NON-NLS-1$ + visitTypeAnnotations(node); + qualifiedName.getName().accept(this); + } else { + visitTypeAnnotations(node); + node.getName().accept(this); + } return false; } @@ -1234,13 +1285,33 @@ public class NaiveASTFlattener extends ASTVisitor { node.getType().accept(this); if (node.getAST().apiLevel() >= JLS3) { if (node.isVarargs()) { + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391898 + if (node.getAST().apiLevel() >= AST.JLS8) { + List annotations = node.varargsAnnotations(); + if (annotations != null) { + this.buffer.append(' '); + for (Iterator it = annotations.iterator(); it.hasNext(); ) { + Annotation annotation = (Annotation) it.next(); + annotation.accept(this); + this.buffer.append(' '); + } + } + } this.buffer.append("...");//$NON-NLS-1$ } } this.buffer.append(" ");//$NON-NLS-1$ node.getName().accept(this); - for (int i = 0; i < node.getExtraDimensions(); i++) { - this.buffer.append("[]"); //$NON-NLS-1$ + int size = node.getExtraDimensions(); + if (node.getAST().apiLevel() >= AST.JLS8) { + List dimensions = node.extraDimensionInfos(); + for (int i = 0; i < size; i++) { + visit((ExtraDimension) dimensions.get(i)); + } + } else { + for (int i = 0; i < size; i++) { + this.buffer.append("[]"); //$NON-NLS-1$ + } } if (node.getInitializer() != null) { this.buffer.append("=");//$NON-NLS-1$ @@ -1665,8 +1736,16 @@ public class NaiveASTFlattener extends ASTVisitor { */ public boolean visit(VariableDeclarationFragment node) { node.getName().accept(this); - for (int i = 0; i < node.getExtraDimensions(); i++) { - this.buffer.append("[]");//$NON-NLS-1$ + int size = node.getExtraDimensions(); + if (node.getAST().apiLevel() >= AST.JLS8) { + List dimensions = node.extraDimensionInfos(); + for (int i = 0; i < size; i++) { + visit((ExtraDimension) dimensions.get(i)); + } + } else { + for (int i = 0; i < size; i++) { + this.buffer.append("[]");//$NON-NLS-1$ + } } if (node.getInitializer() != null) { this.buffer.append("=");//$NON-NLS-1$ @@ -1729,28 +1808,18 @@ public class NaiveASTFlattener extends ASTVisitor { } return false; } - - private void visitTypeAnnotations(Type node) { + private void visitTypeAnnotations(AnnotatableType node) { if (node.getAST().apiLevel() >= AST.JLS8) { - List annotations = node.annotations(); - if (annotations != null) { - for (Iterator it = annotations.iterator(); it.hasNext(); ) { - Annotation annotation = (Annotation) it.next(); - annotation.accept(this); - this.buffer.append(' '); - } - } + visitAnnotationsList(node.annotations()); } } - private void visitTypeAnnotations(Name node) { - if (node.getAST().apiLevel() >= AST.JLS8) { - List annotations = node.annotations(); - if (annotations != null) { - for (Iterator it = annotations.iterator(); it.hasNext(); ) { - Annotation annotation = (Annotation) it.next(); - annotation.accept(this); - this.buffer.append(' '); - } + + private void visitAnnotationsList(List annotations) { + if (annotations != null) { + for (Iterator it = annotations.iterator(); it.hasNext(); ) { + Annotation annotation = (Annotation) it.next(); + annotation.accept(this); + this.buffer.append(' '); } } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java index 8ae586735..330dd7a6f 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -80,6 +80,25 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { * @deprecated */ /*package*/ static final int JLS3_INTERNAL = AST.JLS3; + + /** + * Internal synonym for deprecated constant MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY + * to alleviate deprecated warnings. + * @deprecated + */ + static final SimplePropertyDescriptor INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY = MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY; + /** + * Internal synonym for deprecated constant SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY + * to alleviate deprecated warnings. + * @deprecated + */ + static final SimplePropertyDescriptor INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY = SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY; + /** + * Internal synonym for deprecated constant VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY + * to alleviate deprecated warnings. + * @deprecated + */ + static final SimplePropertyDescriptor INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY = VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY; TextEdit currentEdit; final RewriteEventStore eventStore; // used from inner classes @@ -1860,14 +1879,14 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameRPAREN, pos); - int extraDims= rewriteExtraDimensions(node, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY, pos); + int extraDims= rewriteExtraDimensions(node, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY, pos); boolean hasExceptionChanges= isChanged(node, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY); int bodyChangeKind= getChangeKind(node, MethodDeclaration.BODY_PROPERTY); if ((extraDims > 0) && (hasExceptionChanges || bodyChangeKind == RewriteEvent.INSERTED || bodyChangeKind == RewriteEvent.REMOVED)) { - int dim= ((Integer) getOriginalValue(node, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY)).intValue(); + int dim= ((Integer) getOriginalValue(node, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY)).intValue(); while (dim > 0) { pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameRBRACKET, pos); dim--; @@ -2823,9 +2842,6 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { } rewriteRequiredNode(node, QualifiedName.QUALIFIER_PROPERTY); - if (node.getAST().apiLevel() >= AST.JLS8) { - rewriteTypeAnnotations(node, QualifiedName.ANNOTATIONS_PROPERTY, node.getStartPosition()); - } rewriteRequiredNode(node, QualifiedName.NAME_PROPERTY); return false; } @@ -2837,9 +2853,6 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { if (!hasChildrenChanges(node)) { return doVisitUnchangedChildren(node); } - if (node.getAST().apiLevel() >= AST.JLS8) { - rewriteTypeAnnotations(node, SimpleName.ANNOTATIONS_PROPERTY, node.getStartPosition()); - } String newString= (String) getNewValue(node, SimpleName.IDENTIFIER_PROPERTY); TextEditGroup group = getEditGroup(node, SimpleName.IDENTIFIER_PROPERTY); doTextReplace(node.getStartPosition(), node.getLength(), newString, group); @@ -2895,7 +2908,7 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { } pos= rewriteRequiredNode(node, SingleVariableDeclaration.NAME_PROPERTY); - int extraDims= rewriteExtraDimensions(node, SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY, pos); + int extraDims= rewriteExtraDimensions(node, INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY, pos); if (extraDims > 0) { int kind= getChangeKind(node, SingleVariableDeclaration.INITIALIZER_PROPERTY); @@ -3295,7 +3308,7 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { int pos= rewriteRequiredNode(node, VariableDeclarationFragment.NAME_PROPERTY); - int extraDims= rewriteExtraDimensions(node, VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY, pos); + int extraDims= rewriteExtraDimensions(node, INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY, pos); if (extraDims > 0) { int kind= getChangeKind(node, VariableDeclarationFragment.INITIALIZER_PROPERTY); diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java index 93f382b16..8ac4e27a7 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -37,6 +37,25 @@ public class ASTRewriteFlattener extends ASTVisitor { */ /*package*/ static final int JLS3_INTERNAL = AST.JLS3; + /** + * Internal synonym for deprecated constant MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY + * to alleviate deprecated warnings. + * @deprecated + */ + static final SimplePropertyDescriptor INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY = MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY; + /** + * Internal synonym for deprecated constant SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY + * to alleviate deprecated warnings. + * @deprecated + */ + static final SimplePropertyDescriptor INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY = SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY; + /** + * Internal synonym for deprecated constant VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY + * to alleviate deprecated warnings. + * @deprecated + */ + static final SimplePropertyDescriptor INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY = VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY; + public static String asString(ASTNode node, RewriteEventStore store) { ASTRewriteFlattener flattener= new ASTRewriteFlattener(store); node.accept(flattener); @@ -661,7 +680,7 @@ public class ASTRewriteFlattener extends ASTVisitor { this.result.append('('); visitList(node, MethodDeclaration.PARAMETERS_PROPERTY, String.valueOf(',')); this.result.append(')'); - int extraDims= getIntAttribute(node, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY); + int extraDims= getIntAttribute(node, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY); for (int i = 0; i < extraDims; i++) { this.result.append("[]"); //$NON-NLS-1$ } @@ -780,9 +799,6 @@ public class ASTRewriteFlattener extends ASTVisitor { public boolean visit(QualifiedName node) { getChildNode(node, QualifiedName.QUALIFIER_PROPERTY).accept(this); this.result.append('.'); - if (node.getAST().apiLevel() >= AST.JLS8) { - visitList(node, QualifiedName.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' ')); - } getChildNode(node, QualifiedName.NAME_PROPERTY).accept(this); return false; } @@ -805,9 +821,6 @@ public class ASTRewriteFlattener extends ASTVisitor { * @see ASTVisitor#visit(SimpleName) */ public boolean visit(SimpleName node) { - if (node.getAST().apiLevel() >= AST.JLS8) { - visitList(node, SimpleName.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' ')); - } this.result.append(getAttribute(node, SimpleName.IDENTIFIER_PROPERTY)); return false; } @@ -840,7 +853,7 @@ public class ASTRewriteFlattener extends ASTVisitor { } this.result.append(' '); getChildNode(node, SingleVariableDeclaration.NAME_PROPERTY).accept(this); - int extraDimensions= getIntAttribute(node, SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY); + int extraDimensions= getIntAttribute(node, INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY); for (int i = 0; i < extraDimensions; i++) { this.result.append("[]"); //$NON-NLS-1$ } @@ -1095,7 +1108,7 @@ public class ASTRewriteFlattener extends ASTVisitor { */ public boolean visit(VariableDeclarationFragment node) { getChildNode(node, VariableDeclarationFragment.NAME_PROPERTY).accept(this); - int extraDimensions= getIntAttribute(node, VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY); + int extraDimensions= getIntAttribute(node, INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY); for (int i = 0; i < extraDimensions; i++) { this.result.append("[]"); //$NON-NLS-1$ } diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java index f0a111413..6298e9295 100644 --- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java +++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java @@ -60,11 +60,6 @@ public CodeSnippetClassFile( this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 0); long targetVersion = this.targetJDK = this.referenceBinding.scope.compilerOptions().targetJDK; - if (this.targetJDK == ClassFileConstants.JDK1_8) { - //TODO JAVA8: Version number is not yet updated in the java8 beta... - //Remove this after it is upgraded - targetVersion = this.targetJDK = ClassFileConstants.JDK1_7; - } //TODO: Might have to update even for CLDC_1_1 this.header[this.headerOffset++] = (byte) (targetVersion >> 8); // minor high this.header[this.headerOffset++] = (byte) (targetVersion >> 0); // minor low |