Compare commits

...

7 Commits

7 changed files with 127 additions and 30 deletions

View File

@@ -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),
@@ -998,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());
}
@@ -1048,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);
}
@@ -1165,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());
}
@@ -1211,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);
}
@@ -1475,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");
@@ -1541,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);
@@ -1581,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");
@@ -1633,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) {
@@ -1696,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),
@@ -1797,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) {
@@ -1820,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)),
@@ -1843,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)),
@@ -1866,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)),

View File

@@ -61,4 +61,5 @@ public interface MethodInvocationTree extends ExpressionTree {
* @return the arguments
*/
List<? extends ExpressionTree> getArguments();
String getOwner();
}

View File

@@ -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

View File

@@ -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((s -> Log.instance(context).printRawLines(s))));
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 =

View File

@@ -1,10 +1,9 @@
package com.sun.tools.javac.api;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.MemberSelectTree;
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;
@@ -13,6 +12,7 @@ public class WildcardFinderPlugin extends TreeScanner<Void, Void> implements Plu
private final Consumer<String> logger;
public WildcardFinderPlugin(Consumer<String> logger){
this.logger = logger;
}
@Override
@@ -39,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);
}
@@ -71,7 +104,8 @@ public class WildcardFinderPlugin extends TreeScanner<Void, Void> implements Plu
var pos_field = node.getClass().getField("pos");
type_field.setAccessible(true);
pos_field.setAccessible(true);
String typeText = type_field.get(node).toString();
//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));
@@ -88,7 +122,8 @@ public class WildcardFinderPlugin extends TreeScanner<Void, Void> implements Plu
}
} catch (Throwable e){
//System.out.println("Error in method invocation: " + e.getMessage()+
// " in "+currentSource);i
// " in "+currentSource);
logger.accept(preText + "error4: " + e);
}
return super.visitMemberSelect(node, unused);
}
@@ -118,6 +153,12 @@ public class WildcardFinderPlugin extends TreeScanner<Void, Void> implements Plu
if(typeText.contains("capture#") && methString.startsWith("<")){ //we found a capture conversion
//System.out.println(node.getClass().getMethod("getStartPosition").invoke(node));
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{
@@ -127,11 +168,14 @@ public class WildcardFinderPlugin extends TreeScanner<Void, Void> implements Plu
}
} 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);
}

View File

@@ -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;

View File

@@ -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();
}
}
/**