blob: 44178a04c694d20dcd8e1e84a9e5ca69f67c4115 [file] [log] [blame]
// Note that this file is a near duplicate in /nullness and /nullness-uninit
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import org.checkerframework.checker.nullness.qual.*;
@org.checkerframework.framework.qual.DefaultQualifier(Nullable.class)
public class RawTypesBounded {
class Bad {
@NonNull String field;
public Bad() {
// :: error: (method.invocation)
this.init(); // error
// :: error: (method.invocation)
init(); // error
this.field = "field"; // valid
// :: error: (assignment)
this.field = null; // error
field = "field"; // valid
// :: error: (assignment)
field = null; // error
}
void init() {
output(this.field.length()); // valid
}
}
class A {
@NonNull String field;
public A() {
this.field = "field"; // valid
field = "field"; // valid
this.init(); // valid
init(); // valid
}
public void init(@UnknownInitialization A this) {
// :: error: (dereference.of.nullable)
output(this.field.length());
}
public void initExpl2(@UnknownInitialization A this) {
// :: error: (argument)
output(this.field);
}
public void initImpl1(@UnknownInitialization A this) {
// :: error: (dereference.of.nullable)
output(field.length());
}
public void initImpl2(@UnknownInitialization A this) {
// :: error: (argument)
output(field);
}
}
class B extends A {
@NonNull String otherField;
public B() {
super();
// :: error: (assignment)
this.otherField = null; // error
this.otherField = "otherField"; // valid
}
@Override
public void init(@UnknownInitialization B this) {
// :: error: (dereference.of.nullable)
output(this.field.length()); // error (TODO: substitution)
super.init(); // valid
}
public void initImpl1(@UnknownInitialization B this) {
// :: error: (dereference.of.nullable)
output(field.length()); // error (TODO: substitution)
}
public void initExpl2(@UnknownInitialization B this) {
// :: error: (dereference.of.nullable)
output(this.otherField.length()); // error
}
public void initImpl2(@UnknownInitialization B this) {
// :: error: (dereference.of.nullable)
output(otherField.length()); // error
}
void other() {
init(); // valid
this.init(); // valid
}
void otherRaw(@UnknownInitialization B this) {
init(); // valid
this.init(); // valid
}
}
class C extends B {
@NonNull String[] strings;
@Override
public void init(@UnknownInitialization C this) {
// :: error: (dereference.of.nullable)
output(this.strings.length); // error
System.out.println(); // valid
}
}
// To test whether the argument is @NonNull and @Initialized
static void output(@NonNull Object o) {}
class D extends C {
@Override
public void init(@UnknownInitialization D this) {
this.field = "s";
output(this.field.length());
}
}
class MyTest {
int i;
MyTest(int i) {
this.i = i;
}
void myTest(@UnknownInitialization MyTest this) {
i++;
}
}
class AllFieldsInitialized {
long elapsedMillis = 0;
long startTime = 0;
// If all fields have an initializer, then the type of "this"
// should still not be non-raw (there might be uninitilized subclasses)
public AllFieldsInitialized() {
// :: error: (method.invocation)
nonRawMethod();
}
public void nonRawMethod() {}
}
class AFSIICell {
AllFieldsSetInInitializer afsii;
}
class AllFieldsSetInInitializer {
long elapsedMillis;
long startTime;
public AllFieldsSetInInitializer() {
elapsedMillis = 0;
// :: error: (method.invocation)
nonRawMethod();
startTime = 0;
// :: error: (method.invocation)
nonRawMethod(); // still error (subclasses...)
}
public AllFieldsSetInInitializer(boolean b) {
// :: error: (method.invocation)
nonRawMethod();
}
public void nonRawMethod() {}
}
class ConstructorInvocations {
int v;
public ConstructorInvocations(int v) {
this.v = v;
}
public ConstructorInvocations() {
this(0);
// :: error: (method.invocation)
nonRawMethod();
}
public void nonRawMethod() {}
}
class MethodAccess {
public MethodAccess() {
@NonNull String s = string();
}
public @NonNull String string(@UnknownInitialization MethodAccess this) {
return "nonnull";
}
}
void cast(@UnknownInitialization Object... args) {
@SuppressWarnings("rawtypes")
// :: error: (assignment)
Object[] argsNonRaw1 = args;
@SuppressWarnings("cast")
Object[] argsNonRaw2 = (Object[]) args;
}
// default qualifier is @Nullable, so this is OK.
class RawAfterConstructorBad {
Object o;
RawAfterConstructorBad() {}
}
class RawAfterConstructorOK1 {
@Nullable Object o;
RawAfterConstructorOK1() {}
}
class RawAfterConstructorOK2 {
int a;
RawAfterConstructorOK2() {}
}
}