Make isUpperBound return true for unbounded wildcard
This commit is contained in:
@ -1578,7 +1578,7 @@ void TypeArgument() #void:
|
|||||||
void WildcardType():
|
void WildcardType():
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
"?" [ ("extends" {jjtThis.setUpperBound(true);}| "super") AnnotatedRefType() ]
|
"?" [ ("extends" | "super" {jjtThis.setLowerBound(true);}) AnnotatedRefType() ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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()) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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")
|
||||||
|
Reference in New Issue
Block a user