Simplify impl

This commit is contained in:
Clément Fournier committed 2022-11-28 15:49:53 +01:00
1 parent a85e5c867d
commit bf6e64a1e1
17 files changed
+95 -103

No files matched your search

@@ -6,10 +6,8 @@ package net.sourceforge.pmd.util;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyIterator;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
import static java.util.Collections.singletonList;
import java.util.ArrayList;
import java.util.Collection;
@@ -36,8 +34,10 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.Validate;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.pcollections.ConsPStack;
import org.pcollections.HashTreePSet;
import org.pcollections.PMap;
import org.pcollections.PSequence;
import org.pcollections.PSet;
import net.sourceforge.pmd.annotation.InternalApi;
@@ -323,6 +323,26 @@ public final class CollectionUtil {
return newM;
}
/**
* Produce a new list with the elements of the first, and one additional
* item. The returned list is immutable.
*/
public static <V> List<V> plus(List<V> list, V v) {
if (list instanceof PSequence) {
return ((PSequence<V>) list).plus(v);
} else if (list.isEmpty()) {
return ConsPStack.singleton(v);
}
return ConsPStack.from(list).plus(v);
}
/** Returns the empty list. */
public static <V> List<V> emptyList() {
// We use this implementation so that it plays well with other
// operations that expect immutable data.
return ConsPStack.empty();
}
/**
* Returns an unmodifiable set containing the set union of the collection,
* and the new elements.
@@ -461,7 +481,7 @@ public final class CollectionUtil {
if (!from.hasNext()) {
return emptyList();
} else if (sizeHint == 1) {
return Collections.singletonList(f.apply(from.next()));
return ConsPStack.singleton(f.apply(from.next()));
}
List<R> res = sizeHint == UNKNOWN_SIZE ? new ArrayList<>() : new ArrayList<>(sizeHint);
while (from.hasNext()) {
@@ -592,7 +612,7 @@ public final class CollectionUtil {
public static <T> List<T> listOfNotNull(T t) {
return t == null ? emptyList() : singletonList(t);
return t == null ? emptyList() : ConsPStack.singleton(t);
}
/**
@@ -641,12 +661,15 @@ public final class CollectionUtil {
* @param <T> Type of items
*/
public static <T> List<T> defensiveUnmodifiableCopy(List<? extends T> list) {
if (list.isEmpty()) {
return emptyList();
} else if (list.size() == 1) {
return singletonList(list.get(0));
if (list instanceof PSequence) {
return (List<T>) list; // is already immutable
}
return Collections.unmodifiableList(new ArrayList<>(list));
if (list.isEmpty()) {
return ConsPStack.empty();
} else if (list.size() == 1) {
return ConsPStack.singleton(list.get(0));
}
return ConsPStack.from(list);
}
public static <T> Set<T> defensiveUnmodifiableCopyToSet(Collection<? extends T> list) {
@@ -6,10 +6,9 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.objectweb.asm.TypePath;
@@ -70,70 +69,37 @@ class LazyTypeSig {
static final class TypeAnnotationSet {
private final Map<ComparableTypePath, List<SymAnnot>> pathAndAnnot = new HashMap<>();
private final List<Pair<TypePath, SymAnnot>> pathAndAnnot = new ArrayList<>();
void add(TypePath path, SymAnnot annot) {
pathAndAnnot.computeIfAbsent(new ComparableTypePath(path), k -> new ArrayList<>(1)).add(annot);
}
/** TypePath does not implement equals or hashcode so we wrap it. */
static class ComparableTypePath {
String toString;
final TypePath path;
ComparableTypePath(@Nullable TypePath path) {
this.path = path;
}
@Override
public String toString() {
if (toString == null) {
toString = path == null ? "" : path.toString();
}
return toString;
}
@Override
public boolean equals(Object obj) {
return obj instanceof ComparableTypePath && obj.toString().equals(this.toString());
}
@Override
public int hashCode() {
return toString().hashCode();
}
pathAndAnnot.add(Pair.of(path, annot));
}
/**
* Transform the given type to apply type annotations. Returns
* the type decorated with type annotations in the right places.
*/
JTypeMirror decorate(JTypeMirror base) {
for (Map.Entry<ComparableTypePath, List<SymAnnot>> pair : pathAndAnnot.entrySet()) {
TypePath path = pair.getKey().path;
for (Pair<TypePath, SymAnnot> pair : pathAndAnnot) {
TypePath path = pair.getKey();
base = resolvePath(base, path, pair.getValue());
base = resolvePathStep(base, path, 0, pair.getValue());
}
return base;
}
private JTypeMirror resolvePath(JTypeMirror t, @Nullable TypePath path, List<SymAnnot> annot) {
private static JTypeMirror resolvePathStep(JTypeMirror t, @Nullable TypePath path, int i, SymAnnot annot) {
if (t instanceof JClassType && ((JClassType) t).getEnclosingType() != null) {
return handleEnclosingType((JClassType) t, path, 0, annot);
return handleEnclosingType((JClassType) t, path, i, annot);
}
return resolvePathStep(t, path, 0, annot);
return resolvePathStepNoInner(t, path, i, annot);
}
private static JTypeMirror resolvePathStep(JTypeMirror t, @Nullable TypePath path, int i, List<SymAnnot> annots) {
if (t instanceof JClassType && ((JClassType) t).getEnclosingType() != null) {
return handleEnclosingType((JClassType) t, path, i, annots);
}
return resolvePathStepNoInner(t, path, i, annots);
}
private static JTypeMirror resolvePathStepNoInner(JTypeMirror t, @Nullable TypePath path, int i, List<SymAnnot> annots) {
private static JTypeMirror resolvePathStepNoInner(JTypeMirror t, @Nullable TypePath path, int i, SymAnnot annot) {
assert path == null || path.getStep(i) != TypePath.INNER_TYPE;
if (path == null || i == path.getLength()) {
return t.withAnnotations(annots);
return t.addAnnotation(annot);
}
switch (path.getStep(i)) {
@@ -141,7 +107,7 @@ class LazyTypeSig {
if (t instanceof JClassType) {
int typeArgIndex = path.getStepArgument(i);
JTypeMirror arg = ((JClassType) t).getTypeArgs().get(typeArgIndex);
JTypeMirror newArg = resolvePathStep(arg, path, i + 1, annots);
JTypeMirror newArg = resolvePathStep(arg, path, i + 1, annot);
List<JTypeMirror> newArgs = replaceAtIndex(((JClassType) t).getTypeArgs(), typeArgIndex, newArg);
return ((JClassType) t).withTypeArguments(newArgs);
}
@@ -149,7 +115,7 @@ class LazyTypeSig {
case TypePath.ARRAY_ELEMENT:
if (t instanceof JArrayType) {
JTypeMirror component = ((JArrayType) t).getComponentType();
JTypeMirror newComponent = resolvePathStep(component, path, i + 1, annots);
JTypeMirror newComponent = resolvePathStep(component, path, i + 1, annot);
return t.getTypeSystem().arrayType(newComponent).withAnnotations(t.getTypeAnnotations());
}
throw new IllegalArgumentException("Expected array type: " + t);
@@ -158,7 +124,7 @@ class LazyTypeSig {
case TypePath.WILDCARD_BOUND:
if (t instanceof JWildcardType) {
JWildcardType wild = (JWildcardType) t;
JTypeMirror newBound = resolvePathStep(wild.getBound(), path, i + 1, annots);
JTypeMirror newBound = resolvePathStep(wild.getBound(), path, i + 1, annot);
return wild.getTypeSystem().wildcard(wild.isUpperBound(), newBound).withAnnotations(wild.getTypeAnnotations());
}
throw new IllegalArgumentException("Expected wilcard type: " + t);
@@ -167,7 +133,7 @@ class LazyTypeSig {
}
}
private static JClassType handleEnclosingType(JClassType t, @Nullable TypePath path, int i, List<SymAnnot> annots) {
private static JClassType handleEnclosingType(JClassType t, @Nullable TypePath path, int i, SymAnnot annot) {
// We need to resolve the inner types left to right as given in the path.
// Because JClassType is left-recursive its structure does not match the
// structure of the path.
@@ -183,8 +149,7 @@ class LazyTypeSig {
selectedT = enclosingTypes.get(selectedTypeIndex);
// interpret the rest of the path as with this type as context
JClassType rebuiltType = (JClassType) resolvePathStepNoInner(selectedT, path,
i + selectionDepth, annots);
JClassType rebuiltType = (JClassType) resolvePathStepNoInner(selectedT, path, i + selectionDepth, annot);
// Then, we may need to rebuild the type by adding the remaining segments.
for (int j = selectedTypeIndex - 1; j >= 0; j--) {
JClassType nextInner = enclosingTypes.get(j);
@@ -102,6 +102,6 @@ final class SymbolicAnnotationImpl implements SymAnnot {
@Override
public String toString() {
return "@" + typeStub + explicitAttrs;
return "@" + typeStub.getCanonicalName() + explicitAttrs;
}
}
@@ -31,15 +31,15 @@ final class BoxedPrimitive extends ClassTypeImpl {
}
@Override
public JClassType withAnnotations(List<SymAnnot> symAnnots) {
if (symAnnots.equals(this.getTypeAnnotations())) {
public JClassType withAnnotations(List<SymAnnot> newTypeAnnots) {
if (newTypeAnnots.equals(this.getTypeAnnotations())) {
return this;
}
return new BoxedPrimitive(
getTypeSystem(),
this.getSymbol(),
this.unboxed,
symAnnots
newTypeAnnots
);
}
@@ -38,7 +38,7 @@ final class CaptureMatcher implements JTypeVar {
}
@Override
public JTypeMirror withAnnotations(List<SymAnnot> symAnnots) {
public JTypeMirror withAnnotations(List<SymAnnot> newTypeAnnots) {
throw new UnsupportedOperationException("this is a test only object which should only be used for equals");
}
@@ -4,10 +4,10 @@
package net.sourceforge.pmd.lang.java.types;
import static net.sourceforge.pmd.util.CollectionUtil.emptyList;
import static net.sourceforge.pmd.util.CollectionUtil.map;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
@@ -104,11 +104,11 @@ class ClassTypeImpl implements JClassType {
}
@Override
public JClassType withAnnotations(List<SymAnnot> symAnnots) {
if (symAnnots.isEmpty() && this.typeAnnotations.isEmpty()) {
public JClassType withAnnotations(List<SymAnnot> newTypeAnnots) {
if (newTypeAnnots.isEmpty() && this.typeAnnotations.isEmpty()) {
return this;
}
return new ClassTypeImpl(ts, enclosingType, symbol, typeArgs, CollectionUtil.defensiveUnmodifiableCopy(symAnnots), isDecl);
return new ClassTypeImpl(ts, enclosingType, symbol, typeArgs, CollectionUtil.defensiveUnmodifiableCopy(newTypeAnnots), isDecl);
}
@Override
@@ -258,9 +258,9 @@ class ClassTypeImpl implements JClassType {
private JClassType getDeclaredClass(JClassSymbol inner) {
if (Modifier.isStatic(inner.getModifiers())) {
return new ClassTypeImpl(ts, null, inner, Collections.emptyList(), typeAnnotations, true);
return new ClassTypeImpl(ts, null, inner, emptyList(), typeAnnotations, true);
} else {
return selectInner(inner, Collections.emptyList());
return selectInner(inner, emptyList());
}
}
@@ -278,9 +278,9 @@ class ClassTypeImpl implements JClassType {
JClassSymbol declaredClass = symbol.getDeclaredClass(simpleName);
if (declaredClass != null) {
if (Modifier.isStatic(declaredClass.getModifiers())) {
return new ClassTypeImpl(ts, null, declaredClass, Collections.emptyList(), Collections.emptyList(), true);
return new ClassTypeImpl(ts, null, declaredClass, emptyList(), emptyList(), true);
} else {
return selectInner(declaredClass, Collections.emptyList());
return selectInner(declaredClass, emptyList());
}
}
return null;
@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.java.types;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -31,7 +30,7 @@ public final class JArrayType implements JTypeMirror {
private JClassSymbol symbol;
JArrayType(TypeSystem ts, JTypeMirror component) {
this(ts, component, null, Collections.emptyList());
this(ts, component, null, CollectionUtil.emptyList());
}
JArrayType(TypeSystem ts, JTypeMirror component, JClassSymbol arraySymbol, List<SymAnnot> typeAnnots) {
@@ -66,11 +65,11 @@ public final class JArrayType implements JTypeMirror {
}
@Override
public JTypeMirror withAnnotations(List<SymAnnot> symAnnots) {
if (symAnnots.equals(typeAnnots)) {
public JArrayType withAnnotations(List<SymAnnot> newTypeAnnots) {
if (newTypeAnnots.isEmpty() && this.typeAnnots.isEmpty()) {
return this;
}
return new JArrayType(ts, component, symbol, CollectionUtil.defensiveUnmodifiableCopy(symAnnots));
return new JArrayType(ts, component, symbol, CollectionUtil.defensiveUnmodifiableCopy(newTypeAnnots));
}
@Override
@@ -153,7 +152,7 @@ public final class JArrayType implements JTypeMirror {
public JArrayType subst(Function<? super SubstVar, ? extends @NonNull JTypeMirror> subst) {
JTypeMirror newComp = getComponentType().subst(subst);
return newComp == component ? this // NOPMD UseEqualsToCompareObjectReferences
: getTypeSystem().arrayType(newComp);
: getTypeSystem().arrayType(newComp).withAnnotations(getTypeAnnotations());
}
@Override
@@ -56,7 +56,7 @@ public interface JClassType extends JTypeMirror {
@Override
JClassType withAnnotations(List<SymAnnot> symAnnots);
JClassType withAnnotations(List<SymAnnot> newTypeAnnots);
@Override
default JClassType subst(Function<? super SubstVar, ? extends @NonNull JTypeMirror> fun) {
@@ -66,11 +66,11 @@ public final class JIntersectionType implements JTypeMirror {
}
@Override
public JTypeMirror withAnnotations(List<SymAnnot> symAnnots) {
public JTypeMirror withAnnotations(List<SymAnnot> newTypeAnnots) {
return new JIntersectionType(
ts,
primaryBound.withAnnotations(symAnnots),
CollectionUtil.map(components, c -> c.withAnnotations(symAnnots))
primaryBound.withAnnotations(newTypeAnnots),
CollectionUtil.map(components, c -> c.withAnnotations(newTypeAnnots))
);
}
@@ -49,11 +49,11 @@ public final class JPrimitiveType implements JTypeMirror {
}
@Override
public JTypeMirror withAnnotations(List<SymAnnot> newAnnotations) {
if (newAnnotations.equals(this.typeAnnots)) {
public JTypeMirror withAnnotations(List<SymAnnot> newTypeAnnots) {
if (newTypeAnnots.isEmpty() && this.typeAnnots.isEmpty()) {
return this;
}
return new JPrimitiveType(ts, kind, type, box.getSymbol(), CollectionUtil.defensiveUnmodifiableCopy(newAnnotations));
return new JPrimitiveType(ts, kind, type, box.getSymbol(), CollectionUtil.defensiveUnmodifiableCopy(newTypeAnnots));
}
@Override
@@ -25,6 +25,7 @@ import net.sourceforge.pmd.lang.java.symbols.SymbolicValue.SymAnnot;
import net.sourceforge.pmd.lang.java.types.JPrimitiveType.PrimitiveTypeKind;
import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility;
import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar;
import net.sourceforge.pmd.util.CollectionUtil;
/**
* Type mirrors represent Java types. They are created by a {@link TypeSystem}
@@ -83,7 +84,11 @@ public interface JTypeMirror extends JTypeVisitable {
TypeSystem getTypeSystem();
JTypeMirror withAnnotations(List<SymAnnot> symAnnots);
JTypeMirror withAnnotations(List<SymAnnot> newTypeAnnots);
default JTypeMirror addAnnotation(SymAnnot symAnnot) {
return withAnnotations(CollectionUtil.plus(getTypeAnnotations(), symAnnot));
}
/** Return a list of type annotations on this type. */
List<SymAnnot> getTypeAnnotations();
@@ -31,7 +31,7 @@ final class SentinelType implements JTypeMirror {
}
@Override
public JTypeMirror withAnnotations(List<SymAnnot> symAnnots) {
public JTypeMirror withAnnotations(List<SymAnnot> newTypeAnnots) {
return this;
}
@@ -4,7 +4,7 @@
package net.sourceforge.pmd.lang.java.types;
import static java.util.Collections.emptyList;
import static net.sourceforge.pmd.util.CollectionUtil.emptyList;
import static net.sourceforge.pmd.util.CollectionUtil.immutableSetOf;
import java.io.Serializable;
@@ -741,7 +741,7 @@ public final class TypeSystem {
}
@Override
public JTypeMirror withAnnotations(List<SymAnnot> symAnnots) {
public JTypeMirror withAnnotations(List<SymAnnot> newTypeAnnots) {
return this;
}
@@ -60,7 +60,7 @@ abstract class TypeVarImpl implements JTypeVar {
}
@Override
public JTypeMirror withAnnotations(List<SymAnnot> symAnnots) {
public JTypeMirror withAnnotations(List<SymAnnot> newTypeAnnots) {
return this;
}
@@ -171,7 +171,7 @@ abstract class TypeVarImpl implements JTypeVar {
}
@Override
public JTypeMirror withAnnotations(List<SymAnnot> symAnnots) {
public JTypeMirror withAnnotations(List<SymAnnot> newTypeAnnots) {
return this;
}
@@ -43,11 +43,11 @@ final class WildcardTypeImpl implements JWildcardType {
}
@Override
public JTypeMirror withAnnotations(List<SymAnnot> symAnnots) {
if (symAnnots.isEmpty() && !typeAnnots.isEmpty()) {
public JTypeMirror withAnnotations(List<SymAnnot> newTypeAnnots) {
if (newTypeAnnots.isEmpty() && !typeAnnots.isEmpty()) {
return ts.wildcard(isUpperBound, bound);
} else if (!symAnnots.isEmpty()) {
return new WildcardTypeImpl(ts, isUpperBound(), bound, CollectionUtil.defensiveUnmodifiableCopy(symAnnots));
} else if (!newTypeAnnots.isEmpty()) {
return new WildcardTypeImpl(ts, isUpperBound(), bound, CollectionUtil.defensiveUnmodifiableCopy(newTypeAnnots));
}
return this;
}
@@ -54,7 +54,7 @@ public final class InferenceVar implements JTypeMirror, SubstVar {
}
@Override
public JTypeMirror withAnnotations(List<SymAnnot> symAnnots) {
public JTypeMirror withAnnotations(List<SymAnnot> newTypeAnnots) {
return this;
}
@@ -83,7 +83,7 @@ public class TypeAnnotReflectionTest {
JArrayType t = (JArrayType) getFieldType(sym, "twoAnnotsOnOuterArrayDim");
assertHasTypeAnnots(t, emptyList());
assertThat(t.getComponentType(), Matchers.isA(JArrayType.class));
assertHasTypeAnnots(t.getComponentType(), listOf(new AnnotAImpl(), new AnnotBImpl()));
assertHasTypeAnnots(t.getComponentType(), listOf(new AnnotBImpl(), new AnnotAImpl()));
assertHasTypeAnnots(t.getElementType(), emptyList());
}
{
@@ -270,7 +270,7 @@ public class TypeAnnotReflectionTest {
private void assertHasTypeAnnots(JTypeMirror t, List<Annotation> annots) {
assertThat(t.getTypeAnnotations().toArray(), Matchers.array(annots.stream().map(this::matchesAnnot).toArray(Matcher[]::new)));
assertThat(t.getTypeAnnotations(), Matchers.hasItems(annots.stream().map(this::matchesAnnot).toArray(Matcher[]::new)));
}
static final class AnnotAImpl implements ClassWithTypeAnnotationsInside.A {