ek9_query_classes
Answers first: classNames[], then classes[] (name, module, file, line, extends, traits, isOpen, isAbstract, keyMethods, methodCount) and summary counts - workspace-wide or the filtered subset.
When to use it
Is there already a class I can reuse, extend or compose - one call with nameFilter:'User'; no arguments lists every class. Narrow further with extendsFilter, traitFilter, methodNameFilter or moduleFilter.
When not to use it
- Looking for a pure data shape with no methods — use
ek9_query_records. - Looking for an interface contract — use
ek9_query_traits. - Looking for a DI-injectable component (a specialised class kind) — use
ek9_query_components. - You already have a class name — use
ek9_query_type_hierarchy(full hierarchy graph),ek9_query_effective_api(complete method API), orek9_read_construct(source).
Details
EK9 classes are CLOSED by default — check isOpen before planning to extend; for a closed candidate the reuse path is composition (use as a field). status:empty means the walk succeeded but nothing matched — non-existent extends/trait/module targets surface in meta.unmatchedFilters[], NOT as an error; no compiled program is status:not-compiled (run ek9_compile first), and the only error is a traitMatch other than any/all. nameFilter/methodNameFilter are plain case-insensitive substrings, never regex; built-in org.ek9.* stdlib classes are excluded. traitFilter and extendsFilter name a trait/class EXACTLY (bare name, or module::Name for one module's) and match by symbol, transitively; traitMatch picks any-of (default) or all-of, and traitFilterResolvedTo lists the traits the filter matched. A value naming no trait/class is in meta.unmatchedFilters[], with meta.didYouMean naming those that contain it. traitFilter covers classes: records and components cannot carry traits, and the traits that extend a trait are in ek9_query_traits implementedBy.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
among | array of string | Names to answer FOR: 'which of these ...' - the name lists shrink to these and amongUnmatched names the ones that are not in the answer. Bare names, 'mod::Type' or 'Type.member'; a MODULE name stands for every construct in it ('which in scale.m07 do not ...' = amongUnmatched). | |
extendsFilter | string | Filter to classes whose extends-chain transitively includes this superclass name. | |
includeAbstract | boolean | Default true. When false, excludes classes marked 'as abstract'. | |
includeMethodSummary | boolean | Default true. When true each entry includes keyMethods[] (up to 5 public signatures). Set false for a lighter response. | |
methodNameFilter | string | Filter to classes declaring a method whose name matches (case-insensitive substring). | |
moduleFilter | array of string | Restrict to these exact module names. Default: workspace-wide. | |
nameFilter | string | Case-insensitive substring match on class names. | |
traitFilter | array of string | Filter to classes carrying the listed traits (transitive) - any one of them, or every one with traitMatch:'all'. Exact names, bare or module::Name. | |
traitMatch | string: any | all | How traitFilter combines: 'any' (default) - at least one; 'all' - every one. |
Recorded calls
Real calls, recorded against small projects and checked on every build - a changed answer fails it. 3 of the 4 recorded are shown.
Partial trait filter
Request
{
"traitFilter" : [ "Ident" ]
}
Response
{
"classNames" : [ ],
"classes" : [ ],
"meta" : {
"didYouMean" : {
"trait:Ident" : [ "Identifiable" ]
},
"serverMs" : "<timing>",
"unmatchedFilters" : [ "trait:Ident" ]
},
"status" : "empty",
"summary" : {
"abstractCount" : 0,
"classCount" : 0,
"moduleCount" : 0,
"openCount" : 0
},
"traitFilterResolvedTo" : [ ],
"traitMatch" : "any"
}
Qualified trait filter
Request
{
"includeMethodSummary" : false,
"traitFilter" : [ "com.example.auth::Identifiable" ]
}
Response
{
"classNames" : [ "UserService" ],
"classes" : [ {
"allTraits" : [ "Identifiable" ],
"extends" : "BaseService",
"file" : "services.ek9",
"isAbstract" : false,
"isOpen" : false,
"line" : 20,
"methodCount" : 4,
"module" : "com.example.auth",
"name" : "UserService",
"traits" : [ "Identifiable" ]
} ],
"meta" : {
"serverMs" : "<timing>"
},
"status" : "ok",
"summary" : {
"abstractCount" : 0,
"classCount" : 1,
"moduleCount" : 1,
"openCount" : 0
},
...
Cut short here: 3 more lines. The whole recorded call.
Trait filter all of
Request
{
"includeMethodSummary" : false,
"traitFilter" : [ "Identifiable", "Describable" ],
"traitMatch" : "all"
}
Response
{
"classNames" : [ "Both", "ViaCatalogue" ],
"classes" : [ {
"allTraits" : [ "Identifiable", "Describable" ],
"extends" : null,
"file" : "traits.ek9",
"isAbstract" : false,
"isOpen" : false,
"line" : 22,
"methodCount" : 4,
"module" : "com.example.both",
"name" : "Both",
"traits" : [ "Identifiable", "Describable" ]
}, {
"allTraits" : [ "Catalogued", "Identifiable", "Describable" ],
"extends" : null,
"file" : "traits.ek9",
"isAbstract" : false,
"isOpen" : false,
"line" : 28,
"methodCount" : 4,
"module" : "com.example.both",
"name" : "ViaCatalogue",
"traits" : [ "Catalogued" ]
...
Cut short here: 14 more lines. The whole recorded call.