aontu 0.62.0 → 0.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/agentsmd.js +0 -27
- package/dist/agentsmd.js.map +1 -1
- package/dist/alias.js.map +1 -1
- package/dist/allow.js +0 -92
- package/dist/allow.js.map +1 -1
- package/dist/aontu.d.ts +3 -3
- package/dist/aontu.js +4 -84
- package/dist/aontu.js.map +1 -1
- package/dist/aontumodel.d.ts +4 -0
- package/dist/aontumodel.js +27 -0
- package/dist/aontumodel.js.map +1 -0
- package/dist/casing.d.ts +5 -0
- package/dist/casing.js +90 -0
- package/dist/casing.js.map +1 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +228 -935
- package/dist/cli.js.map +1 -1
- package/dist/ctx.js +0 -48
- package/dist/ctx.js.map +1 -1
- package/dist/diff.js +0 -32
- package/dist/diff.js.map +1 -1
- package/dist/err.js +0 -40
- package/dist/err.js.map +1 -1
- package/dist/escape.js +0 -45
- package/dist/escape.js.map +1 -1
- package/dist/exactjson.d.ts +0 -35
- package/dist/exactjson.js +0 -131
- package/dist/exactjson.js.map +1 -1
- package/dist/format.js +13 -203
- package/dist/format.js.map +1 -1
- package/dist/grammar.d.ts +9 -0
- package/dist/grammar.js +54 -0
- package/dist/grammar.js.map +1 -0
- package/dist/graph.js +0 -26
- package/dist/graph.js.map +1 -1
- package/dist/hcanon.js +0 -82
- package/dist/hcanon.js.map +1 -1
- package/dist/helpdoc.js +2 -2
- package/dist/helpdoc.js.map +1 -1
- package/dist/hints.d.ts +0 -6
- package/dist/hints.js +57 -55
- package/dist/hints.js.map +1 -1
- package/dist/jsonschema.js +0 -114
- package/dist/jsonschema.js.map +1 -1
- package/dist/keyorder.d.ts +0 -7
- package/dist/keyorder.js +0 -41
- package/dist/keyorder.js.map +1 -1
- package/dist/lang.js +17 -915
- package/dist/lang.js.map +1 -1
- package/dist/lsp-server.js +0 -16
- package/dist/lsp-server.js.map +1 -1
- package/dist/lsp.d.ts +1 -1
- package/dist/lsp.js +12 -159
- package/dist/lsp.js.map +1 -1
- package/dist/mcp-server.js +0 -26
- package/dist/mcp-server.js.map +1 -1
- package/dist/mcp.js +0 -149
- package/dist/mcp.js.map +1 -1
- package/dist/mod-tool.js +16 -131
- package/dist/mod-tool.js.map +1 -1
- package/dist/mod.js +0 -162
- package/dist/mod.js.map +1 -1
- package/dist/patch.js +0 -217
- package/dist/patch.js.map +1 -1
- package/dist/profile.d.ts +9 -0
- package/dist/profile.js +28 -0
- package/dist/profile.js.map +1 -0
- package/dist/provenance.js +0 -140
- package/dist/provenance.js.map +1 -1
- package/dist/query.js +0 -75
- package/dist/query.js.map +1 -1
- package/dist/reach.js +0 -43
- package/dist/reach.js.map +1 -1
- package/dist/relation.js +0 -61
- package/dist/relation.js.map +1 -1
- package/dist/report-sarif.d.ts +0 -11
- package/dist/report-sarif.js +0 -28
- package/dist/report-sarif.js.map +1 -1
- package/dist/sig.js +0 -35
- package/dist/sig.js.map +1 -1
- package/dist/sigdecl.js +1 -1
- package/dist/sigdecl.js.map +1 -1
- package/dist/siggate.js +0 -4
- package/dist/siggate.js.map +1 -1
- package/dist/site.js +3 -29
- package/dist/site.js.map +1 -1
- package/dist/subsume.d.ts +0 -10
- package/dist/subsume.js +0 -137
- package/dist/subsume.js.map +1 -1
- package/dist/template.d.ts +2 -1
- package/dist/template.js +58 -138
- package/dist/template.js.map +1 -1
- package/dist/trace.d.ts +21 -0
- package/dist/trace.js +107 -0
- package/dist/trace.js.map +1 -0
- package/dist/trim.js +0 -41
- package/dist/trim.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/type.js.map +1 -1
- package/dist/unify.js +13 -248
- package/dist/unify.js.map +1 -1
- package/dist/utility.js +0 -22
- package/dist/utility.js.map +1 -1
- package/dist/val/AbnfFuncVal.d.ts +18 -0
- package/dist/val/AbnfFuncVal.js +132 -0
- package/dist/val/AbnfFuncVal.js.map +1 -0
- package/dist/val/AbsentVal.d.ts +11 -0
- package/dist/val/AbsentVal.js +30 -0
- package/dist/val/AbsentVal.js.map +1 -0
- package/dist/val/AggFuncVal.d.ts +10 -1
- package/dist/val/AggFuncVal.js +104 -116
- package/dist/val/AggFuncVal.js.map +1 -1
- package/dist/val/ArithFuncVal.js +0 -12
- package/dist/val/ArithFuncVal.js.map +1 -1
- package/dist/val/BagVal.js +1 -78
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/BigDecimalVal.js +0 -16
- package/dist/val/BigDecimalVal.js.map +1 -1
- package/dist/val/BigIntegerVal.js +0 -16
- package/dist/val/BigIntegerVal.js.map +1 -1
- package/dist/val/CloseFuncVal.js +0 -9
- package/dist/val/CloseFuncVal.js.map +1 -1
- package/dist/val/CmpFuncVal.d.ts +2 -0
- package/dist/val/CmpFuncVal.js +49 -72
- package/dist/val/CmpFuncVal.js.map +1 -1
- package/dist/val/ConjunctVal.js +0 -29
- package/dist/val/ConjunctVal.js.map +1 -1
- package/dist/val/ConstraintVal.js +0 -500
- package/dist/val/ConstraintVal.js.map +1 -1
- package/dist/val/ContainerKindVal.js +0 -2
- package/dist/val/ContainerKindVal.js.map +1 -1
- package/dist/val/CopyFuncVal.js +0 -3
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/Decimal.js +0 -179
- package/dist/val/Decimal.js.map +1 -1
- package/dist/val/DeprecateFuncVal.js.map +1 -1
- package/dist/val/DisjunctVal.js +0 -152
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/EachFuncVal.js +0 -3
- package/dist/val/EachFuncVal.js.map +1 -1
- package/dist/val/EmitFuncVal.d.ts +1 -1
- package/dist/val/EmitFuncVal.js +6 -119
- package/dist/val/EmitFuncVal.js.map +1 -1
- package/dist/val/ExpectVal.js +0 -62
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FilterFuncVal.js +0 -25
- package/dist/val/FilterFuncVal.js.map +1 -1
- package/dist/val/FuncBaseVal.d.ts +1 -0
- package/dist/val/FuncBaseVal.js +7 -127
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/GraphAtomVal.js +0 -15
- package/dist/val/GraphAtomVal.js.map +1 -1
- package/dist/val/HideFuncVal.js +0 -13
- package/dist/val/HideFuncVal.js.map +1 -1
- package/dist/val/IntegerVal.js +0 -61
- package/dist/val/IntegerVal.js.map +1 -1
- package/dist/val/JunctionVal.js +0 -20
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/KeyFuncVal.js +0 -46
- package/dist/val/KeyFuncVal.js.map +1 -1
- package/dist/val/ListVal.js +0 -57
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/LowerFuncVal.js +0 -11
- package/dist/val/LowerFuncVal.js.map +1 -1
- package/dist/val/MapVal.js +0 -151
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/MatchFuncVal.js +0 -27
- package/dist/val/MatchFuncVal.js.map +1 -1
- package/dist/val/{FormFuncVal.d.ts → MaybeFuncVal.d.ts} +5 -5
- package/dist/val/MaybeFuncVal.js +50 -0
- package/dist/val/MaybeFuncVal.js.map +1 -0
- package/dist/val/MoveFuncVal.js +0 -18
- package/dist/val/MoveFuncVal.js.map +1 -1
- package/dist/val/NilVal.js +0 -60
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/NomFuncVal.js +18 -54
- package/dist/val/NomFuncVal.js.map +1 -1
- package/dist/val/NumberVal.js +0 -15
- package/dist/val/NumberVal.js.map +1 -1
- package/dist/val/OpBaseVal.d.ts +1 -0
- package/dist/val/OpBaseVal.js +3 -15
- package/dist/val/OpBaseVal.js.map +1 -1
- package/dist/val/PackFuncVal.js +0 -34
- package/dist/val/PackFuncVal.js.map +1 -1
- package/dist/val/PathFuncVal.js +0 -6
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PathVal.js +0 -41
- package/dist/val/PathVal.js.map +1 -1
- package/dist/val/PlaceVal.js +0 -25
- package/dist/val/PlaceVal.js.map +1 -1
- package/dist/val/PlusOpVal.d.ts +1 -7
- package/dist/val/PlusOpVal.js +13 -74
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefFuncVal.js +0 -1
- package/dist/val/PrefFuncVal.js.map +1 -1
- package/dist/val/PrefVal.js +0 -167
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/RecurseVal.js +0 -55
- package/dist/val/RecurseVal.js.map +1 -1
- package/dist/val/RefVal.js +0 -282
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ReferFuncVal.js +3 -232
- package/dist/val/ReferFuncVal.js.map +1 -1
- package/dist/val/ScalarKindVal.js +0 -49
- package/dist/val/ScalarKindVal.js.map +1 -1
- package/dist/val/ScalarVal.js +0 -11
- package/dist/val/ScalarVal.js.map +1 -1
- package/dist/val/StrFuncVal.js +0 -18
- package/dist/val/StrFuncVal.js.map +1 -1
- package/dist/val/SuperFuncVal.js +0 -32
- package/dist/val/SuperFuncVal.js.map +1 -1
- package/dist/val/TopVal.js +0 -1
- package/dist/val/TopVal.js.map +1 -1
- package/dist/val/TranslateFuncVal.js +1 -3
- package/dist/val/TranslateFuncVal.js.map +1 -1
- package/dist/val/UpperFuncVal.js +0 -11
- package/dist/val/UpperFuncVal.js.map +1 -1
- package/dist/val/Val.d.ts +1 -0
- package/dist/val/Val.js +2 -133
- package/dist/val/Val.js.map +1 -1
- package/dist/val/VarVal.js +0 -12
- package/dist/val/VarVal.js.map +1 -1
- package/dist/val/arith.js +0 -37
- package/dist/val/arith.js.map +1 -1
- package/dist/val/caserange.js +0 -61
- package/dist/val/caserange.js.map +1 -1
- package/dist/val/members.js +0 -6
- package/dist/val/members.js.map +1 -1
- package/dist/val/numcmp.js +0 -11
- package/dist/val/numcmp.js.map +1 -1
- package/dist/val/numkind.js +0 -145
- package/dist/val/numkind.js.map +1 -1
- package/dist/val/valutil.js +0 -16
- package/dist/val/valutil.js.map +1 -1
- package/dist/vet.js +0 -461
- package/dist/vet.js.map +1 -1
- package/dist/view.js +0 -414
- package/dist/view.js.map +1 -1
- package/dist/walk.js +0 -41
- package/dist/walk.js.map +1 -1
- package/grammar/aontu.abnf +8 -6
- package/grammar/aontu.gbnf +4 -4
- package/grammar/aontu.lark +4 -4
- package/grammar/aontu.tmLanguage.json +1 -1
- package/package.json +4 -2
- package/skill/tasks.md +9 -7
- package/src/agentsmd.ts +0 -35
- package/src/alias.ts +0 -39
- package/src/allow.ts +1 -96
- package/src/aontu.ts +4 -116
- package/src/aontumodel.ts +26 -0
- package/src/casing.ts +95 -0
- package/src/cli.ts +258 -1024
- package/src/ctx.ts +0 -103
- package/src/diff.ts +0 -40
- package/src/err.ts +0 -40
- package/src/escape.ts +0 -46
- package/src/exactjson.ts +0 -131
- package/src/format.ts +14 -257
- package/src/grammar.ts +72 -0
- package/src/graph.ts +0 -61
- package/src/hcanon.ts +0 -82
- package/src/helpdoc.ts +2 -2
- package/src/hints.ts +69 -57
- package/src/jsonschema.ts +0 -123
- package/src/keyorder.ts +0 -42
- package/src/lang.ts +19 -931
- package/src/lsp-server.ts +0 -16
- package/src/lsp.ts +12 -180
- package/src/mcp-server.ts +0 -31
- package/src/mcp.ts +0 -169
- package/src/mod-tool.ts +18 -159
- package/src/mod.ts +0 -178
- package/src/patch.ts +0 -232
- package/src/profile.ts +42 -0
- package/src/provenance.ts +0 -183
- package/src/query.ts +0 -84
- package/src/reach.ts +0 -53
- package/src/relation.ts +0 -84
- package/src/report-sarif.ts +0 -48
- package/src/sig.ts +0 -35
- package/src/sigdecl.ts +1 -1
- package/src/siggate.ts +0 -30
- package/src/site.ts +3 -29
- package/src/subsume.ts +1 -161
- package/src/template.ts +69 -140
- package/src/trace.ts +157 -0
- package/src/trim.ts +0 -53
- package/src/type.ts +2 -45
- package/src/unify.ts +14 -257
- package/src/utility.ts +0 -31
- package/src/val/AbnfFuncVal.ts +181 -0
- package/src/val/AbsentVal.ts +54 -0
- package/src/val/AggFuncVal.ts +152 -188
- package/src/val/ArithFuncVal.ts +0 -20
- package/src/val/BagVal.ts +1 -78
- package/src/val/BigDecimalVal.ts +0 -16
- package/src/val/BigIntegerVal.ts +0 -16
- package/src/val/CloseFuncVal.ts +0 -9
- package/src/val/CmpFuncVal.ts +68 -184
- package/src/val/ConjunctVal.ts +0 -33
- package/src/val/ConstraintVal.ts +2 -537
- package/src/val/ContainerKindVal.ts +0 -18
- package/src/val/CopyFuncVal.ts +0 -5
- package/src/val/Decimal.ts +1 -185
- package/src/val/DeprecateFuncVal.ts +0 -10
- package/src/val/DisjunctVal.ts +0 -157
- package/src/val/EachFuncVal.ts +0 -40
- package/src/val/EmitFuncVal.ts +8 -208
- package/src/val/ExpectVal.ts +0 -62
- package/src/val/FilterFuncVal.ts +0 -55
- package/src/val/FuncBaseVal.ts +9 -130
- package/src/val/GraphAtomVal.ts +0 -42
- package/src/val/HideFuncVal.ts +0 -15
- package/src/val/IntegerVal.ts +0 -61
- package/src/val/JunctionVal.ts +0 -20
- package/src/val/KeyFuncVal.ts +0 -48
- package/src/val/ListVal.ts +0 -59
- package/src/val/LowerFuncVal.ts +0 -12
- package/src/val/MapVal.ts +0 -151
- package/src/val/MatchFuncVal.ts +0 -59
- package/src/val/MaybeFuncVal.ts +86 -0
- package/src/val/MoveFuncVal.ts +0 -20
- package/src/val/NilVal.ts +0 -60
- package/src/val/NomFuncVal.ts +10 -99
- package/src/val/NumberVal.ts +0 -16
- package/src/val/OpBaseVal.ts +4 -17
- package/src/val/PackFuncVal.ts +0 -63
- package/src/val/PathFuncVal.ts +0 -32
- package/src/val/PathVal.ts +0 -66
- package/src/val/PlaceVal.ts +0 -45
- package/src/val/PlusOpVal.ts +18 -75
- package/src/val/PrefFuncVal.ts +0 -1
- package/src/val/PrefVal.ts +0 -179
- package/src/val/RecurseVal.ts +0 -81
- package/src/val/RefVal.ts +1 -285
- package/src/val/ReferFuncVal.ts +4 -255
- package/src/val/ScalarKindVal.ts +0 -50
- package/src/val/ScalarVal.ts +0 -12
- package/src/val/StrFuncVal.ts +0 -44
- package/src/val/SuperFuncVal.ts +0 -42
- package/src/val/TopVal.ts +0 -1
- package/src/val/TranslateFuncVal.ts +1 -51
- package/src/val/UpperFuncVal.ts +0 -12
- package/src/val/Val.ts +3 -192
- package/src/val/VarVal.ts +0 -15
- package/src/val/arith.ts +0 -92
- package/src/val/caserange.ts +0 -62
- package/src/val/members.ts +0 -23
- package/src/val/numcmp.ts +1 -27
- package/src/val/numkind.ts +0 -149
- package/src/val/valutil.ts +0 -16
- package/src/vet.ts +1 -582
- package/src/view.ts +0 -507
- package/src/walk.ts +0 -41
- package/dist/lower.d.ts +0 -23
- package/dist/lower.js +0 -578
- package/dist/lower.js.map +0 -1
- package/dist/render.d.ts +0 -53
- package/dist/render.js +0 -547
- package/dist/render.js.map +0 -1
- package/dist/std.d.ts +0 -3
- package/dist/std.js +0 -672
- package/dist/std.js.map +0 -1
- package/dist/val/FormFuncVal.js +0 -55
- package/dist/val/FormFuncVal.js.map +0 -1
- package/dist/val/NamerFuncVal.d.ts +0 -12
- package/dist/val/NamerFuncVal.js +0 -176
- package/dist/val/NamerFuncVal.js.map +0 -1
- package/src/lower.ts +0 -636
- package/src/render.ts +0 -732
- package/src/std.ts +0 -683
package/src/walk.ts
CHANGED
|
@@ -1,22 +1,5 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
// One tree walk, two consumers: the language server collects NilVals
|
|
4
|
-
// for diagnostics (ts/src/lsp.ts) and the validation verb both stamps
|
|
5
|
-
// provenance and collects NilVals for findings (ts/src/vet.ts). They had
|
|
6
|
-
// the same traversal written out twice, which is one copy too many for
|
|
7
|
-
// something with three easy ways to be subtly wrong:
|
|
8
|
-
//
|
|
9
|
-
// - a Val's children live under `peg`, which is an ARRAY for lists,
|
|
10
|
-
// conjuncts and disjuncts, and an OBJECT for maps;
|
|
11
|
-
// - a spread constraint lives OFF-peg (`spread.cj`), so a value inside
|
|
12
|
-
// a `&:` template is reachable only by following it deliberately;
|
|
13
|
-
// - the `seen` set is a termination guard, not an optimisation, and
|
|
14
|
-
// the non-Val guard is load-bearing too: a peg object can hold
|
|
15
|
-
// entries that are not Vals.
|
|
16
|
-
//
|
|
17
|
-
// The visitor returns false to prune the subtree below a node, which is
|
|
18
|
-
// how a nil collector stops at the nil rather than walking into the
|
|
19
|
-
// operands it carries.
|
|
20
3
|
|
|
21
4
|
export function walkVals(
|
|
22
5
|
v: any,
|
|
@@ -52,40 +35,16 @@ export function walkVals(
|
|
|
52
35
|
walkVals(spread, visit, seen)
|
|
53
36
|
}
|
|
54
37
|
|
|
55
|
-
// OFF-PEG VALUES THAT CAN BE REPORTED. A preference carries the type
|
|
56
|
-
// yardstick it derived from its own value, and a `must` carries the
|
|
57
|
-
// value it checks against; neither is a peg entry, and both can end
|
|
58
|
-
// up as an operand of a failure — the preference's yardstick is what
|
|
59
|
-
// `*1 & {}` conflicts with. A caller
|
|
60
|
-
// that stamps provenance (ts/src/vet.ts) has to reach them, or a
|
|
61
|
-
// report names the document such a value came from as "unknown",
|
|
62
|
-
// and the two ports disagree about it (go/walk.go does the same).
|
|
63
38
|
walkVals(v.superpeg, visit, seen)
|
|
64
39
|
for (const must of (v.musts ?? [])) {
|
|
65
40
|
walkVals(must?.v, visit, seen)
|
|
66
41
|
}
|
|
67
42
|
|
|
68
|
-
// A FAILURE'S OPERANDS, for the same reason and with the same
|
|
69
|
-
// safety. They are not peg entries, and they are exactly what a
|
|
70
|
-
// report names: a finding's sites are the nil's primary and
|
|
71
|
-
// secondary (ts/src/vet.ts, siteOf). A visitor that PRUNES at a nil
|
|
72
|
-
// never gets here -- collectNils returns false and this line is
|
|
73
|
-
// behind that gate -- so a nil collector is unaffected. A visitor
|
|
74
|
-
// that does not prune, and stamping provenance is the one that does
|
|
75
|
-
// not, must reach them or a broken schema's finding names no file at
|
|
76
|
-
// all (go/walk.go does the same).
|
|
77
43
|
walkVals(v.primary, visit, seen)
|
|
78
44
|
walkVals(v.secondary, visit, seen)
|
|
79
45
|
}
|
|
80
46
|
|
|
81
47
|
|
|
82
|
-
// Every NilVal in the tree, in walk order. Callers that need a stable
|
|
83
|
-
// order across the two ports must sort — the walk follows raw key
|
|
84
|
-
// order, and the hosts disagree about that (ts/src/keyorder.ts).
|
|
85
|
-
//
|
|
86
|
-
// The `seen` set is the caller's, not an internal detail: both callers
|
|
87
|
-
// go on to dedup context-only errors against the nils already found,
|
|
88
|
-
// which is only possible if they hold the set.
|
|
89
48
|
export function collectNils(root: any, seen: Set<any>): any[] {
|
|
90
49
|
const out: any[] = []
|
|
91
50
|
walkVals(root, (v: any) => {
|
package/dist/lower.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { RenderLoss } from './render';
|
|
2
|
-
export type LowerCtx = {
|
|
3
|
-
profile: any;
|
|
4
|
-
family: string;
|
|
5
|
-
unit: string;
|
|
6
|
-
lossy: RenderLoss[];
|
|
7
|
-
};
|
|
8
|
-
export declare function splitWords(name: string): string[];
|
|
9
|
-
export declare function lowerASCII(s: string): string;
|
|
10
|
-
export declare function upperASCII(s: string): string;
|
|
11
|
-
export declare function capitalise(word: string, acronyms: string[]): string;
|
|
12
|
-
export declare function caseName(name: string, style: string, acronyms: string[]): string;
|
|
13
|
-
export declare function ident(name: string, role: string, ctx: LowerCtx, path: string, bare: boolean): string;
|
|
14
|
-
export declare function quote(s: string, profile: any): string;
|
|
15
|
-
export declare function literal(v: any, ctx: LowerCtx): string;
|
|
16
|
-
type Expr = {
|
|
17
|
-
text: string;
|
|
18
|
-
prec: number;
|
|
19
|
-
};
|
|
20
|
-
export declare function typeExpr(t: any, ctx: LowerCtx, path: string): Expr;
|
|
21
|
-
export declare function lowerHeader(unit: any, source: any, ctx: LowerCtx): any[];
|
|
22
|
-
export declare function lowerDecl(decl: any, path: string, ctx: LowerCtx): any[];
|
|
23
|
-
export {};
|
package/dist/lower.js
DELETED
|
@@ -1,578 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.splitWords = splitWords;
|
|
5
|
-
exports.lowerASCII = lowerASCII;
|
|
6
|
-
exports.upperASCII = upperASCII;
|
|
7
|
-
exports.capitalise = capitalise;
|
|
8
|
-
exports.caseName = caseName;
|
|
9
|
-
exports.ident = ident;
|
|
10
|
-
exports.quote = quote;
|
|
11
|
-
exports.literal = literal;
|
|
12
|
-
exports.typeExpr = typeExpr;
|
|
13
|
-
exports.lowerHeader = lowerHeader;
|
|
14
|
-
exports.lowerDecl = lowerDecl;
|
|
15
|
-
// THE DECLARATION LOWERING (docs/design/RENDER.0.md D5, D6, P5): the
|
|
16
|
-
// one place in the renderer where "a new language is data" does not
|
|
17
|
-
// hold. A `%record` becoming `export interface X {` or `type X struct
|
|
18
|
-
// {` is a per-language-family function here, selected by the profile's
|
|
19
|
-
// `lowering` field and parameterised by the profile's data -- the
|
|
20
|
-
// indent, the comment forms, the string quote and its escape table, the
|
|
21
|
-
// identifier rules and the type forms. Two families ship, `typescript`
|
|
22
|
-
// and `go`; a third language with declarations is a change here, in
|
|
23
|
-
// both ports (go/lower.go is the twin, function for function).
|
|
24
|
-
//
|
|
25
|
-
// Everything produced is PIECES -- lines at a depth, blanks -- that the
|
|
26
|
-
// fragment fold then turns into bytes, so a lowered declaration and a
|
|
27
|
-
// fragment take the same path to the file: one indent rule, one
|
|
28
|
-
// terminator rule, nothing trimmed.
|
|
29
|
-
//
|
|
30
|
-
// THE PARITY GUARDS (G9 section 3), each a rule both ports keep: case
|
|
31
|
-
// conversion is ASCII-only, and a code point at or above U+0080 rides
|
|
32
|
-
// into the current word verbatim, never split and never converted;
|
|
33
|
-
// string escaping is one pass, per code point, through the profile's
|
|
34
|
-
// table, keyed by decimal code point, with a control character the
|
|
35
|
-
// table does not name spelled as a \u escape; a reserved word is
|
|
36
|
-
// matched by exact equality on the converted name; parenthesisation is
|
|
37
|
-
// by `prec`/`childPrec`; numbers go through `exactJSON`; nothing here
|
|
38
|
-
// sorts, and nothing iterates a map.
|
|
39
|
-
const exactjson_1 = require("./exactjson");
|
|
40
|
-
function ln(at, text) {
|
|
41
|
-
return { k: 'line', at, of: [text] };
|
|
42
|
-
}
|
|
43
|
-
const BLANK = { k: 'blank' };
|
|
44
|
-
// --- identifiers -------------------------------------------------------
|
|
45
|
-
function isUpper(c) {
|
|
46
|
-
return 'A' <= c && c <= 'Z';
|
|
47
|
-
}
|
|
48
|
-
function isLower(c) {
|
|
49
|
-
return 'a' <= c && c <= 'z';
|
|
50
|
-
}
|
|
51
|
-
function isDigit(c) {
|
|
52
|
-
return '0' <= c && c <= '9';
|
|
53
|
-
}
|
|
54
|
-
function isASCII(c) {
|
|
55
|
-
return c.codePointAt(0) < 0x80;
|
|
56
|
-
}
|
|
57
|
-
// THE ASCII WORD SPLITTER. Words break at `_`, `-` and space, at a
|
|
58
|
-
// lower-to-upper boundary (`creditLimit`), at a letter-to-digit
|
|
59
|
-
// boundary in either direction (`utf8String`), and before the last
|
|
60
|
-
// capital of a capital run that a lower case letter follows
|
|
61
|
-
// (`HTTPServer` is HTTP, Server). A code point at or above U+0080
|
|
62
|
-
// rides into the current word and never starts, ends or converts one.
|
|
63
|
-
function splitWords(name) {
|
|
64
|
-
const words = [];
|
|
65
|
-
let cur = '';
|
|
66
|
-
const chars = Array.from(name);
|
|
67
|
-
for (let i = 0; i < chars.length; i++) {
|
|
68
|
-
const c = chars[i];
|
|
69
|
-
if ('_' === c || '-' === c || ' ' === c) {
|
|
70
|
-
if ('' !== cur) {
|
|
71
|
-
words.push(cur);
|
|
72
|
-
}
|
|
73
|
-
cur = '';
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
if ('' !== cur) {
|
|
77
|
-
const prev = chars[i - 1];
|
|
78
|
-
const next = chars[i + 1];
|
|
79
|
-
const boundary = isASCII(c) && isASCII(prev) && ((isUpper(c) && (isLower(prev) || isDigit(prev))) ||
|
|
80
|
-
(isDigit(c) !== isDigit(prev)) ||
|
|
81
|
-
(isUpper(c) && isUpper(prev) && undefined !== next && isLower(next)));
|
|
82
|
-
if (boundary) {
|
|
83
|
-
words.push(cur);
|
|
84
|
-
cur = '';
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
cur += c;
|
|
88
|
-
}
|
|
89
|
-
if ('' !== cur) {
|
|
90
|
-
words.push(cur);
|
|
91
|
-
}
|
|
92
|
-
return words;
|
|
93
|
-
}
|
|
94
|
-
function lowerASCII(s) {
|
|
95
|
-
return Array.from(s).map((c) => isUpper(c) ? String.fromCharCode(c.charCodeAt(0) + 32) : c).join('');
|
|
96
|
-
}
|
|
97
|
-
function upperASCII(s) {
|
|
98
|
-
return Array.from(s).map((c) => isLower(c) ? String.fromCharCode(c.charCodeAt(0) - 32) : c).join('');
|
|
99
|
-
}
|
|
100
|
-
// A word capitalised: the acronym set wins, so `id` is `ID` under a
|
|
101
|
-
// profile that lists it and `Id` under one that does not.
|
|
102
|
-
function capitalise(word, acronyms) {
|
|
103
|
-
const low = lowerASCII(word);
|
|
104
|
-
for (const a of acronyms) {
|
|
105
|
-
if (lowerASCII(a) === low) {
|
|
106
|
-
return a;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
const chars = Array.from(low);
|
|
110
|
-
return upperASCII(chars[0]) + chars.slice(1).join('');
|
|
111
|
-
}
|
|
112
|
-
// THE CASE STYLES of aontu:profile's %case, over the words.
|
|
113
|
-
function caseName(name, style, acronyms) {
|
|
114
|
-
if ('as-is' === style) {
|
|
115
|
-
return name;
|
|
116
|
-
}
|
|
117
|
-
const words = splitWords(name);
|
|
118
|
-
if (0 === words.length) {
|
|
119
|
-
return name;
|
|
120
|
-
}
|
|
121
|
-
if ('snake' === style) {
|
|
122
|
-
return words.map(lowerASCII).join('_');
|
|
123
|
-
}
|
|
124
|
-
if ('screaming' === style) {
|
|
125
|
-
return words.map(upperASCII).join('_');
|
|
126
|
-
}
|
|
127
|
-
if ('kebab' === style) {
|
|
128
|
-
return words.map(lowerASCII).join('-');
|
|
129
|
-
}
|
|
130
|
-
const caps = words.map((w) => capitalise(w, acronyms));
|
|
131
|
-
if ('pascal' === style) {
|
|
132
|
-
return caps.join('');
|
|
133
|
-
}
|
|
134
|
-
// camel: the first word lower, and never an acronym.
|
|
135
|
-
return lowerASCII(words[0]) + caps.slice(1).join('');
|
|
136
|
-
}
|
|
137
|
-
// An identifier in a ROLE (record, field, enum, member, const, func,
|
|
138
|
-
// param, alias): the profile's case style for the role, then -- for
|
|
139
|
-
// the names that become bare identifiers, declarations and parameters
|
|
140
|
-
// -- the reserved-word rule on the converted name, exact equality, so
|
|
141
|
-
// Go's `Type` is not `type`. A reserved name is renamed with a trailing
|
|
142
|
-
// underscore and the report says so, since code that named the
|
|
143
|
-
// original will not compile against the rename. A field is a property,
|
|
144
|
-
// and a property may spell what its target's string form admits.
|
|
145
|
-
function ident(name, role, ctx, path, bare) {
|
|
146
|
-
const rules = ctx.profile.ident ?? {};
|
|
147
|
-
const style = rules.case?.[role] ?? 'as-is';
|
|
148
|
-
const acronyms = rules.acronyms ?? [];
|
|
149
|
-
let out = caseName(name, style, acronyms);
|
|
150
|
-
if (bare && (rules.reserved ?? []).includes(out)) {
|
|
151
|
-
ctx.lossy.push({
|
|
152
|
-
unit: ctx.unit, path, tier: 1, construct: 'reserved',
|
|
153
|
-
reason: out + ' is reserved in ' + ctx.profile.lang + '; renamed ' + out + '_',
|
|
154
|
-
});
|
|
155
|
-
out += '_';
|
|
156
|
-
}
|
|
157
|
-
return out;
|
|
158
|
-
}
|
|
159
|
-
// --- literals ----------------------------------------------------------
|
|
160
|
-
function hex4(n) {
|
|
161
|
-
return '\\u' + n.toString(16).padStart(4, '0');
|
|
162
|
-
}
|
|
163
|
-
// A string literal: the profile's quote, and one pass over the code
|
|
164
|
-
// points through its escape table. A control character the table does
|
|
165
|
-
// not name is a \u escape; so are the quote and the backslash when the
|
|
166
|
-
// table is silent about them; everything else, non-ASCII and astral
|
|
167
|
-
// included, is verbatim.
|
|
168
|
-
function quote(s, profile) {
|
|
169
|
-
const q = profile.str?.quote ?? '"';
|
|
170
|
-
const table = profile.str?.escape ?? {};
|
|
171
|
-
let out = q;
|
|
172
|
-
for (const c of Array.from(s)) {
|
|
173
|
-
const cp = c.codePointAt(0);
|
|
174
|
-
const esc = table[String(cp)];
|
|
175
|
-
if ('string' === typeof esc) {
|
|
176
|
-
out += esc;
|
|
177
|
-
}
|
|
178
|
-
else if (cp < 0x20 || 0x7f === cp || c === q || '\\' === c) {
|
|
179
|
-
out += hex4(cp);
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
out += c;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
return out + q;
|
|
186
|
-
}
|
|
187
|
-
// A literal value as the target spells it: a string quoted, a number
|
|
188
|
-
// through exactJSON (no second number formatter), a boolean as is, and
|
|
189
|
-
// null as the family's null.
|
|
190
|
-
function literal(v, ctx) {
|
|
191
|
-
if ('string' === typeof v) {
|
|
192
|
-
return quote(v, ctx.profile);
|
|
193
|
-
}
|
|
194
|
-
if (null === v) {
|
|
195
|
-
return 'go' === ctx.family ? 'nil' : 'null';
|
|
196
|
-
}
|
|
197
|
-
if ('boolean' === typeof v) {
|
|
198
|
-
return v ? 'true' : 'false';
|
|
199
|
-
}
|
|
200
|
-
return (0, exactjson_1.exactJSON)(v);
|
|
201
|
-
}
|
|
202
|
-
function form(ctx, name) {
|
|
203
|
-
return ctx.profile.types?.[name] ?? { open: '', close: '', prec: 9, childPrec: 0 };
|
|
204
|
-
}
|
|
205
|
-
// An inner expression under a form, in parens when its precedence is
|
|
206
|
-
// below the form's childPrec: TypeScript's `(string | null)[]`.
|
|
207
|
-
//
|
|
208
|
-
// A FORM ALWAYS CARRIES ITS childPrec, so there is nothing to fall back
|
|
209
|
-
// to: the profile vocabulary declares it `*0`, so every type form of a
|
|
210
|
-
// profile met with `aontu:profile` has one, and `form()`'s own fallback
|
|
211
|
-
// spells it. The default lives in the model, which is the point of
|
|
212
|
-
// putting it there.
|
|
213
|
-
function under(inner, f) {
|
|
214
|
-
return inner.prec < f.childPrec ? '(' + inner.text + ')' : inner.text;
|
|
215
|
-
}
|
|
216
|
-
function loss(ctx, path, construct, reason) {
|
|
217
|
-
ctx.lossy.push({ unit: ctx.unit, path, tier: 1, construct, reason });
|
|
218
|
-
}
|
|
219
|
-
// The primitive kind a literal set shares, for a family with no
|
|
220
|
-
// literal type: strings, integers, floats, booleans, null, or any.
|
|
221
|
-
function litPrim(of) {
|
|
222
|
-
const kinds = of.map((v) => null === v ? 'null' : typeof v);
|
|
223
|
-
const first = kinds[0];
|
|
224
|
-
if (!kinds.every((k) => k === first)) {
|
|
225
|
-
return 'any';
|
|
226
|
-
}
|
|
227
|
-
if ('number' === first) {
|
|
228
|
-
return of.every((v) => Number.isInteger(v)) ? 'int' : 'float';
|
|
229
|
-
}
|
|
230
|
-
return 'string' === first ? 'string' : 'boolean' === first ? 'bool' : 'null';
|
|
231
|
-
}
|
|
232
|
-
function prim(ctx, name) {
|
|
233
|
-
return ctx.profile.types?.prim?.[name] ?? name;
|
|
234
|
-
}
|
|
235
|
-
// THE TYPE EXPRESSION, from the profile's type forms (D6): an atom has
|
|
236
|
-
// prec 9; a form is `open + inner + close`, its precedence its own, its
|
|
237
|
-
// inner parenthesised below childPrec. A `text` leaf is verbatim
|
|
238
|
-
// target syntax and tier 3, as a text declaration is.
|
|
239
|
-
function typeExpr(t, ctx, path) {
|
|
240
|
-
const k = t.k;
|
|
241
|
-
if ('prim' === k) {
|
|
242
|
-
return { text: prim(ctx, t.prim), prec: 9 };
|
|
243
|
-
}
|
|
244
|
-
if ('ref' === k) {
|
|
245
|
-
return { text: ident(t.name, 'record', ctx, path, false), prec: 9 };
|
|
246
|
-
}
|
|
247
|
-
if ('text' === k) {
|
|
248
|
-
ctx.lossy.push({
|
|
249
|
-
unit: ctx.unit, path, tier: 3, construct: 'text',
|
|
250
|
-
reason: 'verbatim ' + t.lang + ': the renderer checks nothing in it',
|
|
251
|
-
});
|
|
252
|
-
return { text: t.text, prec: 9 };
|
|
253
|
-
}
|
|
254
|
-
if ('list' === k) {
|
|
255
|
-
const f = form(ctx, 'list');
|
|
256
|
-
return { text: f.open + under(typeExpr(t.of, ctx, path + '.of'), f) + f.close, prec: f.prec };
|
|
257
|
-
}
|
|
258
|
-
if ('map' === k) {
|
|
259
|
-
const f = form(ctx, 'map');
|
|
260
|
-
const key = under(typeExpr(t.key, ctx, path + '.key'), f);
|
|
261
|
-
const of = under(typeExpr(t.of, ctx, path + '.of'), f);
|
|
262
|
-
// The two families spell a map differently between the key and
|
|
263
|
-
// the value: `map[K]V` and `Record<K, V>`.
|
|
264
|
-
const sep = 'go' === ctx.family ? ']' : ', ';
|
|
265
|
-
return { text: f.open + key + sep + of + f.close, prec: f.prec };
|
|
266
|
-
}
|
|
267
|
-
if ('opt' === k) {
|
|
268
|
-
const f = form(ctx, 'opt');
|
|
269
|
-
return { text: f.open + under(typeExpr(t.of, ctx, path + '.of'), f) + f.close, prec: f.prec };
|
|
270
|
-
}
|
|
271
|
-
if ('union' === k) {
|
|
272
|
-
if ('go' === ctx.family) {
|
|
273
|
-
loss(ctx, path, 'union', 'go has no union type: any');
|
|
274
|
-
return { text: prim(ctx, 'any'), prec: 9 };
|
|
275
|
-
}
|
|
276
|
-
const f = form(ctx, 'union');
|
|
277
|
-
const members = t.of.map((m, i) => under(typeExpr(m, ctx, path + '.of.' + i), f));
|
|
278
|
-
return { text: f.open + members.join(' | ') + f.close, prec: f.prec };
|
|
279
|
-
}
|
|
280
|
-
// lit
|
|
281
|
-
if ('go' === ctx.family) {
|
|
282
|
-
const p = litPrim(t.of);
|
|
283
|
-
loss(ctx, path, 'lit', 'go has no literal type: ' + p);
|
|
284
|
-
return { text: prim(ctx, p), prec: 9 };
|
|
285
|
-
}
|
|
286
|
-
const f = form(ctx, 'lit');
|
|
287
|
-
const lits = t.of.map((v) => literal(v, ctx));
|
|
288
|
-
return { text: f.open + lits.join(' | ') + f.close, prec: f.prec };
|
|
289
|
-
}
|
|
290
|
-
// --- comments ----------------------------------------------------------
|
|
291
|
-
// A doc comment as pieces at a depth: the profile's doc form -- open,
|
|
292
|
-
// a prefix per line, close -- and the line form when a profile has no
|
|
293
|
-
// doc form. A deprecation is the last line, in the family's spelling.
|
|
294
|
-
function doc(d, at, ctx) {
|
|
295
|
-
if (null == d) {
|
|
296
|
-
return [];
|
|
297
|
-
}
|
|
298
|
-
const forms = ctx.profile.comment ?? {};
|
|
299
|
-
const f = forms.doc ?? forms.line ?? { prefix: '// ' };
|
|
300
|
-
const prefix = f.prefix ?? '';
|
|
301
|
-
const lines = String(d.text).split('\n');
|
|
302
|
-
if (null != d.deprecated) {
|
|
303
|
-
const dep = d.deprecated;
|
|
304
|
-
const note = [dep.msg, dep.use ? 'use ' + dep.use : '', dep.since ? 'since ' + dep.since : '']
|
|
305
|
-
.filter((s) => s).join('; ');
|
|
306
|
-
lines.push('go' === ctx.family ? 'Deprecated: ' + note : '@deprecated ' + note);
|
|
307
|
-
}
|
|
308
|
-
const out = [];
|
|
309
|
-
if (null != f.open) {
|
|
310
|
-
out.push(ln(at, f.open));
|
|
311
|
-
}
|
|
312
|
-
for (const l of lines) {
|
|
313
|
-
out.push(ln(at, (prefix + l).replace(/[ \t]+$/, '')));
|
|
314
|
-
}
|
|
315
|
-
if (null != f.close) {
|
|
316
|
-
out.push(ln(at, f.close));
|
|
317
|
-
}
|
|
318
|
-
return out;
|
|
319
|
-
}
|
|
320
|
-
// Every check a target's type system cannot enforce is tier-1 loss,
|
|
321
|
-
// one entry per check, addressed at the check.
|
|
322
|
-
function checks(list, path, ctx) {
|
|
323
|
-
(list ?? []).forEach((c, i) => {
|
|
324
|
-
loss(ctx, path + '.check.' + i, 'check', 'the check ' + c.c + ' is not enforced by the ' + ctx.profile.lang + ' type system');
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
// --- the unit header ---------------------------------------------------
|
|
328
|
-
// The path from one unit's directory to another unit, for a TypeScript
|
|
329
|
-
// import: `./other` beside, `../shared/x` across, the extension gone.
|
|
330
|
-
function relImport(from, to) {
|
|
331
|
-
const a = from.split('/').slice(0, -1);
|
|
332
|
-
const b = to.split('/');
|
|
333
|
-
const file = b.pop().replace(/\.[^.]*$/, '');
|
|
334
|
-
let i = 0;
|
|
335
|
-
while (i < a.length && i < b.length && a[i] === b[i]) {
|
|
336
|
-
i++;
|
|
337
|
-
}
|
|
338
|
-
const up = a.slice(i).map(() => '..');
|
|
339
|
-
const parts = [...up, ...b.slice(i), file];
|
|
340
|
-
return (0 === up.length ? './' : '') + parts.join('/');
|
|
341
|
-
}
|
|
342
|
-
// Imports derived from `{k:"ref", unit}` nodes, in order of first
|
|
343
|
-
// appearance, grouped by unit -- TypeScript only: a Go reference names
|
|
344
|
-
// a type in the same package.
|
|
345
|
-
function derivedImports(unit) {
|
|
346
|
-
const groups = [];
|
|
347
|
-
const visit = (t) => {
|
|
348
|
-
if (null == t || 'object' !== typeof t) {
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
if (Array.isArray(t)) {
|
|
352
|
-
t.forEach(visit);
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
if ('ref' === t.k && 'string' === typeof t.unit) {
|
|
356
|
-
let g = groups.find((x) => x.from === t.unit);
|
|
357
|
-
if (undefined === g) {
|
|
358
|
-
g = { from: t.unit, names: [] };
|
|
359
|
-
groups.push(g);
|
|
360
|
-
}
|
|
361
|
-
if (!g.names.includes(t.name)) {
|
|
362
|
-
g.names.push(t.name);
|
|
363
|
-
}
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
for (const key of ['type', 'of', 'key', 'returns', 'fields', 'params']) {
|
|
367
|
-
visit(t[key]);
|
|
368
|
-
}
|
|
369
|
-
};
|
|
370
|
-
visit(unit.decls);
|
|
371
|
-
return groups;
|
|
372
|
-
}
|
|
373
|
-
// The banner from `code.source`, the package clause, and the imports:
|
|
374
|
-
// what stands before the declarations, each part followed by a blank.
|
|
375
|
-
function lowerHeader(unit, source, ctx) {
|
|
376
|
-
const parts = [];
|
|
377
|
-
const banner = ctx.profile.banner;
|
|
378
|
-
if (null != banner && null != source?.path) {
|
|
379
|
-
const prefix = ctx.profile.comment?.line?.prefix ?? '';
|
|
380
|
-
parts.push([prefix + banner.split('{path}').join(source.path)
|
|
381
|
-
.split('{hash}').join(source.hash ?? '')]);
|
|
382
|
-
}
|
|
383
|
-
if ('go' === ctx.family && 'string' === typeof unit.pkg) {
|
|
384
|
-
parts.push(['package ' + unit.pkg]);
|
|
385
|
-
}
|
|
386
|
-
const imports = [...(unit.imports ?? [])];
|
|
387
|
-
if ('typescript' === ctx.family) {
|
|
388
|
-
for (const g of derivedImports(unit)) {
|
|
389
|
-
imports.push({
|
|
390
|
-
from: relImport(unit.path, g.from),
|
|
391
|
-
names: g.names.map((n) => ident(n, 'record', ctx, '', false)),
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
if (0 < imports.length) {
|
|
396
|
-
const lines = [];
|
|
397
|
-
if ('go' === ctx.family) {
|
|
398
|
-
const spell = (im) => (null == im.alias ? '' : im.alias + ' ') + quote(im.from, ctx.profile);
|
|
399
|
-
if (1 === imports.length) {
|
|
400
|
-
lines.push('import ' + spell(imports[0]));
|
|
401
|
-
}
|
|
402
|
-
else {
|
|
403
|
-
lines.push('import (');
|
|
404
|
-
for (const im of imports) {
|
|
405
|
-
lines.push(ln(1, spell(im)));
|
|
406
|
-
}
|
|
407
|
-
lines.push(')');
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
else {
|
|
411
|
-
for (const im of imports) {
|
|
412
|
-
const from = quote(im.from, ctx.profile);
|
|
413
|
-
if (Array.isArray(im.names) && 0 < im.names.length) {
|
|
414
|
-
lines.push('import { ' + im.names.join(', ') + ' } from ' + from + ';');
|
|
415
|
-
}
|
|
416
|
-
else if (null != im.alias) {
|
|
417
|
-
lines.push('import * as ' + im.alias + ' from ' + from + ';');
|
|
418
|
-
}
|
|
419
|
-
else {
|
|
420
|
-
lines.push('import ' + from + ';');
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
parts.push(lines);
|
|
425
|
-
}
|
|
426
|
-
// The parts, a blank between each two; the fold puts the blank
|
|
427
|
-
// after the last when a declaration follows.
|
|
428
|
-
const out = [];
|
|
429
|
-
parts.forEach((part, i) => {
|
|
430
|
-
if (0 < i) {
|
|
431
|
-
out.push(BLANK);
|
|
432
|
-
}
|
|
433
|
-
out.push(...part);
|
|
434
|
-
});
|
|
435
|
-
return out;
|
|
436
|
-
}
|
|
437
|
-
// --- declarations ------------------------------------------------------
|
|
438
|
-
// A body fragment's pieces, one level deeper: a bare string is a line
|
|
439
|
-
// at depth 1, a line or a raw keeps its shape at `at + 1`, a blank is
|
|
440
|
-
// a blank.
|
|
441
|
-
function nest(pieces) {
|
|
442
|
-
return pieces.map((p) => 'string' === typeof p ? ln(1, p)
|
|
443
|
-
: 'blank' === p.k ? p : { ...p, at: (p.at ?? 0) + 1 });
|
|
444
|
-
}
|
|
445
|
-
function params(list, ctx, path) {
|
|
446
|
-
return list.map((p, i) => {
|
|
447
|
-
const ppath = path + '.params.' + i;
|
|
448
|
-
const name = ident(p.name, 'param', ctx, ppath + '.name', true);
|
|
449
|
-
const type = typeExpr(p.type, ctx, ppath + '.type').text;
|
|
450
|
-
if ('go' === ctx.family) {
|
|
451
|
-
if (undefined !== p.default) {
|
|
452
|
-
loss(ctx, ppath + '.default', 'default', 'go has no default parameter: the default of ' + p.name + ' is dropped');
|
|
453
|
-
}
|
|
454
|
-
return name + ' ' + type;
|
|
455
|
-
}
|
|
456
|
-
return name + ': ' + type +
|
|
457
|
-
(undefined === p.default ? '' : ' = ' + literal(p.default, ctx));
|
|
458
|
-
}).join(', ');
|
|
459
|
-
}
|
|
460
|
-
// The lowering of one declaration to pieces. A `frag` and a `text`
|
|
461
|
-
// never arrive here: the fold takes those itself.
|
|
462
|
-
function lowerDecl(decl, path, ctx) {
|
|
463
|
-
const go = 'go' === ctx.family;
|
|
464
|
-
const out = [];
|
|
465
|
-
const k = decl.k;
|
|
466
|
-
if ('record' === k) {
|
|
467
|
-
const name = ident(decl.name, 'record', ctx, path + '.name', true);
|
|
468
|
-
out.push(...doc(decl.doc, 0, ctx));
|
|
469
|
-
out.push(go ? 'type ' + name + ' struct {' : 'export interface ' + name + ' {');
|
|
470
|
-
decl.fields.forEach((f, i) => {
|
|
471
|
-
const fpath = path + '.fields.' + i;
|
|
472
|
-
out.push(...doc(f.doc, 1, ctx));
|
|
473
|
-
const fname = ident(f.name, 'field', ctx, fpath + '.name', false);
|
|
474
|
-
const type = typeExpr(f.type, ctx, fpath + '.type');
|
|
475
|
-
checks(f.check, fpath, ctx);
|
|
476
|
-
const opt = true === f.optional;
|
|
477
|
-
if (go) {
|
|
478
|
-
const star = opt && 'opt' !== f.type.k ? '*' : '';
|
|
479
|
-
out.push(ln(1, fname + ' ' + star + type.text +
|
|
480
|
-
' `json:"' + f.name + (opt ? ',omitempty' : '') + '"`'));
|
|
481
|
-
}
|
|
482
|
-
else {
|
|
483
|
-
out.push(ln(1, fname + (opt ? '?' : '') + ': ' + type.text + ';'));
|
|
484
|
-
}
|
|
485
|
-
if (undefined !== f.default) {
|
|
486
|
-
loss(ctx, fpath + '.default', 'default', 'a field default is not expressed by a ' +
|
|
487
|
-
(go ? 'go struct' : 'typescript interface'));
|
|
488
|
-
}
|
|
489
|
-
});
|
|
490
|
-
if (true === decl.open) {
|
|
491
|
-
if (go) {
|
|
492
|
-
loss(ctx, path + '.open', 'open', 'go has no open struct: extra keys are dropped');
|
|
493
|
-
}
|
|
494
|
-
else {
|
|
495
|
-
out.push(ln(1, '[key: string]: unknown;'));
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
checks(decl.check, path, ctx);
|
|
499
|
-
out.push('}');
|
|
500
|
-
return out;
|
|
501
|
-
}
|
|
502
|
-
if ('enum' === k) {
|
|
503
|
-
const name = ident(decl.name, 'enum', ctx, path + '.name', true);
|
|
504
|
-
out.push(...doc(decl.doc, 0, ctx));
|
|
505
|
-
const members = decl.members;
|
|
506
|
-
if (go) {
|
|
507
|
-
const numeric = 0 < members.length &&
|
|
508
|
-
members.every((m) => 'number' === typeof m.value);
|
|
509
|
-
out.push('type ' + name + ' ' + prim(ctx, numeric ? 'int' : 'string'));
|
|
510
|
-
out.push(BLANK, 'const (');
|
|
511
|
-
members.forEach((m, i) => {
|
|
512
|
-
out.push(...doc(m.doc, 1, ctx));
|
|
513
|
-
const mname = name + ident(m.name, 'member', ctx, path + '.members.' + i + '.name', false);
|
|
514
|
-
const value = undefined === m.value ? quote(m.name, ctx.profile) : literal(m.value, ctx);
|
|
515
|
-
out.push(ln(1, mname + ' ' + name + ' = ' + value));
|
|
516
|
-
});
|
|
517
|
-
out.push(')');
|
|
518
|
-
}
|
|
519
|
-
else {
|
|
520
|
-
out.push('export enum ' + name + ' {');
|
|
521
|
-
members.forEach((m, i) => {
|
|
522
|
-
out.push(...doc(m.doc, 1, ctx));
|
|
523
|
-
const mname = ident(m.name, 'member', ctx, path + '.members.' + i + '.name', false);
|
|
524
|
-
out.push(ln(1, mname + (undefined === m.value ? '' : ' = ' + literal(m.value, ctx)) + ','));
|
|
525
|
-
});
|
|
526
|
-
out.push('}');
|
|
527
|
-
}
|
|
528
|
-
return out;
|
|
529
|
-
}
|
|
530
|
-
if ('alias' === k) {
|
|
531
|
-
const name = ident(decl.name, 'alias', ctx, path + '.name', true);
|
|
532
|
-
out.push(...doc(decl.doc, 0, ctx));
|
|
533
|
-
const type = typeExpr(decl.type, ctx, path + '.type').text;
|
|
534
|
-
checks(decl.check, path, ctx);
|
|
535
|
-
out.push(go ? 'type ' + name + ' ' + type : 'export type ' + name + ' = ' + type + ';');
|
|
536
|
-
return out;
|
|
537
|
-
}
|
|
538
|
-
if ('const' === k) {
|
|
539
|
-
const name = ident(decl.name, 'const', ctx, path + '.name', true);
|
|
540
|
-
out.push(...doc(decl.doc, 0, ctx));
|
|
541
|
-
const type = null == decl.type ? undefined : typeExpr(decl.type, ctx, path + '.type').text;
|
|
542
|
-
const value = literal(decl.value, ctx);
|
|
543
|
-
out.push(go
|
|
544
|
-
? 'const ' + name + (undefined === type ? '' : ' ' + type) + ' = ' + value
|
|
545
|
-
: 'export const ' + name + (undefined === type ? '' : ': ' + type) + ' = ' + value + ';');
|
|
546
|
-
return out;
|
|
547
|
-
}
|
|
548
|
-
// func
|
|
549
|
-
const name = ident(decl.name, 'func', ctx, path + '.name', true);
|
|
550
|
-
out.push(...doc(decl.doc, 0, ctx));
|
|
551
|
-
const sig = params(decl.params, ctx, path);
|
|
552
|
-
const returns = null == decl.returns ? undefined : typeExpr(decl.returns, ctx, path + '.returns').text;
|
|
553
|
-
const abstract = 'abstract' === decl.body.k;
|
|
554
|
-
if (go) {
|
|
555
|
-
out.push('func ' + name + '(' + sig + ')' + (undefined === returns ? '' : ' ' + returns) + ' {');
|
|
556
|
-
if (abstract) {
|
|
557
|
-
loss(ctx, path + '.body', 'abstract', 'go has no abstract function: the body panics');
|
|
558
|
-
out.push(ln(1, 'panic(' + quote('abstract', ctx.profile) + ')'));
|
|
559
|
-
}
|
|
560
|
-
else {
|
|
561
|
-
out.push(...nest(decl.body.of));
|
|
562
|
-
}
|
|
563
|
-
out.push('}');
|
|
564
|
-
}
|
|
565
|
-
else {
|
|
566
|
-
const ret = ': ' + (returns ?? 'void');
|
|
567
|
-
if (abstract) {
|
|
568
|
-
out.push('export declare function ' + name + '(' + sig + ')' + ret + ';');
|
|
569
|
-
}
|
|
570
|
-
else {
|
|
571
|
-
out.push('export function ' + name + '(' + sig + ')' + ret + ' {');
|
|
572
|
-
out.push(...nest(decl.body.of));
|
|
573
|
-
out.push('}');
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
return out;
|
|
577
|
-
}
|
|
578
|
-
//# sourceMappingURL=lower.js.map
|