Annotations
XXML supports a Java-style annotation system for adding metadata to code elements. Annotations can be processed at compile-time or retained for runtime reflection.
Defining Annotations
xxml
// Simple marker annotation
[ Annotation <Immutable> Allows (AnnotationAllow::Classes) ]
// Annotation with runtime retention
[ Annotation <Serializable> Allows (AnnotationAllow::Classes) Retain ]
// Annotation with parameters
[ Annotation <Range> Allows (AnnotationAllow::Properties) Retain
Annotate (Integer^)(min);
Annotate (Integer^)(max);
]Annotation Targets
| Target | Description |
|---|---|
AnnotationAllow::Classes | Class declarations |
AnnotationAllow::Methods | Method declarations |
AnnotationAllow::Properties | Property declarations |
AnnotationAllow::Parameters | Method parameters |
AnnotationAllow::Constructors | Constructor declarations |
AnnotationAllow::All | Any target |
Using Annotations
xxml
@Entity
@Serializable(format = "json")
[ Class <User> Final Extends None
[ Public <>
@Column(name = "user_id", nullable = false)
Property <id> Types Integer^;
@Column(name = "user_name", nullable = false)
@MinLength(value = 1)
Property <name> Types String^;
@Range(min = 0, max = 150)
Property <age> Types Integer^;
]
]Default Values
Annotation parameters can have default values:
xxml
[ Annotation <Config> Allows (AnnotationAllow::Classes)
Annotate (String^)(name); // Required
Annotate (Integer^)(version) = 1; // Optional, default is 1
Annotate (Bool^)(debug) = false; // Optional, default is false
]
// Only required parameters need to be specified
@Config(name = "MyApp") // version=1, debug=false by default
[ Class <App> ... ]Inline Processors
Annotations can include inline processors that run during compilation:
xxml
[ Annotation <Review> Allows (AnnotationAllow::Classes, AnnotationAllow::Methods)
Annotate (String^)(message);
[ Processor
[ Public <>
Method <onAnnotate> Returns None Parameters (
Parameter <reflectionContext> Types ReflectionContext&,
Parameter <compilationContext> Types CompilationContext&
) -> {
Run compilationContext.warning(
String::Constructor("Code is under review")
);
}
]
]
]Note
Inline processors have access to
ReflectionContext for inspecting the annotated element and CompilationContext for emitting messages, warnings, or errors.Built-in Annotations
@Deprecated
xxml
@Deprecated
[ Class <OldApi> Final Extends None ... ]
// Compiler warning: class 'OldApi' is deprecated
@Deprecated(reason = "Use NewApi instead")
Method <oldMethod> Returns None Parameters () -> { ... }
// Compiler warning: method 'oldMethod' is deprecated: Use NewApi instead@Derive
xxml
@Derive(trait = "Stringable")
@Derive(trait = "Equatable")
@Derive(trait = "Hashable")
[ Class <Point> Final Extends None ... ]Complete Example
validation.xxml
#import Language::Core;
// Define validation annotations
[ Annotation <NotNull> Allows (AnnotationAllow::Properties) Retain ]
[ Annotation <Range> Allows (AnnotationAllow::Properties) Retain
Annotate (Integer^)(min);
Annotate (Integer^)(max);
]
[ Annotation <Pattern> Allows (AnnotationAllow::Properties) Retain
Annotate (String^)(regex);
]
// Use annotations for validation metadata
[ Class <Registration> Final Extends None
[ Public <>
@NotNull
@Pattern(regex = "^[a-zA-Z0-9_]+$")
Property <username> Types String^;
@NotNull
@Range(min = 8, max = 128)
Property <passwordLength> Types Integer^;
@NotNull
@Pattern(regex = "^[^@]+@[^@]+\\.[^@]+$")
Property <email> Types String^;
Constructor = default;
]
]Next Steps
Learn about Derives for automatic method generation, or explore Reflection to access annotation metadata at runtime.