sclass LASValueDescriptor { bool knownValue() { false; } O value() { null; } Class javaClass() { null; } bool javaClassIsExact() { false; } bool canBeNull() { true; } bool canFail() { false; } bool willFail() { false; } srecord Exact(Class c, bool canBeNull) > LASValueDescriptor { Class javaClass() { ret c; } bool javaClassIsExact() { true; } bool canBeNull() { ret canBeNull; } } srecord NonExact(Class c, bool canBeNull) > LASValueDescriptor { Class javaClass() { ret c; } bool javaClassIsExact() { false; } bool canBeNull() { ret canBeNull; } } srecord KnownValue(O value) > LASValueDescriptor { bool knownValue() { true; } O value() { ret value; } Class javaClass() { ret value?.getClass(); } bool javaClassIsExact() { ret value != null; } bool canBeNull() { ret value == null; } } sclass WillFail > LASValueDescriptor { bool canFail() { true; } bool willFail() { true; } } static LASValueDescriptor fromClass(Class c) { ret new NonExact(c, true); } }