Make isUpperBound return true for unbounded wildcard

This commit is contained in:
Clément Fournier
2022-12-07 22:51:02 +01:00
parent 521f80591e
commit aeb4978676
5 changed files with 25 additions and 28 deletions

View File

@ -1578,7 +1578,7 @@ void TypeArgument() #void:
void WildcardType(): void WildcardType():
{} {}
{ {
"?" [ ("extends" {jjtThis.setUpperBound(true);}| "super") AnnotatedRefType() ] "?" [ ("extends" | "super" {jjtThis.setLowerBound(true);}) AnnotatedRefType() ]
} }

View File

@ -18,14 +18,14 @@ import org.checkerframework.checker.nullness.qual.Nullable;
*/ */
public final class ASTWildcardType extends AbstractJavaTypeNode implements ASTReferenceType { public final class ASTWildcardType extends AbstractJavaTypeNode implements ASTReferenceType {
private boolean isUpperBound; private boolean isLowerBound;
ASTWildcardType(int id) { ASTWildcardType(int id) {
super(id); super(id);
} }
void setUpperBound(boolean upperBound) { void setLowerBound(boolean lowerBound) {
isUpperBound = upperBound; isLowerBound = lowerBound;
} }
@Override @Override
@ -34,11 +34,12 @@ public final class ASTWildcardType extends AbstractJavaTypeNode implements ASTRe
} }
/** /**
* Returns true if this is an upper type bound, e.g. * Return true if this is an upper type bound, e.g.
* in {@code <? extends Integer>}. * {@code <? extends Integer>}, or the unbounded
* wildcard {@code <?>}.
*/ */
public boolean hasUpperBound() { public boolean isUpperBound() {
return isUpperBound && getNumChildren() > 0; return !isLowerBound;
} }
@ -46,18 +47,18 @@ public final class ASTWildcardType extends AbstractJavaTypeNode implements ASTRe
* Returns true if this is a lower type bound, e.g. * Returns true if this is a lower type bound, e.g.
* in {@code <? super Node>}. * in {@code <? super Node>}.
*/ */
public boolean hasLowerBound() { public boolean isLowerBound() {
return !isUpperBound && getNumChildren() > 0; return isLowerBound;
} }
/** /**
* Returns the type node representing the bound, e.g. * Returns the type node representing the bound, e.g.
* the {@code Node} in {@code <? super Node>}, or null. * the {@code Node} in {@code <? super Node>}, or null in
* the unbounded wildcard {@code <?>}.
*/ */
@Nullable public @Nullable ASTReferenceType getTypeBoundNode() {
public ASTReferenceType getTypeBoundNode() { return firstChild(ASTReferenceType.class);
return getFirstChildOfType(ASTReferenceType.class);
} }
@Override @Override

View File

@ -64,13 +64,10 @@ final class TypesFromAst {
ASTWildcardType wild = (ASTWildcardType) node; ASTWildcardType wild = (ASTWildcardType) node;
@Nullable JTypeMirror bound = fromAst(ts, lexicalSubst, wild.getTypeBoundNode()); @Nullable JTypeMirror bound = fromAst(ts, lexicalSubst, wild.getTypeBoundNode());
boolean isUpperBound = true;
if (bound == null) { if (bound == null) {
bound = ts.OBJECT; bound = ts.OBJECT;
} else {
isUpperBound = wild.hasUpperBound();
} }
return ts.wildcard(isUpperBound, bound).withAnnotations(getTypeAnnotations(node)); return ts.wildcard(wild.isUpperBound(), bound).withAnnotations(getTypeAnnotations(node));
} else if (node instanceof ASTIntersectionType) { } else if (node instanceof ASTIntersectionType) {
@ -264,7 +261,6 @@ final class TypesFromAst {
PSet<SymAnnot> annotsOnType = getSymbolicAnnotations(type); PSet<SymAnnot> annotsOnType = getSymbolicAnnotations(type);
Annotatable parent = getEnclosingAnnotationGiver(type); Annotatable parent = getEnclosingAnnotationGiver(type);
if (parent != null) { if (parent != null) {
// todo parent annots should be filtered by target TYPE_USE
PSet<SymAnnot> parentAnnots = getSymbolicAnnotations(parent); PSet<SymAnnot> parentAnnots = getSymbolicAnnotations(parent);
for (SymAnnot parentAnnot : parentAnnots) { for (SymAnnot parentAnnot : parentAnnots) {
if (parentAnnot.appliesToTypeUse()) { if (parentAnnot.appliesToTypeUse()) {

View File

@ -117,7 +117,7 @@ public final class PrettyPrintingUtil {
sb.append("?"); sb.append("?");
ASTReferenceType bound = ((ASTWildcardType) t).getTypeBoundNode(); ASTReferenceType bound = ((ASTWildcardType) t).getTypeBoundNode();
if (bound != null) { if (bound != null) {
sb.append(((ASTWildcardType) t).hasLowerBound() ? " super " : " extends "); sb.append(((ASTWildcardType) t).isLowerBound() ? " super " : " extends ");
prettyPrintTypeNode(sb, bound); prettyPrintTypeNode(sb, bound);
} }
} else if (t instanceof ASTUnionType) { } else if (t instanceof ASTUnionType) {

View File

@ -23,8 +23,8 @@ class ASTWildcardTypeTest : ParserTestSpec({
classType("List") { classType("List") {
typeArgList { typeArgList {
child<ASTWildcardType> { child<ASTWildcardType> {
it::hasUpperBound shouldBe true it::isUpperBound shouldBe true
it::hasLowerBound shouldBe false it::isLowerBound shouldBe false
it::getTypeBoundNode shouldBe classType("B") it::getTypeBoundNode shouldBe classType("B")
} }
@ -37,8 +37,8 @@ class ASTWildcardTypeTest : ParserTestSpec({
classType("List") { classType("List") {
typeArgList { typeArgList {
child<ASTWildcardType> { child<ASTWildcardType> {
it::hasUpperBound shouldBe false it::isUpperBound shouldBe false
it::hasLowerBound shouldBe true it::isLowerBound shouldBe true
it::getTypeBoundNode shouldBe classType("B") it::getTypeBoundNode shouldBe classType("B")
} }
@ -51,8 +51,8 @@ class ASTWildcardTypeTest : ParserTestSpec({
classType("List") { classType("List") {
typeArgList { typeArgList {
child<ASTWildcardType> { child<ASTWildcardType> {
it::hasUpperBound shouldBe false it::isUpperBound shouldBe true
it::hasLowerBound shouldBe false it::isLowerBound shouldBe false
it::getTypeBoundNode shouldBe null it::getTypeBoundNode shouldBe null
} }
@ -76,8 +76,8 @@ class ASTWildcardTypeTest : ParserTestSpec({
annotation("A") annotation("A")
annotation("B") annotation("B")
it::hasUpperBound shouldBe true it::isUpperBound shouldBe true
it::hasLowerBound shouldBe false it::isLowerBound shouldBe false
it::getTypeBoundNode shouldBe classType("B") { it::getTypeBoundNode shouldBe classType("B") {
annotation("C") annotation("C")