Add a test case
This commit is contained in:
9 files changed
+245
-202
No files matched your search
+1
@@ -62,6 +62,7 @@ class AstSymbolicAnnot implements SymbolicValue.SymAnnot {
|
||||
|
||||
@Override
|
||||
public boolean appliesToTypeUse() {
|
||||
// todo look into whether hardcoding Override is good for perf, as it's very frequent
|
||||
return node.getTypeMirror().getSymbol().annotationAppliesTo(ElementType.TYPE_USE);
|
||||
}
|
||||
|
||||
|
||||
@@ -117,19 +117,23 @@ public final class TypeOps {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean areSameTypes(List<JTypeMirror> ts, List<JTypeMirror> ss, boolean inInference) {
|
||||
return areSameTypes(ts, ss, EMPTY, inInference, false);
|
||||
public static boolean areSameTypes(List<JTypeMirror> ts, List<JTypeMirror> ss) {
|
||||
return areSameTypes(ts, ss, EMPTY, false, false);
|
||||
}
|
||||
|
||||
public static boolean areSameTypes(List<JTypeMirror> ts, List<JTypeMirror> ss, boolean inInference, boolean considerAnnotations) {
|
||||
public static boolean areSameTypesInInference(List<JTypeMirror> ts, List<JTypeMirror> ss) {
|
||||
return areSameTypes(ts, ss, EMPTY, true, false);
|
||||
}
|
||||
|
||||
private static boolean areSameTypes(List<JTypeMirror> ts, List<JTypeMirror> ss, boolean inInference, boolean considerAnnotations) {
|
||||
return areSameTypes(ts, ss, EMPTY, inInference, considerAnnotations);
|
||||
}
|
||||
|
||||
public static boolean areSameTypes(List<JTypeMirror> ts, List<JTypeMirror> ss, Substitution subst) {
|
||||
private static boolean areSameTypes(List<JTypeMirror> ts, List<JTypeMirror> ss, Substitution subst) {
|
||||
return areSameTypes(ts, ss, subst, false, false);
|
||||
}
|
||||
|
||||
public static boolean areSameTypes(List<JTypeMirror> ts, List<JTypeMirror> ss, Substitution subst, boolean inInference, boolean considerAnnotations) {
|
||||
private static boolean areSameTypes(List<JTypeMirror> ts, List<JTypeMirror> ss, Substitution subst, boolean inInference, boolean considerAnnotations) {
|
||||
if (ts.size() != ss.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -115,12 +115,15 @@ abstract class TypeVarImpl implements JTypeVar {
|
||||
|
||||
@Override
|
||||
public JTypeVar withAnnotations(PSet<SymAnnot> newTypeAnnots) {
|
||||
if (newTypeAnnots.isEmpty() && this.typeAnnots.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
return new RegularTypeVar(this, newTypeAnnots);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JTypeVar addAnnotation(@NonNull SymAnnot newAnnot) {
|
||||
return new RegularTypeVar(this, typeAnnots.plus(newAnnot));
|
||||
return withAnnotations(typeAnnots.plus(newAnnot));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
package net.sourceforge.pmd.lang.java.types.internal.infer;
|
||||
|
||||
import static net.sourceforge.pmd.lang.java.types.TypeConversion.capture;
|
||||
import static net.sourceforge.pmd.lang.java.types.TypeOps.areSameTypes;
|
||||
import static net.sourceforge.pmd.lang.java.types.TypeOps.areSameTypesInInference;
|
||||
import static net.sourceforge.pmd.lang.java.types.TypeOps.asClassType;
|
||||
import static net.sourceforge.pmd.lang.java.types.TypeOps.findFunctionalInterfaceMethod;
|
||||
import static net.sourceforge.pmd.lang.java.types.TypeOps.mentionsAny;
|
||||
@@ -539,7 +539,7 @@ final class ExprCheckHelper {
|
||||
// and the function type has parameter types G1, ..., Gn, then
|
||||
// i) for all i (1 ≤ i ≤ n), ‹Fi = Gi›
|
||||
if (lambda.isExplicitlyTyped()
|
||||
&& !areSameTypes(groundFun.getFormalParameters(), lambda.getExplicitParameterTypes(), true)) {
|
||||
&& !areSameTypesInInference(groundFun.getFormalParameters(), lambda.getExplicitParameterTypes())) {
|
||||
throw ResolutionFailedException.mismatchedLambdaParameters(infer.LOG, groundFun, lambda.getExplicitParameterTypes(), lambda);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,10 @@ public class JavaParsingHelper extends BaseParsingHelper<JavaParsingHelper, ASTC
|
||||
return new JavaParsingHelper(this.getParams(), this.semanticLogger, this.ts, logger);
|
||||
}
|
||||
|
||||
public JavaParsingHelper logTypeInferenceVerbose() {
|
||||
return logTypeInference(true, System.out);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull JavaParsingHelper clone(@NonNull Params params) {
|
||||
return new JavaParsingHelper(params, semanticLogger, ts, typeInfLogger);
|
||||
|
||||
@@ -15,6 +15,7 @@ import net.sourceforge.pmd.lang.ast.test.BaseTreeDumpTest;
|
||||
import net.sourceforge.pmd.lang.ast.test.RelevantAttributePrinter;
|
||||
import net.sourceforge.pmd.lang.java.JavaParsingHelper;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
|
||||
import net.sourceforge.pmd.lang.java.ast.InvocationNode;
|
||||
import net.sourceforge.pmd.lang.java.ast.TypeNode;
|
||||
@@ -71,6 +72,9 @@ class TypesTreeDumpTest extends BaseTreeDumpTest {
|
||||
if (node instanceof ASTVariableDeclaratorId) {
|
||||
result.add(new AttributeInfo("Name", ((ASTVariableDeclaratorId) node).getName()));
|
||||
}
|
||||
if (node instanceof ASTMethodDeclaration) {
|
||||
result.add(new AttributeInfo("Name", ((ASTMethodDeclaration) node).getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+39
@@ -726,4 +726,43 @@ class NodeStream<T> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
parserTest("f:inference of call within lambda fails") {
|
||||
|
||||
val (acu, spy) = parser.logTypeInferenceVerbose().parseWithTypeInferenceSpy("""
|
||||
|
||||
interface Iterator<Q> {}
|
||||
interface Function<U,V> {
|
||||
V apply(U u);
|
||||
}
|
||||
interface Iterable<Q> {
|
||||
Iterator<Q> iterator();
|
||||
}
|
||||
|
||||
class NodeStream {
|
||||
|
||||
public static <T, R> Iterable<R> mapIterator(Iterable<? extends T> iter, Function<? super Iterator<? extends T>, ? extends Iterator<R>> mapper) {
|
||||
return () -> mapper.apply(iter.iterator());
|
||||
}
|
||||
|
||||
}
|
||||
""")
|
||||
|
||||
val (t_Iterator, t_Function, t_Iterable) = acu.declaredTypeSignatures()
|
||||
val (lambda) = acu.descendants(ASTLambdaExpression::class.java).crossFindBoundaries().toList()
|
||||
val (_, _, _, _, tvar, rvar) = acu.typeVariables()
|
||||
|
||||
spy.shouldBeOk {
|
||||
lambda shouldHaveType t_Iterable[rvar]
|
||||
lambda.expressionBody!!.shouldBeA<ASTMethodCall> {
|
||||
it.methodType.shouldMatchMethod(
|
||||
named = "apply",
|
||||
withFormals = listOf(t_Iterator[`?` extends tvar])
|
||||
)
|
||||
it shouldHaveType t_Iterator[rvar]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
+6
-7
@@ -3,8 +3,8 @@
|
||||
*/
|
||||
|
||||
|
||||
package net.sourceforge.pmd.internal.util;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -30,10 +30,13 @@ public final class IteratorUtilCopy {
|
||||
private static final int MATCH_ALL = 1;
|
||||
private static final int MATCH_NONE = 2;
|
||||
|
||||
private IteratorUtil() {
|
||||
private IteratorUtilCopy() {
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface Nullable {}
|
||||
|
||||
public static <T> Iterator<T> takeWhile(Iterator<T> iter, Predicate<? super T> predicate) {
|
||||
return new AbstractIterator<T>() {
|
||||
@Override
|
||||
@@ -246,8 +249,6 @@ public final class IteratorUtilCopy {
|
||||
|
||||
|
||||
public static void advance(Iterator<?> iterator, int n) {
|
||||
AssertionUtil.requireNonNegative("n", n);
|
||||
|
||||
while (n > 0 && iterator.hasNext()) {
|
||||
iterator.next();
|
||||
n--;
|
||||
@@ -256,7 +257,6 @@ public final class IteratorUtilCopy {
|
||||
|
||||
|
||||
public static <T> Iterator<T> take(Iterator<? extends T> iterator, final int n) {
|
||||
AssertionUtil.requireNonNegative("n", n);
|
||||
if (n == 0) {
|
||||
return Collections.emptyIterator();
|
||||
}
|
||||
@@ -278,7 +278,6 @@ public final class IteratorUtilCopy {
|
||||
|
||||
|
||||
public static <T> Iterator<T> drop(Iterator<? extends T> source, final int n) {
|
||||
AssertionUtil.requireNonNegative("n", n);
|
||||
if (n == 0) {
|
||||
return (Iterator<T>) source;
|
||||
}
|
||||
|
||||
+176
-187
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user