ek9_new_construct

Scaffolds one top-level construct (class/record/trait/component/function/type/constant/service) into an EXISTING module file, or a new package.ek9 for mode:'package'; answers status, edits[] (one INSERT, or one CREATE for a package), stubs[] to fill with ek9_insert_statements, added[] and nextStep.

Category: Editor · Compare: File → New Package… / IntelliJ New… / Cargo new

When to use it

'Create a class Order with its operators and a program Main that prints it' is ONE call: targetFile plus constructs:[{mode:'class', name:'Order', fields, operators, statements...}, {mode:'program', name:'Main', statements:[...]}] - bodies included, compiled once; a single construct is mode + name at the top level. mode:'package' creates the file instead. Pick the mode by intent: class=state+behaviour, record=value+operators, trait=API contract, function=stateless computation, component=DI-wired, type=enum/constrained/alias, service=REST routes, constant, package=publishable metadata; every mode but package appends into the module file (creating the 'defines <genus>' block if absent).

When not to use it

Details

name is required for every mode (for package it is the MODULE name, com.acme.orders; 'module' is accepted); genus rules are validated before render — record rejects named methods, trait rejects fields, component rejects trait composition. Classes and traits are closed-by-default ('is'/'extends' are synonyms via inheritanceKeyword; pass modifiers:['as open'] for an extensible base — an unresolved or non-open parent is caught by the compile gate); fields-bearing aggregates auto-get 'default operator ?' (E07235) and trait operators render as abstract contracts (Any-provided ?,==,$,$$,#?,<=> skipped + reported). service requires operations[] (>=1 — a route-less service does not compile) and defaults its security posture to bare 'open', not 'as open', when omitted (E12050); package capability enforcement turns on only when publicAccess + version + license + capabilities are ALL set.

Arguments

ArgumentTypeRequiredWhat it is
allowOnlyarray of stringSealed-hierarchy implementors (class + trait) — renders 'allow only A, B' after the header, restricting who may extend/implement.
applyStandardExcludesbooleanWhen true, EK9 standard excludes are merged with excludeFiles. Default false — must opt in. The directive is only emitted when this is explicitly true.
applyStandardIncludesbooleanWhen true, EK9 standard includes (all .ek9 files in source tree) are merged with includeFiles. Default false — must opt in. The directive is only emitted when this is explicitly true.
baseTypestringtype/constrained + type/alias: the underlying base type.
bodystringRaw EK9 source for the package-block body. When supplied, the structured fields below are ignored and the body is emitted verbatim inside the defines package wrapper. Indent each line with four spaces relative to column 0.
capabilitiesarray of stringFully-qualified gated-type names (e.g. 'org.ek9.lang::Stdout', 'org.ek9.lang::TCP', 'org.ek9.lang::HTTPRequest'). Presence of this list — alongside publicAccess + version + license — turns on compile-time supply-chain capability enforcement for the package. EK9 forbids empty list literals; pass null/omit the parameter for a pure-computation library.
constraintstringtype/constrained: the expression after 'constrain as' (e.g. '>= 16 and <= 100').
constructorsarray of objectConstructors [{parameters:['price as Float', ...], pure?, default?, visibility?}] — one parameter per field, each assigned to the property (':=?' when pure). default:true renders a synthesised 'default Name()' (no body); visibility 'private'/'protected' prefixes the declaration.
constructsarray of objectSEVERAL constructs in ONE call - each item has the same keys as this tool's top level (mode, name, fields, constructors, methods, operators, traits, parameters, returnType, statements, value, ...), mode:'program' with statements is allowed here, and an item may name its own targetFile (default: the call's) - a file that does not exist yet is created around the item's (or the call's) module. Rendered in order into their 'defines' blocks, every body pre-flighted, every touched file compiled ONCE: 'a trait, the classes over it and the program that drives them' is one call. What compiles is written; a construct that does not is named in refused[] with its diagnostics mapped to the statements[] entry (partial:true) - resend only that one.
depsobjectRuntime dependencies as module-name → version-string mapping. Becomes an EK9 Dict literal. Example: { 'ekopen.network.support.utils': '1.6.1-9' }.
descriptionstringPackage description (becomes a quoted EK9 String literal).
devDepsobjectDevelopment-only dependencies as module-name → version-string mapping. Same format as deps. Used for build/test dependencies that don't ship with the package.
enumValuesarray of stringtype/enumeration: the enum value names.
excludeDepsobjectTransitive dependency exclusions: bad-module → context-module mapping. Example: { 'ekopen.some.bad.dependency.pack': 'ekopen.org.supertools.util' }.
excludeFilesarray of stringGlob patterns of files to exclude.
extendsstringParent type for class/record/trait/component, OR the abstract function a function extends (function inheritance: 'f() extends abstractFunction'). Pair with inheritanceKeyword for is-vs-extends. Closed-by-default: an unresolved or non-'as open' parent surfaces as a would-fail on dry-run.
fieldsarray of anyField declarations as DATA: {name, type, defaultValue?, injected?} with BOTH name and type (the EK9 text 'name as Type' / 'name as Type: default' / 'name as Type!' / 'name <- default' is also accepted). A field without a type or default is rejected before anything is rendered. Not valid on traits. A typed field with no default is declared unset ('as Type?') and the compiler-required no-arg constructor is added for you (reported under 'added').
fileModestring: auto | create-file | overwritemode:package - auto (default; conflict 'file-exists' when the file exists), create-file (alias for auto), overwrite (replace the existing file).
includeFilesarray of stringGlob patterns of files to include in the package (e.g. '**.{cal}', 'License.txt'). Use alongside or instead of applyStandardIncludes.
inheritanceKeywordstring: extends | is'extends' (default) or 'is' — synonyms; choice is stylistic (conventionally 'is' for components).
licensestringLicense identifier (e.g. 'MIT', 'Apache-2.0'). Becomes a quoted EK9 String literal. One of the four publishable conditions for capability enforcement.
methodsarray of objectMethods [{name, parameters:[{name, type}, ...], returnType?, pure?, isAbstract?, override?, visibility?, dispatcher?, statements?}]. Each parameter is ONE item as DATA - {name:'code', type:'Integer'} - never a {name} and a {type} as two items, and never with '->' or '<-' in it: the tool writes the arrows and the layout. ('code as Integer' is also accepted.) Not valid on records (operators only). dispatcher:true renders 'as dispatcher' (double-dispatch root). Give the body as statements[] (each entry one statement or one block, assign 'rtn: <value>' on every path) and the member is complete in this call; without it the body is a stub listed under 'stubs' for ek9_insert_statements to fill.
modestring: package | class | record | trait | component | function | type | constant | service | programConstruct kind. class/record/trait/component/function/type/constant/service/program append into an EXISTING .ek9 module file via the gated changeset path (omitted with parameters/returnType/statements and no fields = function); package creates a new file.
modifiersarray of stringTrailing modifiers verbatim, e.g. ['as open'], ['as abstract']. All four aggregate genera (class/record/trait/component) accept open|abstract — closed by default.
modulestringmode:package - the EK9 module name (FQ format like com.acme.orders); the same value as name, accepted in either. With constructs[] - the module a targetFile that does not exist yet is created around (an item's own 'module' wins).
namestringConstruct name - PascalCase for type-shaped genera, camelCase for a function or constant; for mode:package the MODULE name (com.acme.orders; 'module' is accepted).
operationsarray of objectservice mode (required, >=1): the web operations/routes. Each: {name | operator, verb?, uri, security?, params?, response?}. Use 'name' (+ optional 'verb' GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS, default GET) for a named route, or 'operator' (+= POST, -= DELETE, :^: PUT, :~: PATCH, ? HEAD) for the operator form. 'uri' is the operation path (e.g. '/{id}'). params: [{name, type, in: PATH|QUERY|HEADER|CONTENT|REQUEST|CONTEXT, source?, sanitized?}] — named extractions (PATH/QUERY/HEADER) are auto-captured + referenced so they compile. response: {status?, contentType?, contentLanguage?, cacheControl? | cache:{maxAge, visibility:public|private, mustRevalidate?, noStore?}} — only the fields you set are overridden; HTTPResponse defaults the rest.
operatorsarray of anyOperators to declare. RULE OF THUMB: a string ('?', '$', 'all') means 'let the compiler synthesise it' (default operator); if the task describes what the operator RETURNS or DOES, you need the object form with custom:true, which renders a stub body for ek9_insert_statements(method:'<sym>') to fill. A plain string (or {symbol}) renders the terse 'default operator <sym>'; 'all' / '*' renders the bare 'default operator' (all defaultable). A CUSTOM operator object {symbol, custom:true, override?, pure?, parameters:[{name,type}], returnType?} renders a CONCRETE operator with a //AI-marked body — for operators the compiler cannot synthesise (a hand-rolled '$', an overriding '?', a mutating '+='). On a trait, default operators render as ABSTRACT contracts ('operator <sym> [as pure] as abstract' with resolved param/return) — Any-provided operators (?,==,$,$$,#?,<=>) are skipped + reported. Valid on class/record/trait/component. A fields-bearing aggregate auto-gets 'default operator ?' if one isn't requested (E07235).
parametersarray of anyfunction mode: input parameters, each ONE item - 'code as Integer' or {name:'code', type:'Integer'}. 'params' is accepted as an alias.
publicAccessbooleanWhen true, the package can be deployed to the EK9 repository (or a private repository when false-and-published). One of the four publishable conditions. Default false.
purebooleanPure-construction mode (class/record/component). Renders every field unset ('as Type?', any defaultValue relocated), forces every constructor 'as pure' (assigning via ':=?'), and — when no no-arg constructor was supplied and the construct has assignable fields — adds a public no-arg default-setter, so the construct is constructible in a pure context. Default false.
returnTypestringReturn TYPE only, e.g. 'String', 'List of Integer' - never '<- rtn as String', never a name: the tool writes the '<- rtn as <Type>?' declaration and the body assigns 'rtn: <expr>'. Omitted means no return.
securitystringservice mode: the security posture rendered after the base URI — 'open' or 'constrain by Gate [and Cors]'. Mandatory at service or operation level (E12050); defaults to 'open' when neither is given.
serviceUristringservice mode (required): the base URI, e.g. '/addresses' — renders 'Name for :/addresses <posture>'. Base URIs cannot contain path variables (E07680).
statementsarray of stringmode:function - the function's body, one statement or one block per entry (assign 'rtn: <value>' on every path when there is a return): the function is complete in this call, no stub to fill.
tagsarray of stringTag list — used for repository search.
targetFilestringyesDestination: workspace-relative path of the .ek9 file - for package the NEW file to create (conflict 'file-exists' unless fileMode:'overwrite'); for every other mode the EXISTING module file the construct is appended to (its 'defines <genus>' block is created if absent). With constructs[] it is the default for items that name no targetFile of their own.
traitsarray of object'with trait of' composition (class/trait only). Each {trait, byField?}; byField delegates the trait to a field.
typeFormstring: enumeration | constrained | aliastype mode (required): 'enumeration' | 'constrained' | 'alias'.
typeParametersarray of objectConceptual type parameters for a GENERIC class or function: [{name, constrainBy?}] → 'of type T' or 'of type (K, V)', each optionally 'constrain by <Type>'. Member signatures may reference the parameter names (T/K/V) as types. The parameterised header is grammar-incompatible with extends/with-trait-of/allow-only, so those are omitted when present.
valuestringconstant mode: the literal verbatim (e.g. '"localhost"', '42', '3.14') — emitted as 'NAME <- value'.
versionstringPackage version literal (Version type, not a String). Strict semver: MAJOR.MINOR.PATCH-BUILD or MAJOR.MINOR.PATCH-FEATURE-BUILD. Default '1.0.0-0'.

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. 3 of the 78 recorded are shown.

Trait rejects field

Request

{
  "fields" : [ {
    "name" : "x",
    "type" : "Integer"
  } ],
  "mode" : "trait",
  "name" : "Drawable",
  "targetFile" : "main.ek9"
}

Response

{
  "conflicts" : [ ],
  "edits" : [ ],
  "error" : {
    "message" : "trait does not support fields"
  },
  "meta" : {
    "serverMs" : "<timing>"
  },
  "status" : "error",
  "summary" : "trait does not support fields",
  "wouldBeDiagnostics" : [ ],
  "written" : false
}

Record rejects method

Request

{
  "methods" : [ {
    "name" : "describe",
    "returnType" : "String"
  } ],
  "mode" : "record",
  "name" : "Point",
  "targetFile" : "main.ek9"
}

Response

{
  "conflicts" : [ ],
  "edits" : [ ],
  "error" : {
    "message" : "record does not support named methods (records support operators only)"
  },
  "meta" : {
    "serverMs" : "<timing>"
  },
  "status" : "error",
  "summary" : "record does not support named methods (records support operators only)",
  "wouldBeDiagnostics" : [ ],
  "written" : false
}

Record rejects type parameters

Request

{
  "dryRun" : true,
  "mode" : "record",
  "name" : "Box",
  "targetFile" : "main.ek9",
  "typeParameters" : [ {
    "name" : "T"
  } ]
}

Response

{
  "conflicts" : [ ],
  "edits" : [ ],
  "error" : {
    "message" : "record cannot be generic — only class and function support type parameters ('of type T')"
  },
  "meta" : {
    "serverMs" : "<timing>"
  },
  "status" : "error",
  "summary" : "record cannot be generic — only class and function support type parameters ('of type T')",
  "wouldBeDiagnostics" : [ ],
  "written" : false
}

See also