Skip to content

Commit 243fac0

Browse files
committed
add annotations
1 parent a07d06d commit 243fac0

File tree

1 file changed

+200
-0
lines changed
  • docs/03.reference/40.annotations

1 file changed

+200
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
title: Annotations
3+
id: annotations
4+
menuTitle: Annotations
5+
categories:
6+
- server
7+
related:
8+
- tag-component
9+
- tag-interface
10+
- tag-function
11+
- tag-property
12+
- language-syntax-differences
13+
- function-getmetadata
14+
---
15+
16+
Annotations in Lucee allow you to add metadata to components, interfaces, functions, and properties using JavaDoc-style documentation blocks (docblocks).
17+
18+
This metadata is available at runtime via [[function-getmetadata]] but does not affect code execution.
19+
20+
## Docblock Syntax
21+
22+
Annotations are written in docblock comments (`/** ... */`) placed immediately before the element they describe:
23+
24+
```luceescript
25+
/**
26+
* A user service component
27+
* @author John Smith
28+
* @version 1.0
29+
*/
30+
component {
31+
32+
/**
33+
* Retrieves a user by ID
34+
* @id The unique user identifier
35+
* @return A user struct or null if not found
36+
* @deprecated Use getUserById() instead
37+
*/
38+
function getUser( required numeric id ) {
39+
// implementation
40+
}
41+
42+
}
43+
```
44+
45+
## Annotation Format
46+
47+
Annotations use the `@name value` format within docblocks:
48+
49+
- **Description**: Text before any `@` tags becomes the description
50+
- **@tags**: Lines starting with `@` followed by a name and optional value
51+
52+
```luceescript
53+
/**
54+
* This is the description.
55+
* It can span multiple lines.
56+
* @param.name The user's name
57+
* @param.age The user's age
58+
* @return A greeting string
59+
* @custom.anything You can use any tag name
60+
*/
61+
function greet( string name, numeric age ) {
62+
return "Hello #name#!";
63+
}
64+
```
65+
66+
## Supported Elements
67+
68+
Docblock annotations can be applied to:
69+
70+
- [[tag-component]] (`component {}`)
71+
- [[tag-interface]] (`interface {}`)
72+
- [[tag-function]] (both script and tag style)
73+
- [[tag-property]] (`property name="..."`)
74+
75+
## Accessing Annotations
76+
77+
Use [[function-getmetadata]] to retrieve annotations at runtime:
78+
79+
```luceescript
80+
component {
81+
/**
82+
* Component description
83+
* @author Test Author
84+
*/
85+
}
86+
87+
meta = getMetadata( new MyComponent() );
88+
dump( meta.hint ); // "Component description"
89+
dump( meta.author ); // "Test Author"
90+
```
91+
92+
For functions:
93+
94+
```luceescript
95+
/**
96+
* Function description
97+
* @return The result
98+
*/
99+
function myFunc() {}
100+
101+
meta = getMetadata( myFunc );
102+
dump( meta.hint ); // "Function description"
103+
dump( meta.return ); // "The result"
104+
```
105+
106+
## Annotations vs Inline Attributes
107+
108+
Lucee distinguishes between:
109+
110+
- **Annotations**: Metadata from docblocks (accessed via [[function-getmetadata]])
111+
- **Inline attributes**: Attributes in the declaration itself (affect behaviour)
112+
113+
```luceescript
114+
/**
115+
* @mixin controller
116+
*/
117+
function handler() mixin="model" output="false" {
118+
// The docblock @mixin is annotation metadata
119+
// The inline mixin="model" is the actual attribute
120+
}
121+
```
122+
123+
**Important**: When there's a conflict, inline attributes take precedence. Docblock annotations that would affect runtime behaviour (`@returntype`, `@output`, etc.) are ignored if they conflict with the actual declaration.
124+
125+
## Annotations Do Not Affect Runtime
126+
127+
Unlike some other CFML engines, Lucee treats docblock annotations as pure metadata.
128+
129+
They populate [[function-getmetadata]] results but do not change how code executes:
130+
131+
```luceescript
132+
/**
133+
* @returntype string
134+
*/
135+
public numeric function calculate() {
136+
return 42;
137+
}
138+
// Return type is numeric (from declaration), not string (from annotation)
139+
```
140+
141+
This design ensures that comments never cause compiler errors or unexpected behaviour changes.
142+
143+
## Common Annotation Tags
144+
145+
While you can use any tag name, these are commonly used:
146+
147+
| Tag | Purpose |
148+
|-----|---------|
149+
| `@param` | Document function parameters |
150+
| `@return` | Document return value |
151+
| `@author` | Author information |
152+
| `@version` | Version number |
153+
| `@deprecated` | Mark as deprecated with reason |
154+
| `@see` | Reference to related documentation |
155+
| `@throws` | Document exceptions that may be thrown |
156+
| `@hint` | Short description (alternative to first line) |
157+
158+
## Parameter Hints
159+
160+
Document function parameters using `@param.paramname` or just the parameter name:
161+
162+
```luceescript
163+
/**
164+
* Greets a user
165+
* @name The user's name
166+
* @age The user's age in years
167+
*/
168+
function greet( string name, numeric age ) {
169+
return "Hello #name#, you are #age# years old!";
170+
}
171+
```
172+
173+
The parameter hints become available in `getMetadata( greet ).parameters[n].hint`.
174+
175+
## Property Annotations
176+
177+
[[tag-property]] supports docblock annotations:
178+
179+
```luceescript
180+
component accessors="true" {
181+
182+
/** The user's unique identifier */
183+
property name="id" type="numeric";
184+
185+
/**
186+
* The user's display name
187+
* @validate required
188+
*/
189+
property name="displayName" type="string";
190+
191+
}
192+
```
193+
194+
## Best Practices
195+
196+
1. **Use docblocks for documentation** - descriptions, author info, deprecation notices
197+
2. **Use inline attributes for behaviour** - output, returntype, access modifiers
198+
3. **Keep descriptions concise** - first line should be a summary
199+
4. **Document parameters** - helps IDE tooling and API consumers
200+
5. **Mark deprecated code** - use `@deprecated` with migration guidance

0 commit comments

Comments
 (0)