Protected Regions
To avoid confusing errors during automated evaluation, Subato clients should prevent users from
editing predefined elements in template files, such as method names and parameter types. Thus, a
task can be configured with protected regions for defining readonly sections of the code.
Protected regions are only supported for tasks configured with lang=java in
meta.xml.
Manual Definition
Protected regions can be defined manually in template files using
annotations. Set protectedRegions="enabled" in meta.xml first,
then import the annotations in the file:
import de.hsrm.sls.subato.ext.*;
Fields, methods, types, and records can then be annotated with these annotations:
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.FIELD)
public @interface ProtectedField {
}
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
public @interface ProtectedMethod {
// Whether the method body can be edited
public boolean enableBody() default false;
}
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface ProtectedType {
// Whether the class body can be edited
public boolean enableBody() default false;
}
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface ProtectedRecord {
// Whether the record body can be edited
public boolean enableBody() default false;
// Whether the components in the record header (canonical constructor) can be edited
public boolean enableComponents() default false;
}
Example
import de.hsrm.sls.subato.ext.*;
@ProtectedType(enableBody = true)
public class AL<E> {
@ProtectedField
private long theSize;
private Object[] store;
@ProtectedMethod(enableBody = true)
AL() {
/* TODO */
}
@ProtectedMethod
long size() {
return theSize;
}
@ProtectedMethod(enableBody = true)
AL<E> add(E e) {
/* TODO */
}
AL<E> remove(E o) {
/* TODO */
}
private void enlargeStore(){
Object[] newStore = new Object[store.length+10];
for (long i=0;i<theSize;i++) newStore[i]=store[i];
store=newStore;
}
@ProtectedType
interface MyPredicate<A> {
boolean test(A v);
}
AL<E> filter(MyPredicate<E> p) {
/* TODO */
}
@ProtectedRecord(enableComponents = true)
record Pair<E, A>(/* TODO */) { }
<A> AL<Pair<E, A>> pairWith(AL<A> rs) {
/* TODO */
}
}
Automated Definition
Instead of annotating everything by hand, set protectedRegions="auto" in meta.xml.
Protected regions are then configured automatically from the test files, using these rules:
- Every method in a
templatefile called from atestfile is annotated with@ProtectedMethod - Every constructor in a
templatefile used to instantiate an object in atestfile is annotated with@ProtectedMethod - Every field accessed from a
testfile is annotated with@ProtectedField - Every class, record, interface or enum containing an element that matches any of the previously listed rules is annotated with either
@ProtectedType(for classes, interfaces and enums) or@ProtectedRecord(for records).
@ProtectedMethod, @ProtectedType, and @ProtectedRecord are applied with enableBody = true,
which produces the expected result in most cases. When it does not, override it with a manual
annotation in the template file. These always take precedence over auto-detected ones. You can
also exclude annotations that were automatically created by annotating the target element with
@ProtectedIgnore.