import org.checkerframework.checker.nullness.qual.*; import org.checkerframework.checker.nullness.qual.EnsuresNonNull; public class AssertAfterChecked { class InitField { @Nullable Object f; @EnsuresNonNull("f") void init() { f = new Object(); } @EnsuresNonNull("f") //:: error: (contracts.postcondition.not.satisfied) void initBad() {} void testInit() { init(); f.toString(); } } static class InitStaticField { static @Nullable Object f; @EnsuresNonNull("f") void init() { f = new Object(); } @EnsuresNonNull("f") void init2() { InitStaticField.f = new Object(); } @EnsuresNonNull("f") //:: error: (contracts.postcondition.not.satisfied) void initBad() {} void testInit() { init(); f.toString(); } @EnsuresNonNull("InitStaticField.f") void initE() { f = new Object(); } @EnsuresNonNull("InitStaticField.f") void initE2() { InitStaticField.f = new Object(); } @EnsuresNonNull("InitStaticField.f") //:: error: (contracts.postcondition.not.satisfied) void initBadE() {} void testInitE() { initE(); // TODO: we need to also support the unqualified static field access? // f.toString(); } void testInitE2() { initE(); InitStaticField.f.toString(); } } class TestParams { @EnsuresNonNull("get(#1)") //:: error: (contracts.postcondition.not.satisfied) void init(final TestParams p) {} @org.checkerframework.dataflow.qual.Pure @Nullable Object get(Object o) { return null; } void testInit1() { init(this); get(this).toString(); } void testInit1b() { init(this); this.get(this).toString(); } void testInit2(TestParams p) { init(p); get(p).toString(); } void testInit3(TestParams p) { p.init(this); p.get(this).toString(); } void testInit4(TestParams p) { p.init(this); //:: error: (dereference.of.nullable) this.get(this).toString(); } } class WithReturn { @Nullable Object f; @EnsuresNonNull("f") int init1() { f = new Object(); return 0; } @EnsuresNonNull("f") int init2() { if (5 == 5) { f = new Object(); return 0; } else { f = new Object(); return 1; } } @EnsuresNonNull("f") //:: error: (contracts.postcondition.not.satisfied) int initBad1() { return 0; } @EnsuresNonNull("f") //:: error: (contracts.postcondition.not.satisfied) int initBad2() { if (5 == 5) { return 0; } else { f = new Object(); return 1; } } void testInit() { init1(); f.toString(); } } }