Merge branch 'typeres-fix-inference-issue'

This commit is contained in:
Clément Fournier
2024-11-14 16:14:50 +01:00
4 changed files with 103 additions and 3 deletions
@@ -22,7 +22,7 @@ public class JavaLanguageProperties extends JvmLanguagePropertyBundle {
PropertyFactory.enumProperty("xTypeInferenceLogging",
EnumUtils.getEnumMap(InferenceLoggingVerbosity.class))
.desc("Verbosity of the type inference logging")
.defaultValue(InferenceLoggingVerbosity.DISABLED)
.defaultValue(InferenceLoggingVerbosity.VERBOSE)
.build();
@@ -525,6 +525,7 @@ final class InferenceContext {
* we try again to make progress.
*/
private boolean solve(VarWalkStrategy walker) {
graphWasChanged = false;
incorporate();
while (walker.hasNext()) {
@@ -22,6 +22,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import net.sourceforge.pmd.lang.java.ast.JavaNode;
import net.sourceforge.pmd.lang.java.internal.JavaLanguageProperties;
import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol;
import net.sourceforge.pmd.lang.java.types.JMethodSig;
import net.sourceforge.pmd.lang.java.types.JTypeMirror;
@@ -34,6 +35,12 @@ import net.sourceforge.pmd.util.StringUtil;
/**
* A strategy to log the execution traces of {@link Infer}.
* The default does nothing, so the logger calls can be optimized out
* at runtime, while not having to check that logging is enabled at the
* call sites.
*
* <p>To enable logging for the CLI, use the language property ({@link JavaLanguageProperties})
* {@code xTypeInferenceLogging}. From tests, see {@code JavaParsingHelper#logTypeInferenceVerbose()}.
*/
@SuppressWarnings("PMD.UncommentedEmptyMethodBody")
public interface TypeInferenceLogger {
@@ -64,8 +71,7 @@ public interface TypeInferenceLogger {
default void applicabilityTest(InferenceContext ctx) { }
default void finishApplicabilityTest() {
}
default void finishApplicabilityTest() { }
default void startArgsChecks() { }
@@ -8,7 +8,10 @@ import static net.sourceforge.pmd.lang.java.types.TestUtilitiesForTypesKt.captur
import static net.sourceforge.pmd.lang.java.types.internal.infer.BaseTypeInferenceUnitTest.Bound.eqBound;
import static net.sourceforge.pmd.lang.java.types.internal.infer.BaseTypeInferenceUnitTest.Bound.lower;
import static net.sourceforge.pmd.lang.java.types.internal.infer.BaseTypeInferenceUnitTest.Bound.upper;
import static net.sourceforge.pmd.util.CollectionUtil.setOf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -19,11 +22,17 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.util.List;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
import net.sourceforge.pmd.lang.java.types.JTypeMirror;
import net.sourceforge.pmd.lang.java.types.TypeOps;
import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind;
import net.sourceforge.pmd.lang.java.types.internal.infer.VarWalkStrategy.GraphWalk;
import net.sourceforge.pmd.util.IteratorUtil;
/**
*
@@ -331,4 +340,88 @@ class InferenceCtxUnitTests extends BaseTypeInferenceUnitTest {
assertThat(a, hasBoundsExactly(upper(ts.BOOLEAN.box())));
}
private static @NotNull List<Set<InferenceVar>> createBatchSetsFromGraph(InferenceContext ctx) {
GraphWalk graphWalk = new GraphWalk(ctx, false);
List<Set<InferenceVar>> batches = IteratorUtil.toList(graphWalk);
return batches;
}
@Test
void testGraphBuilding() {
InferenceContext ctx = emptyCtx();
InferenceVar a = newIvar(ctx);
InferenceVar b = newIvar(ctx);
List<Set<InferenceVar>> batches = createBatchSetsFromGraph(ctx);
// no dependency: unordered
assertThat(batches, containsInAnyOrder(setOf(a), setOf(b)));
}
@Test
void testGraphBuildingWithDependency() {
InferenceContext ctx = emptyCtx();
InferenceVar a = newIvar(ctx);
InferenceVar b = newIvar(ctx);
// a -> b
addSubtypeConstraint(ctx, a, ts.arrayType(b));
List<Set<InferenceVar>> batches = createBatchSetsFromGraph(ctx);
assertThat(batches, contains(setOf(b), setOf(a)));
}
@Test
void testGraphBuildingWithDependency2() {
InferenceContext ctx = emptyCtx();
InferenceVar a = newIvar(ctx);
InferenceVar b = newIvar(ctx);
// a -> b
// b -> a (because of propagation)
addSubtypeConstraint(ctx, a, b);
List<Set<InferenceVar>> batches = createBatchSetsFromGraph(ctx);
assertThat(batches, contains(setOf(b, a)));
}
@Test
void testGraphBuildingWithExtraDependency() {
InferenceContext ctx = emptyCtx();
InferenceVar a = newIvar(ctx);
InferenceVar b = newIvar(ctx);
// b -> a
ctx.addInstantiationDependencies(setOf(b), setOf(a));
List<Set<InferenceVar>> batches = createBatchSetsFromGraph(ctx);
assertThat(batches, contains(setOf(a), setOf(b)));
}
@Test
void testGraphBuildingWithDependencyCycle() {
InferenceContext ctx = emptyCtx();
InferenceVar a = newIvar(ctx);
InferenceVar b = newIvar(ctx);
InferenceVar c = newIvar(ctx);
// a -> b, b -> a,
// a -> c, b -> c
a.addBound(BoundKind.UPPER, b);
a.addBound(BoundKind.EQ, listType(c));
b.addBound(BoundKind.LOWER, a);
b.addBound(BoundKind.LOWER, listType(c));
List<Set<InferenceVar>> batches = createBatchSetsFromGraph(ctx);
assertThat(batches, contains(setOf(c), setOf(b, a)));
}
}