diff --git a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java index 0dbe8d9f536..ffa79547212 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java +++ b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java @@ -2906,10 +2906,6 @@ public ParameterizedExecutableType constructorFromUse(NewClassTree tree) { AnnotatedExecutableType con = getAnnotatedType(ctor); // get unsubstituted type constructorFromUsePreSubstitution(tree, con); - if (viewpointAdapter != null) { - viewpointAdapter.viewpointAdaptConstructor(type, ctor, con); - } - if (tree.getClassBody() != null) { // Because the anonymous constructor can't have explicit annotations on its parameters, // they are copied from the super constructor invoked in the anonymous constructor. To @@ -2958,6 +2954,10 @@ public ParameterizedExecutableType constructorFromUse(NewClassTree tree) { con = AnnotatedTypes.asMemberOf(types, this, type, ctor, con); } + if (viewpointAdapter != null) { + viewpointAdapter.viewpointAdaptConstructor(type, ctor, con); + } + Map typeParamToTypeArg = AnnotatedTypes.findTypeArguments(processingEnv, this, tree, ctor, con); List typeargs; diff --git a/framework/src/test/java/org/checkerframework/framework/test/junit/ViewpointTestCheckerTest.java b/framework/src/test/java/org/checkerframework/framework/test/junit/ViewpointTestCheckerTest.java index f1cae8a2337..81479836a19 100644 --- a/framework/src/test/java/org/checkerframework/framework/test/junit/ViewpointTestCheckerTest.java +++ b/framework/src/test/java/org/checkerframework/framework/test/junit/ViewpointTestCheckerTest.java @@ -1,4 +1,4 @@ -package tests; +package org.checkerframework.framework.test.junit; import org.checkerframework.framework.test.CheckerFrameworkPerDirectoryTest; import org.junit.runners.Parameterized; diff --git a/framework/tests/viewpointtest/VarargsConstructor.java b/framework/tests/viewpointtest/VarargsConstructor.java new file mode 100644 index 00000000000..acf2380d741 --- /dev/null +++ b/framework/tests/viewpointtest/VarargsConstructor.java @@ -0,0 +1,65 @@ +// Test case for EISOP issue #777: +// https://github.com/eisop/checker-framework/issues/777 +import viewpointtest.quals.*; + +public class VarargsConstructor { + + VarargsConstructor(String str, Object... args) {} + + @SuppressWarnings({"inconsistent.constructor.type", "super.invocation.invalid"}) + @ReceiverDependentQual + VarargsConstructor(@ReceiverDependentQual Object... args) {} + + void foo() { + VarargsConstructor a = new VarargsConstructor("testStr", new Object()); + } + + void invokeConstructor(@A Object aObj, @B Object bObj, @Top Object topObj) { + @A Object a = new @A VarargsConstructor(aObj); + @B Object b = new @B VarargsConstructor(bObj); + @Top Object top = new @Top VarargsConstructor(topObj); + // :: error: (argument.type.incompatible) + new @A VarargsConstructor(bObj); + // :: error: (argument.type.incompatible) + new @B VarargsConstructor(aObj); + } + + class Inner { + @SuppressWarnings({"inconsistent.constructor.type", "super.invocation.invalid"}) + @ReceiverDependentQual + Inner(@ReceiverDependentQual Object... args) {} + + void foo() { + Inner a = new Inner(); + Inner b = new Inner(new Object()); + Inner c = VarargsConstructor.this.new Inner(); + Inner d = VarargsConstructor.this.new Inner(new Object()); + } + + void invokeConstructor(@A Object aObj, @B Object bObj, @Top Object topObj) { + @A Object a = new @A Inner(aObj); + @B Object b = new @B Inner(bObj); + @Top Object top = new @Top Inner(topObj); + // :: error: (argument.type.incompatible) + new @A Inner(bObj); + // :: error: (argument.type.incompatible) + new @B Inner(aObj); + } + } + + void testAnonymousClass(@A Object aObj, @B Object bObj, @Top Object topObj) { + Object o = + new VarargsConstructor("testStr", new Object()) { + void foo() { + VarargsConstructor a = new VarargsConstructor("testStr", new Object()); + } + }; + @A Object a = new @A VarargsConstructor(aObj) {}; + @B Object b = new @B VarargsConstructor(bObj) {}; + @Top Object top = new @Top VarargsConstructor(topObj) {}; + // :: error: (argument.type.incompatible) + new @A VarargsConstructor(bObj) {}; + // :: error: (argument.type.incompatible) + new @B VarargsConstructor(aObj) {}; + } +}