ek9_adopt_trait
Appends 'with trait of <Trait>' (or '… by <field>') to the construct's declaration and, when implementing, one override stub per abstract trait method; answers status, edits[] and summary, an already-adopted trait as conflicts[] (trait-already-adopted).
When to use it
'Make Greeter implement Speakable' is one call with symbol:'Greeter' and traitName:'Speakable' - stubs to fill in, or delegateFieldName to forward to a field.
When not to use it
- The class ALREADY declares the trait and only the 'by <field>' forwarding is missing - use
ek9_generate_delegation. - Renaming or restructuring a method rather than adopting a trait - use
ek9_rename_symbolorek9_change_signature. - The target is a record / function / enumeration - trait composition is classes/components only.
- Defining the trait itself, or pulling members out of a class into a new trait - use
ek9_new_construct/ek9_extract_trait. - Adding a plain method or field (no trait contract) - use
ek9_add_method/ek9_add_field.
Details
mode is inferred: delegateFieldName present → delegate, else implement; a contradicting mode is a mode-contradicts-arguments conflict. delegate errors if delegateFieldName names no existing field; a sealed ('allow only') trait that excludes the construct also errors. conflicts kinds: 'trait-already-adopted' and 'target-cannot-adopt-trait' (record/enumeration); a concrete-method clash across traits does NOT block - implement emits an override stub with '//AI: Resolve conflict' guidance instead. A trait from another module gets a references entry added automatically; a delegate field whose type doesn't satisfy the trait surfaces as would-fail from the scratch compile.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
delegateFieldName | string | To DELEGATE instead of implementing: the existing field on the construct to forward every trait method to (its type must satisfy the trait). | |
file | string | The EK9 source file - OPTIONAL when symbol is a construct name; required to anchor on a member or a use site. | |
mode | string: implement | delegate | Optional - inferred: delegateFieldName present → delegate, else implement (override stubs). | |
symbol | string | yes | The class or component that adopts the trait - a bare name ('Greeter') finds its file workspace-wide; 'mod::Greeter' when the name is declared in two modules. |
traitName | string | yes | The EXISTING trait to adopt (must resolve in the workspace); 'mod::Trait' when the name is declared in two modules. |
It also takes the arguments every tool takes.
Recorded calls
Real calls, recorded against small projects and checked on every build - a changed answer fails it.
Implement trait apply
Request
{
"constructName" : "Greeter",
"file" : "Greeter.ek9",
"mode" : "implement",
"traitName" : "Speakable"
}
Response
{
"conflicts" : [ ],
"edits" : [ {
"after" : " Greeter with trait of Speakable",
"before" : " Greeter",
"endLine" : 10,
"file" : "Greeter.ek9",
"startLine" : 10,
"type" : "replace"
}, {
"after" : " override speak() as pure\n <- rtn as String: String()\n //AI: Implement speak",
"endLine" : 13,
"file" : "Greeter.ek9",
"startLine" : 13,
"type" : "insert"
} ],
"meta" : {
"serverMs" : "<timing>"
},
"resolvedPath" : "<workspace-root>/Greeter.ek9",
"risk" : {
"crossesModuleBoundary" : false,
"estimatedSeverity" : "trivial",
"fileCount" : 1,
...
Cut short here: 10 more lines. The whole recorded call.
See also
- Show me in the IDE: Chapter 18: traits and delegation, built
- Show me in the IDE: Adopt Trait
- Fixes E05030