feat(compiler): allow inline decorators on declaration expressions#11035
feat(compiler): allow inline decorators on declaration expressions#11035timotheeguerin wants to merge 13 commits into
Conversation
Allow model, enum, union, and scalar declarations to be used in expression position (e.g. alias RHS, property types). In expression position they are anonymous (name is "") and the resulting type has expression: true; they are not registered in the enclosing namespace. A diagnostic is reported when template parameters are used on a declaration in expression position.
A keyword-form union (`union { a, b }`) used in expression position is marked
`expression: true`, which caused checkUnionExpression to flatten its (possibly
named) variants into the parent union, silently dropping colliding members.
Flatten only unions originating from the `|` operator (UnionExpression node).
Add tests for: - expression: false on statement declarations - name retention on named declaration expressions - named expressions not being referenceable - union namespace non-registration - alias-resolved types, op return/param, union variant usage - member access via alias, decorator rejection - enum values, union named variants, scalar constructors, model spread - parser negatives for interface/op in expression position - formatter named & nested declaration expressions
Anonymous declarations used in expression position rendered with a stray
namespace prefix (e.g. `Ns.` for enum/scalar, `Ns.{ x: string }` for
keyword-form model). Render them inline and un-prefixed, mirroring union
expression naming.
Also extract a single shared `isDeclarationInExpressionPosition` helper used
by both the binder and checker so the two position predicates cannot drift,
and add regression tests (type names, keyword-form union as `|` operand,
template parameter referenced inside an expression declaration).
Inline anonymous declaration expressions and hoist named ones across the OpenAPI and JSON Schema emitters, validate keyword-form union expression variants in versioning, and derive the enum typekit `expression` flag from an empty name.
@typespec/compiler
@typespec/html-program-viewer
@typespec/json-schema
@typespec/openapi
@typespec/openapi3
@typespec/versioning
commit: |
|
All changed packages have been documented.
Show changes
|
|
You can try these changes here
|
# Conflicts: # packages/compiler/src/formatter/print/printer.ts
5894e7b to
24d23ff
Compare
Note
Stacked on top of #11019 (declarations-as-expressions). This PR targets
main, so its diff currently includes thedecl-exprcommits as well — it should be reviewed/merged after #11019, or rebased once that lands.Summary
Builds on the declaration-expressions feature to allow decorators to be applied inline to
model,enum,union, andscalardeclarations used in expression position.Changes (incremental over #11019)
parser.ts): the@case inparsePrimaryExpressionnow parses a decorator list and, when followed by amodel/enum/union/scalarkeyword, dispatches to the correspondingparse*Statement(withposcaptured at@so the node span includes the decorators). Decorators before any other expression still reportinvalid-decorator-location("Cannot decorate expression."). No checker changes were required —parse*Statementalready plumbsdecoratorsonto the AST node and the checker already applies them.printer.ts): the fourprint*Statementprinters now passtryInline: isInExpressionPosition(path), keeping decorators on the same line in expression position while statement-position decorators still break to their own line. Output is idempotent.spec.emu.html): added the optionalDecoratorList?prefix to the four*DeclarationExpressionproductions.Tests
getDoc) for anonymous enum, named model, keyword union, and scalar declaration expressions, plus a negative test that non-declaration expressions still reject decorators.Validation
@typespec/compilerbuilds cleandeclaration-expressions.test.tsandformatter.test.tspass (254 tests)