Compare commits
13 Commits
2d7b87edd7
...
removeWild
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a29be33ac7 | ||
|
|
1facf55ccc | ||
|
|
6c1f306dd6 | ||
|
|
4c94a9b869 | ||
|
|
09ab9a7e02 | ||
|
|
f63a8bcd4e | ||
|
|
bf2505685f | ||
|
|
21aa7e0e9c | ||
|
|
3fe35f6476 | ||
|
|
bc4d7d1bc9 | ||
|
|
7c06bd67df | ||
|
|
fa1d70f954 | ||
|
|
849209b8cb |
@@ -222,7 +222,7 @@ public final class Collectors {
|
||||
* {@code Collection}, in encounter order
|
||||
*/
|
||||
public static <T, C extends Collection<T>>
|
||||
Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
|
||||
Collector<T, C, C> toCollection(Supplier<C> collectionFactory) {
|
||||
return new CollectorImpl<>(collectionFactory, Collection::add,
|
||||
(r1, r2) -> { r1.addAll(r2); return r1; },
|
||||
CH_ID);
|
||||
@@ -239,10 +239,10 @@ public final class Collectors {
|
||||
* {@code List}, in encounter order
|
||||
*/
|
||||
public static <T>
|
||||
Collector<T, ?, List<T>> toList() {
|
||||
Collector<T, ArrayList<Object>, List<T>> toList() {
|
||||
return new CollectorImpl<>(ArrayList::new, List::add,
|
||||
(left, right) -> { left.addAll(right); return left; },
|
||||
CH_ID);
|
||||
(left, right) -> { left.addAll(right); return left; },
|
||||
CH_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,7 +257,7 @@ public final class Collectors {
|
||||
* @since 10
|
||||
*/
|
||||
public static <T>
|
||||
Collector<T, ?, List<T>> toUnmodifiableList() {
|
||||
Collector<T, ArrayList<Object>, List<T>> toUnmodifiableList() {
|
||||
return new CollectorImpl<>(ArrayList::new, List::add,
|
||||
(left, right) -> { left.addAll(right); return left; },
|
||||
list -> {
|
||||
@@ -286,7 +286,7 @@ public final class Collectors {
|
||||
* {@code Set}
|
||||
*/
|
||||
public static <T>
|
||||
Collector<T, ?, Set<T>> toSet() {
|
||||
Collector<T, HashSet<Object>, Set<T>> toSet() {
|
||||
return new CollectorImpl<>(HashSet::new, Set::add,
|
||||
(left, right) -> {
|
||||
if (left.size() < right.size()) {
|
||||
@@ -315,7 +315,7 @@ public final class Collectors {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T>
|
||||
Collector<T, ?, Set<T>> toUnmodifiableSet() {
|
||||
Collector<T, HashSet<Object>, Set<T>> toUnmodifiableSet() {
|
||||
return new CollectorImpl<>(HashSet::new, Set::add,
|
||||
(left, right) -> {
|
||||
if (left.size() < right.size()) {
|
||||
@@ -335,7 +335,7 @@ public final class Collectors {
|
||||
* @return a {@code Collector} that concatenates the input elements into a
|
||||
* {@code String}, in encounter order
|
||||
*/
|
||||
public static Collector<CharSequence, ?, String> joining() {
|
||||
public static Collector<CharSequence, StringBuilder, String> joining() {
|
||||
return new CollectorImpl<>(
|
||||
StringBuilder::new, StringBuilder::append,
|
||||
(r1, r2) -> {
|
||||
@@ -353,7 +353,7 @@ public final class Collectors {
|
||||
* @return A {@code Collector} which concatenates CharSequence elements,
|
||||
* separated by the specified delimiter, in encounter order
|
||||
*/
|
||||
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
|
||||
public static Collector<CharSequence, StringJoiner, String> joining(CharSequence delimiter) {
|
||||
return joining(delimiter, "", "");
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ public final class Collectors {
|
||||
* @return A {@code Collector} which concatenates CharSequence elements,
|
||||
* separated by the specified delimiter, in encounter order
|
||||
*/
|
||||
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
|
||||
public static Collector<CharSequence, StringJoiner, String> joining(CharSequence delimiter,
|
||||
CharSequence prefix,
|
||||
CharSequence suffix) {
|
||||
return new CollectorImpl<>(
|
||||
@@ -428,7 +428,7 @@ public final class Collectors {
|
||||
* elements and provides the mapped results to the downstream collector
|
||||
*/
|
||||
public static <T, U, A, R>
|
||||
Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
|
||||
Collector<T, A, R> mapping(Function<? super T, ? extends U> mapper,
|
||||
Collector<? super U, A, R> downstream) {
|
||||
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
|
||||
return new CollectorImpl<>(downstream.supplier(),
|
||||
@@ -473,7 +473,7 @@ public final class Collectors {
|
||||
* @since 9
|
||||
*/
|
||||
public static <T, U, A, R>
|
||||
Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
|
||||
Collector<T, A, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
|
||||
Collector<? super U, A, R> downstream) {
|
||||
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
|
||||
return new CollectorImpl<>(downstream.supplier(),
|
||||
@@ -523,7 +523,7 @@ public final class Collectors {
|
||||
* @since 9
|
||||
*/
|
||||
public static <T, A, R>
|
||||
Collector<T, ?, R> filtering(Predicate<? super T> predicate,
|
||||
Collector<T, A, R> filtering(Predicate<? super T> predicate,
|
||||
Collector<? super T, A, R> downstream) {
|
||||
BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
|
||||
return new CollectorImpl<>(downstream.supplier(),
|
||||
@@ -588,7 +588,7 @@ public final class Collectors {
|
||||
* @param <T> the type of the input elements
|
||||
* @return a {@code Collector} that counts the input elements
|
||||
*/
|
||||
public static <T> Collector<T, ?, Long>
|
||||
public static <T> Collector<T, long[], Long>
|
||||
counting() {
|
||||
return summingLong(e -> 1L);
|
||||
}
|
||||
@@ -640,7 +640,7 @@ public final class Collectors {
|
||||
* @param mapper a function extracting the property to be summed
|
||||
* @return a {@code Collector} that produces the sum of a derived property
|
||||
*/
|
||||
public static <T> Collector<T, ?, Integer>
|
||||
public static <T> Collector<T, int[], Integer>
|
||||
summingInt(ToIntFunction<? super T> mapper) {
|
||||
return new CollectorImpl<>(
|
||||
() -> new int[1],
|
||||
@@ -658,7 +658,7 @@ public final class Collectors {
|
||||
* @param mapper a function extracting the property to be summed
|
||||
* @return a {@code Collector} that produces the sum of a derived property
|
||||
*/
|
||||
public static <T> Collector<T, ?, Long>
|
||||
public static <T> Collector<T, long[], Long>
|
||||
summingLong(ToLongFunction<? super T> mapper) {
|
||||
return new CollectorImpl<>(
|
||||
() -> new long[1],
|
||||
@@ -683,7 +683,7 @@ public final class Collectors {
|
||||
* @param mapper a function extracting the property to be summed
|
||||
* @return a {@code Collector} that produces the sum of a derived property
|
||||
*/
|
||||
public static <T> Collector<T, ?, Double>
|
||||
public static <T> Collector<T, double[], Double>
|
||||
summingDouble(ToDoubleFunction<? super T> mapper) {
|
||||
/*
|
||||
* In the arrays allocated for the collect operation, index 0
|
||||
@@ -751,7 +751,7 @@ public final class Collectors {
|
||||
* @return a {@code Collector} that produces the arithmetic mean of a
|
||||
* derived property
|
||||
*/
|
||||
public static <T> Collector<T, ?, Double>
|
||||
public static <T> Collector<T, long[], Double>
|
||||
averagingInt(ToIntFunction<? super T> mapper) {
|
||||
return new CollectorImpl<>(
|
||||
() -> new long[2],
|
||||
@@ -770,7 +770,7 @@ public final class Collectors {
|
||||
* @return a {@code Collector} that produces the arithmetic mean of a
|
||||
* derived property
|
||||
*/
|
||||
public static <T> Collector<T, ?, Double>
|
||||
public static <T> Collector<T, long[], Double>
|
||||
averagingLong(ToLongFunction<? super T> mapper) {
|
||||
return new CollectorImpl<>(
|
||||
() -> new long[2],
|
||||
@@ -802,7 +802,7 @@ public final class Collectors {
|
||||
* @return a {@code Collector} that produces the arithmetic mean of a
|
||||
* derived property
|
||||
*/
|
||||
public static <T> Collector<T, ?, Double>
|
||||
public static <T> Collector<T, double[], Double>
|
||||
averagingDouble(ToDoubleFunction<? super T> mapper) {
|
||||
/*
|
||||
* In the arrays allocated for the collect operation, index 0
|
||||
@@ -844,7 +844,7 @@ public final class Collectors {
|
||||
* @see #reducing(BinaryOperator)
|
||||
* @see #reducing(Object, Function, BinaryOperator)
|
||||
*/
|
||||
public static <T> Collector<T, ?, T>
|
||||
public static <T> Collector<T, T[], T>
|
||||
reducing(T identity, BinaryOperator<T> op) {
|
||||
return new CollectorImpl<>(
|
||||
boxSupplier(identity),
|
||||
@@ -904,9 +904,8 @@ public final class Collectors {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new CollectorImpl<>(
|
||||
OptionalBox::new, OptionalBox::accept,
|
||||
OptionalBox::new, Consumer<T>::accept,
|
||||
(a, b) -> {
|
||||
if (b.present) a.accept(b.value);
|
||||
return a;
|
||||
@@ -952,7 +951,7 @@ public final class Collectors {
|
||||
* @see #reducing(BinaryOperator)
|
||||
*/
|
||||
public static <T, U>
|
||||
Collector<T, ?, U> reducing(U identity,
|
||||
Collector<T, U[], U> reducing(U identity,
|
||||
Function<? super T, ? extends U> mapper,
|
||||
BinaryOperator<U> op) {
|
||||
return new CollectorImpl<>(
|
||||
@@ -999,7 +998,7 @@ public final class Collectors {
|
||||
* @see #groupingBy(Function, Supplier, Collector)
|
||||
* @see #groupingByConcurrent(Function)
|
||||
*/
|
||||
public static <T, K> Collector<T, ?, Map<K, List<T>>>
|
||||
public static <T, K> Collector<T, Map<K,ArrayList<Object>>, Map<K, List<T>>>
|
||||
groupingBy(Function<? super T, ? extends K> classifier) {
|
||||
return groupingBy(classifier, toList());
|
||||
}
|
||||
@@ -1049,7 +1048,7 @@ public final class Collectors {
|
||||
* @see #groupingByConcurrent(Function, Collector)
|
||||
*/
|
||||
public static <T, K, A, D>
|
||||
Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
|
||||
Collector<T, Map<K,A>, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
|
||||
Collector<? super T, A, D> downstream) {
|
||||
return groupingBy(classifier, HashMap::new, downstream);
|
||||
}
|
||||
@@ -1102,7 +1101,7 @@ public final class Collectors {
|
||||
* @see #groupingByConcurrent(Function, Supplier, Collector)
|
||||
*/
|
||||
public static <T, K, D, A, M extends Map<K, D>>
|
||||
Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
|
||||
Collector<T, Map<K,A>, M> groupingBy(Function<? super T, ? extends K> classifier,
|
||||
Supplier<M> mapFactory,
|
||||
Collector<? super T, A, D> downstream) {
|
||||
Supplier<A> downstreamSupplier = downstream.supplier();
|
||||
@@ -1166,7 +1165,7 @@ public final class Collectors {
|
||||
* @see #groupingByConcurrent(Function, Supplier, Collector)
|
||||
*/
|
||||
public static <T, K>
|
||||
Collector<T, ?, ConcurrentMap<K, List<T>>>
|
||||
Collector<T, ConcurrentMap<K,ArrayList<Object>>, ConcurrentMap<K, List<T>>>
|
||||
groupingByConcurrent(Function<? super T, ? extends K> classifier) {
|
||||
return groupingByConcurrent(classifier, ConcurrentHashMap::new, toList());
|
||||
}
|
||||
@@ -1212,7 +1211,7 @@ public final class Collectors {
|
||||
* @see #groupingByConcurrent(Function, Supplier, Collector)
|
||||
*/
|
||||
public static <T, K, A, D>
|
||||
Collector<T, ?, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier,
|
||||
Collector<T, ConcurrentMap<K,A>, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier,
|
||||
Collector<? super T, A, D> downstream) {
|
||||
return groupingByConcurrent(classifier, ConcurrentHashMap::new, downstream);
|
||||
}
|
||||
@@ -1260,7 +1259,7 @@ public final class Collectors {
|
||||
* @see #groupingBy(Function, Supplier, Collector)
|
||||
*/
|
||||
public static <T, K, A, D, M extends ConcurrentMap<K, D>>
|
||||
Collector<T, ?, M> groupingByConcurrent(Function<? super T, ? extends K> classifier,
|
||||
Collector<T, ConcurrentMap<K,A>, M> groupingByConcurrent(Function<? super T, ? extends K> classifier,
|
||||
Supplier<M> mapFactory,
|
||||
Collector<? super T, A, D> downstream) {
|
||||
Supplier<A> downstreamSupplier = downstream.supplier();
|
||||
@@ -1438,7 +1437,7 @@ public final class Collectors {
|
||||
* @see #toConcurrentMap(Function, Function)
|
||||
*/
|
||||
public static <T, K, U>
|
||||
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
|
||||
Collector<T, Map<K,U>, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
|
||||
Function<? super T, ? extends U> valueMapper) {
|
||||
return new CollectorImpl<>(HashMap::new,
|
||||
uniqKeysMapAccumulator(keyMapper, valueMapper),
|
||||
@@ -1476,7 +1475,7 @@ public final class Collectors {
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static <T, K, U>
|
||||
Collector<T, ?, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
|
||||
Collector<T, Map<K,U>, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
|
||||
Function<? super T, ? extends U> valueMapper) {
|
||||
Objects.requireNonNull(keyMapper, "keyMapper");
|
||||
Objects.requireNonNull(valueMapper, "valueMapper");
|
||||
@@ -1542,7 +1541,7 @@ public final class Collectors {
|
||||
* @see #toConcurrentMap(Function, Function, BinaryOperator)
|
||||
*/
|
||||
public static <T, K, U>
|
||||
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
|
||||
Collector<T, Map<K,U>, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
|
||||
Function<? super T, ? extends U> valueMapper,
|
||||
BinaryOperator<U> mergeFunction) {
|
||||
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
|
||||
@@ -1582,7 +1581,7 @@ public final class Collectors {
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static <T, K, U>
|
||||
Collector<T, ?, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
|
||||
Collector<T, Map<K,U>, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
|
||||
Function<? super T, ? extends U> valueMapper,
|
||||
BinaryOperator<U> mergeFunction) {
|
||||
Objects.requireNonNull(keyMapper, "keyMapper");
|
||||
@@ -1634,7 +1633,7 @@ public final class Collectors {
|
||||
* @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
|
||||
*/
|
||||
public static <T, K, U, M extends Map<K, U>>
|
||||
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
|
||||
Collector<T, M, M> toMap(Function<? super T, ? extends K> keyMapper,
|
||||
Function<? super T, ? extends U> valueMapper,
|
||||
BinaryOperator<U> mergeFunction,
|
||||
Supplier<M> mapFactory) {
|
||||
@@ -1697,7 +1696,7 @@ public final class Collectors {
|
||||
* @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
|
||||
*/
|
||||
public static <T, K, U>
|
||||
Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
|
||||
Collector<T, Map<K,U>, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
|
||||
Function<? super T, ? extends U> valueMapper) {
|
||||
return new CollectorImpl<>(ConcurrentHashMap::new,
|
||||
uniqKeysMapAccumulator(keyMapper, valueMapper),
|
||||
@@ -1798,7 +1797,7 @@ public final class Collectors {
|
||||
* @see #toMap(Function, Function, BinaryOperator, Supplier)
|
||||
*/
|
||||
public static <T, K, U, M extends ConcurrentMap<K, U>>
|
||||
Collector<T, ?, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
|
||||
Collector<T, M, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
|
||||
Function<? super T, ? extends U> valueMapper,
|
||||
BinaryOperator<U> mergeFunction,
|
||||
Supplier<M> mapFactory) {
|
||||
@@ -1821,7 +1820,7 @@ public final class Collectors {
|
||||
* @see #summarizingLong(ToLongFunction)
|
||||
*/
|
||||
public static <T>
|
||||
Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper) {
|
||||
Collector<T, IntSummaryStatistics, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper) {
|
||||
return new CollectorImpl<>(
|
||||
IntSummaryStatistics::new,
|
||||
(r, t) -> r.accept(mapper.applyAsInt(t)),
|
||||
@@ -1844,7 +1843,7 @@ public final class Collectors {
|
||||
* @see #summarizingInt(ToIntFunction)
|
||||
*/
|
||||
public static <T>
|
||||
Collector<T, ?, LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper) {
|
||||
Collector<T, LongSummaryStatistics, LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper) {
|
||||
return new CollectorImpl<>(
|
||||
LongSummaryStatistics::new,
|
||||
(r, t) -> r.accept(mapper.applyAsLong(t)),
|
||||
@@ -1867,7 +1866,7 @@ public final class Collectors {
|
||||
* @see #summarizingInt(ToIntFunction)
|
||||
*/
|
||||
public static <T>
|
||||
Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper) {
|
||||
Collector<T, DoubleSummaryStatistics, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper) {
|
||||
return new CollectorImpl<>(
|
||||
DoubleSummaryStatistics::new,
|
||||
(r, t) -> r.accept(mapper.applyAsDouble(t)),
|
||||
|
||||
@@ -61,4 +61,5 @@ public interface MethodInvocationTree extends ExpressionTree {
|
||||
* @return the arguments
|
||||
*/
|
||||
List<? extends ExpressionTree> getArguments();
|
||||
String getOwner();
|
||||
}
|
||||
|
||||
@@ -71,6 +71,15 @@ public interface VariableTree extends StatementTree {
|
||||
*/
|
||||
Tree getType();
|
||||
|
||||
/**
|
||||
* 0 - no generic
|
||||
* 1 - is a generic
|
||||
* 2 - contains a generic
|
||||
* 3 - contains a generic like List<List<X>>
|
||||
* @return
|
||||
*/
|
||||
int deepestGeneric();
|
||||
|
||||
/**
|
||||
* Returns the initializer for the variable, or {@code null} if none.
|
||||
* @return the initializer
|
||||
|
||||
@@ -201,7 +201,7 @@ public class BasicJavacTask extends JavacTask {
|
||||
PlatformDescription platformProvider = context.get(PlatformDescription.class);
|
||||
|
||||
//ANDI: Init our own plugin to count CC's
|
||||
initPlugin(new WildcardFinderPlugin());
|
||||
initPlugin(new WildcardFinderPlugin((s -> Log.instance(context).printRawLines(Log.WriterKind.NOTICE,s))));
|
||||
if (platformProvider != null) {
|
||||
for (PluginInfo<Plugin> pluginDesc : platformProvider.getPlugins()) {
|
||||
java.util.List<String> options =
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
package com.sun.tools.javac.api;
|
||||
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import com.sun.source.tree.*;
|
||||
import com.sun.source.util.*;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class WildcardFinderPlugin extends TreeScanner<Void, Void> implements Plugin, TaskListener {
|
||||
|
||||
private final Consumer<String> logger;
|
||||
|
||||
public WildcardFinderPlugin(Consumer<String> logger){
|
||||
|
||||
this.logger = logger;
|
||||
}
|
||||
@Override
|
||||
public void started(TaskEvent e) {
|
||||
TaskListener.super.started(e);
|
||||
@@ -31,16 +39,49 @@ public class WildcardFinderPlugin extends TreeScanner<Void, Void> implements Plu
|
||||
javacTask.addTaskListener(this);
|
||||
}
|
||||
|
||||
Boolean noIncompatibleMethods = true;
|
||||
String currentClassName = "";
|
||||
Boolean noIncompatibleFields = true;
|
||||
@Override
|
||||
public Void visitClass(ClassTree node, Void unused) {
|
||||
noIncompatibleMethods = true;
|
||||
noIncompatibleFields = true;
|
||||
try {
|
||||
currentClassName = currentPackage + "." + node.getSimpleName().toString();
|
||||
node.getMembers().forEach(typeDecl -> {
|
||||
if (typeDecl instanceof VariableTree) {
|
||||
logger.accept(preText + "Field Type: " + ((VariableTree) typeDecl).getType().toString());
|
||||
logger.accept(preText + "deepestGeneric: " + ((VariableTree) typeDecl).deepestGeneric());
|
||||
if (((VariableTree) typeDecl).deepestGeneric() >= 3) {
|
||||
logger.accept(preText + "Field not Wildcard compatible");
|
||||
noIncompatibleFields = false;
|
||||
}
|
||||
//logger.accept("deepestGeneric: " + ((VariableTree)((VariableTree) typeDecl).getType()).deepestGeneric());
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {}
|
||||
super.visitClass(node, unused); //Visit class afterwards check if incompatible Fields or Method calls are used:
|
||||
if(noIncompatibleMethods && noIncompatibleFields){
|
||||
logger.accept(preText + "Wildcard compatible class");
|
||||
}else{
|
||||
logger.accept(preText + "Wildcard incompatible class Reason: "
|
||||
+ (noIncompatibleMethods?"Field":(noIncompatibleFields?"Method":"Field,Method")));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String currentPackage = "";
|
||||
String currentSource = "";
|
||||
String currentClassContent = "";
|
||||
@Override
|
||||
public Void visitCompilationUnit(CompilationUnitTree node, Void unused) {
|
||||
//System.out.println(node.getSourceFile().getName());
|
||||
currentPackage = node.getPackageName()!=null?node.getPackageName().toString():"";
|
||||
currentSource = node.getSourceFile().getName();
|
||||
try {
|
||||
currentClassContent = String.valueOf(node.getSourceFile().getCharContent(true));
|
||||
} catch (IOException e) {
|
||||
|
||||
logger.accept(preText + "error5: " + e);
|
||||
}
|
||||
return super.visitCompilationUnit(node, unused);
|
||||
}
|
||||
@@ -55,10 +96,53 @@ public class WildcardFinderPlugin extends TreeScanner<Void, Void> implements Plu
|
||||
return count;
|
||||
}
|
||||
public static final String preText = "[ANDI] ";
|
||||
|
||||
@Override
|
||||
public Void visitMemberSelect(MemberSelectTree node, Void unused) {
|
||||
try {
|
||||
var type_field = node.getClass().getField("type");
|
||||
var pos_field = node.getClass().getField("pos");
|
||||
type_field.setAccessible(true);
|
||||
pos_field.setAccessible(true);
|
||||
//Some fields (or "members") do not have a type... TODO: fix this
|
||||
String typeText = type_field.get(node)!=null?type_field.get(node).toString():"";
|
||||
int methodPos = pos_field.getInt(node);
|
||||
if(typeText.contains("capture#")){ //we found a capture conversion
|
||||
//System.out.println(node.getClass().getMethod("getStartPosition").invoke(node));
|
||||
logger.accept(preText + "Field-CC: " + typeText + " in " + currentSource + " " + lineOfPosition(currentClassContent,methodPos));
|
||||
var expr = node.getExpression();
|
||||
var expr_type_field = node.getClass().getField("type");
|
||||
expr_type_field.setAccessible(true);
|
||||
String exprTypeText = expr_type_field.get(expr).toString();
|
||||
if(exprTypeText.contains("capture") || exprTypeText.contains("?")){
|
||||
logger.accept(preText + "Field-CC!: " + typeText + " in " + currentSource + " " + lineOfPosition(currentClassContent,methodPos));
|
||||
}
|
||||
}else{
|
||||
logger.accept(preText + "normal field access");
|
||||
}
|
||||
} catch (Throwable e){
|
||||
//System.out.println("Error in method invocation: " + e.getMessage()+
|
||||
// " in "+currentSource);
|
||||
logger.accept(preText + "error4: " + e);
|
||||
}
|
||||
return super.visitMemberSelect(node, unused);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitMethodInvocation(MethodInvocationTree node, Void unused) {
|
||||
var args = node.getArguments();
|
||||
String methString = "";
|
||||
try{
|
||||
var meth_field = node.getClass().getField("meth");
|
||||
meth_field.setAccessible(true);
|
||||
var meth = meth_field.get(node);
|
||||
var sym_field = meth.getClass().getField("sym");
|
||||
sym_field.setAccessible(true);
|
||||
methString = sym_field.get(meth).toString();
|
||||
//System.out.println(methString);
|
||||
}catch (Throwable e){}
|
||||
try {
|
||||
int argumentNumber = 0;
|
||||
for(var arg : args){
|
||||
var type_field = arg.getClass().getField("type");
|
||||
var pos_field = arg.getClass().getField("pos");
|
||||
@@ -66,20 +150,32 @@ public class WildcardFinderPlugin extends TreeScanner<Void, Void> implements Plu
|
||||
pos_field.setAccessible(true);
|
||||
String typeText = type_field.get(arg).toString();
|
||||
int methodPos = pos_field.getInt(node);
|
||||
if(typeText.contains("capture#")){ //we found a capture conversion
|
||||
if(typeText.contains("capture#") && methString.startsWith("<")){ //we found a capture conversion
|
||||
//System.out.println(node.getClass().getMethod("getStartPosition").invoke(node));
|
||||
System.out.println(preText + "CC: " + typeText + " in " + currentSource + " " + lineOfPosition(currentClassContent,methodPos));
|
||||
logger.accept(preText + "CC!: "+ "Arg#"+argumentNumber + ": " + typeText + " in " + currentSource + " " + lineOfPosition(currentClassContent,methodPos) + " of method " + methString);
|
||||
logger.accept(preText + " in class:" + node.getOwner());
|
||||
String ownerName = node.getOwner();
|
||||
if(ownerName.equals(currentClassName)){
|
||||
logger.accept(preText + " in same class");
|
||||
}
|
||||
noIncompatibleMethods = false;
|
||||
}else if(typeText.contains("capture#")) {
|
||||
logger.accept(preText + "CC: "+ "Arg#"+argumentNumber + ": " + typeText + " in " + currentSource + " " + lineOfPosition(currentClassContent,methodPos) + " of method " + methString);
|
||||
}else{
|
||||
System.out.println(preText + "normal Method call");
|
||||
logger.accept(preText + "normal Method call");
|
||||
}
|
||||
argumentNumber++;
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
//System.out.println("Argument has no 'type' field");
|
||||
logger.accept(preText + "error1: " + e);
|
||||
} catch (IllegalAccessException e) {
|
||||
//System.out.println("Illegal access of 'type' field");
|
||||
logger.accept(preText + "error2: " + e);
|
||||
} catch (Throwable e){
|
||||
//System.out.println("Error in method invocation: " + e.getMessage()+
|
||||
// " in "+currentSource);
|
||||
logger.accept(preText + "error3: " + e);
|
||||
}
|
||||
return super.visitMethodInvocation(node, unused);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,9 @@ import static com.sun.tools.javac.code.TypeTag.*;
|
||||
*/
|
||||
public abstract class Type extends AnnoConstruct implements TypeMirror, PoolConstant {
|
||||
|
||||
public int deepestGeneric(){
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Type metadata, Should be {@code null} for the default value.
|
||||
*
|
||||
@@ -898,6 +901,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deepestGeneric() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeTag getTag() {
|
||||
return WILDCARD;
|
||||
@@ -1031,6 +1039,12 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
||||
this.interfaces_field = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deepestGeneric() {
|
||||
int deepest = typarams_field.stream().mapToInt(t -> t.deepestGeneric()).max().orElse(0);
|
||||
return deepest>0?1 + deepest:0;
|
||||
}
|
||||
|
||||
public int poolTag() {
|
||||
return ClassFile.CONSTANT_Class;
|
||||
}
|
||||
@@ -1354,6 +1368,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
||||
this(that.elemtype, that.tsym, that.getMetadata());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deepestGeneric() {
|
||||
return elemtype.deepestGeneric();
|
||||
}
|
||||
|
||||
public int poolTag() {
|
||||
return ClassFile.CONSTANT_Class;
|
||||
}
|
||||
@@ -1699,6 +1718,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deepestGeneric() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeTag getTag() {
|
||||
return TYPEVAR;
|
||||
|
||||
@@ -295,7 +295,7 @@ public class Arguments {
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
public boolean handleReleaseOptions(Predicate<Iterable<String>> additionalOptions) {
|
||||
String platformString = options.get(Option.RELEASE);
|
||||
String platformString = options.get("24");
|
||||
|
||||
checkOptionAllowed(platformString == null,
|
||||
option -> reportDiag(Errors.ReleaseBootclasspathConflict(option)),
|
||||
|
||||
@@ -758,6 +758,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
}
|
||||
|
||||
public abstract static class JCExpression extends JCTree implements ExpressionTree {
|
||||
|
||||
public String getOwner() {
|
||||
return "Not implemented";
|
||||
}
|
||||
@Override
|
||||
public JCExpression setType(Type type) {
|
||||
super.setType(type);
|
||||
@@ -768,7 +772,6 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
super.setPos(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isPoly() { return false; }
|
||||
public boolean isStandalone() { return true; }
|
||||
|
||||
@@ -1076,6 +1079,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public JCExpression getNameExpression() { return nameexpr; }
|
||||
@DefinedBy(Api.COMPILER_TREE)
|
||||
public JCTree getType() { return vartype; }
|
||||
public int deepestGeneric(){
|
||||
return type.deepestGeneric();
|
||||
}
|
||||
@DefinedBy(Api.COMPILER_TREE)
|
||||
public JCExpression getInitializer() {
|
||||
return init;
|
||||
@@ -1872,6 +1878,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public List<JCExpression> getArguments() {
|
||||
return args;
|
||||
}
|
||||
public String getOwner(){
|
||||
return meth.getOwner();
|
||||
}
|
||||
@Override @DefinedBy(Api.COMPILER_TREE)
|
||||
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
||||
return v.visitMethodInvocation(this, d);
|
||||
@@ -2590,6 +2599,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public Tag getTag() {
|
||||
return SELECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOwner() {
|
||||
return sym.owner.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2722,6 +2736,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public Tag getTag() {
|
||||
return IDENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOwner() {
|
||||
return sym.owner.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -341,15 +341,15 @@ public class ToolOptions {
|
||||
new ToolOption("--release", STANDARD, true) {
|
||||
@Override
|
||||
public void process(String arg) throws InvalidValueException {
|
||||
processCompilerOption(Option.RELEASE, primaryName, arg);
|
||||
processCompilerOption(Option.RELEASE, primaryName, "24");
|
||||
}
|
||||
},
|
||||
|
||||
new ToolOption("--source -source", STANDARD, true) {
|
||||
@Override
|
||||
public void process(String arg) throws InvalidValueException {
|
||||
processCompilerOption(Option.SOURCE, primaryName, arg);
|
||||
processCompilerOption(Option.TARGET, Option.TARGET.primaryName, arg);
|
||||
//processCompilerOption(Option.SOURCE, primaryName, arg);
|
||||
//processCompilerOption(Option.TARGET, Option.TARGET.primaryName, arg);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user