cddl 0.5.0 → 0.7.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/.editorconfig +18 -0
- package/README.md +49 -2
- package/build/ast.d.ts +26 -5
- package/build/ast.d.ts.map +1 -1
- package/build/ast.js +5 -0
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -1
- package/build/parser.d.ts +2 -0
- package/build/parser.d.ts.map +1 -1
- package/build/parser.js +151 -30
- package/build/transform/ts.d.ts.map +1 -1
- package/build/transform/ts.js +113 -41
- package/examples/webdriver/remote.cddl +1 -1
- package/package.json +1 -1
package/.editorconfig
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# EditorConfig helps developers define and maintain consistent
|
|
2
|
+
# coding styles between different editors and IDEs
|
|
3
|
+
# editorconfig.org
|
|
4
|
+
|
|
5
|
+
root = true
|
|
6
|
+
|
|
7
|
+
[*]
|
|
8
|
+
|
|
9
|
+
indent_style = space
|
|
10
|
+
indent_size = 4
|
|
11
|
+
|
|
12
|
+
end_of_line = lf
|
|
13
|
+
charset = utf-8
|
|
14
|
+
trim_trailing_whitespace = true
|
|
15
|
+
insert_final_newline = true
|
|
16
|
+
|
|
17
|
+
[{.travis.yml,**/*.json,.github/**/*.yml}]
|
|
18
|
+
indent_size = 2
|
package/README.md
CHANGED
|
@@ -20,7 +20,25 @@ $ npm install cddl
|
|
|
20
20
|
|
|
21
21
|
## Using this package
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
This package exposes a CLI as well as a programmatic interface for parsing and transforming CDDL.
|
|
24
|
+
|
|
25
|
+
### CLI
|
|
26
|
+
|
|
27
|
+
The `cddl` CLI offers a `validate` command that helps identify invalid CDDL formats, e.g.:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
npx cddl validate ./path/to/interface.cddl
|
|
31
|
+
✅ Valid CDDL file!
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Programmatic Interface
|
|
35
|
+
|
|
36
|
+
You can also use this package to parse a CDDL file into:
|
|
37
|
+
|
|
38
|
+
- an [abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (AST).
|
|
39
|
+
- or a [TypeScript](https://www.typescriptlang.org/) definition
|
|
40
|
+
|
|
41
|
+
For example, given the following CDDL file:
|
|
24
42
|
|
|
25
43
|
```cddl
|
|
26
44
|
person = {
|
|
@@ -29,7 +47,7 @@ person = {
|
|
|
29
47
|
}
|
|
30
48
|
```
|
|
31
49
|
|
|
32
|
-
|
|
50
|
+
By default the package parses the content into an AST:
|
|
33
51
|
|
|
34
52
|
```js
|
|
35
53
|
import { parse } from 'cddl'
|
|
@@ -49,6 +67,35 @@ console.log(ast)
|
|
|
49
67
|
*/
|
|
50
68
|
```
|
|
51
69
|
|
|
70
|
+
You can apply a target specifier to transform the AST into a different language or format (currently supported: `ts` for TypeScript). Note that this is highly experimental and work in progress.
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
import { parse } from 'cddl'
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* spec.cddl:
|
|
77
|
+
*
|
|
78
|
+
* session.CapabilityRequest = {
|
|
79
|
+
* ?acceptInsecureCerts: bool,
|
|
80
|
+
* ?browserName: text,
|
|
81
|
+
* ?browserVersion: text,
|
|
82
|
+
* ?platformName: text,
|
|
83
|
+
* };
|
|
84
|
+
*/
|
|
85
|
+
const ts = parse('./spec.cddl', { target: 'ts' })
|
|
86
|
+
console.log(ts)
|
|
87
|
+
/**
|
|
88
|
+
* outputs:
|
|
89
|
+
*
|
|
90
|
+
* interface SessionCapabilityRequest {
|
|
91
|
+
* acceptInsecureCerts?: boolean,
|
|
92
|
+
* browserName?: string,
|
|
93
|
+
* browserVersion?: string,
|
|
94
|
+
* platformName?: string,
|
|
95
|
+
* }
|
|
96
|
+
*/
|
|
97
|
+
```
|
|
98
|
+
|
|
52
99
|
---
|
|
53
100
|
|
|
54
101
|
If you are interested in this project, please feel free to contribute ideas or code patches. Have a look at our [contributing](https://github.com/christian-bromann/cddl/blob/master/LICENSE) guidelines](https://github.com/christian-bromann/cddl/blob/master/LICENSE) to get started.
|
package/build/ast.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type Group = {
|
|
|
13
13
|
Name: string;
|
|
14
14
|
IsChoiceAddition: boolean;
|
|
15
15
|
Properties: (Property | Property[])[];
|
|
16
|
+
Comments: Comment[];
|
|
16
17
|
};
|
|
17
18
|
/**
|
|
18
19
|
* an array definition
|
|
@@ -26,6 +27,7 @@ export type Array = {
|
|
|
26
27
|
Type: 'array';
|
|
27
28
|
Name: string;
|
|
28
29
|
Values: (Property | Property[])[];
|
|
30
|
+
Comments: Comment[];
|
|
29
31
|
};
|
|
30
32
|
/**
|
|
31
33
|
* a tag definition
|
|
@@ -48,6 +50,8 @@ export type Variable = {
|
|
|
48
50
|
Name: string;
|
|
49
51
|
IsChoiceAddition: boolean;
|
|
50
52
|
PropertyType: PropertyType | PropertyType[];
|
|
53
|
+
Operator?: Operator;
|
|
54
|
+
Comments: Comment[];
|
|
51
55
|
};
|
|
52
56
|
/**
|
|
53
57
|
* a comment statement
|
|
@@ -58,6 +62,7 @@ export type Variable = {
|
|
|
58
62
|
export type Comment = {
|
|
59
63
|
Type: 'comment';
|
|
60
64
|
Content: string;
|
|
65
|
+
Leading: boolean;
|
|
61
66
|
};
|
|
62
67
|
export type Occurrence = {
|
|
63
68
|
n: number;
|
|
@@ -68,7 +73,8 @@ export type Property = {
|
|
|
68
73
|
Occurrence: Occurrence;
|
|
69
74
|
Name: PropertyName;
|
|
70
75
|
Type: PropertyType | PropertyType[];
|
|
71
|
-
|
|
76
|
+
Comments: Comment[];
|
|
77
|
+
Operator?: Operator;
|
|
72
78
|
};
|
|
73
79
|
export declare enum Type {
|
|
74
80
|
/**
|
|
@@ -91,7 +97,12 @@ export declare enum Type {
|
|
|
91
97
|
BSTR = "bstr",
|
|
92
98
|
BYTES = "bytes",
|
|
93
99
|
TSTR = "tstr",
|
|
94
|
-
TEXT = "text"
|
|
100
|
+
TEXT = "text",
|
|
101
|
+
/**
|
|
102
|
+
* null types
|
|
103
|
+
*/
|
|
104
|
+
NIL = "nil",
|
|
105
|
+
NULL = "null"
|
|
95
106
|
}
|
|
96
107
|
/**
|
|
97
108
|
* can be a number, e.g. "foo = 0..10"
|
|
@@ -115,13 +126,23 @@ export type Range = {
|
|
|
115
126
|
Max: RangePropertyReference;
|
|
116
127
|
Inclusive: boolean;
|
|
117
128
|
};
|
|
118
|
-
export type
|
|
129
|
+
export type OperatorType = 'default' | 'size' | 'regexp' | 'bits' | 'and' | 'within' | 'eq' | 'ne' | 'lt' | 'le' | 'gt' | 'ge';
|
|
130
|
+
export interface Operator {
|
|
131
|
+
Type: OperatorType;
|
|
132
|
+
Value: PropertyType;
|
|
133
|
+
}
|
|
134
|
+
export type PropertyReferenceType = 'literal' | 'group' | 'group_array' | 'array' | 'range' | 'tag';
|
|
119
135
|
export type PropertyReference = {
|
|
120
136
|
Type: PropertyReferenceType;
|
|
121
137
|
Value: string | number | boolean | Group | Array | Range | Tag;
|
|
122
138
|
Unwrapped: boolean;
|
|
139
|
+
Operator?: Operator;
|
|
123
140
|
};
|
|
124
|
-
export
|
|
125
|
-
|
|
141
|
+
export interface NativeTypeWithOperator {
|
|
142
|
+
Type: Type | PropertyReference;
|
|
143
|
+
Operator?: Operator;
|
|
144
|
+
}
|
|
145
|
+
export type Assignment = Group | Array | Variable;
|
|
146
|
+
export type PropertyType = Assignment | Array | PropertyReference | string | NativeTypeWithOperator;
|
|
126
147
|
export type PropertyName = string;
|
|
127
148
|
//# sourceMappingURL=ast.d.ts.map
|
package/build/ast.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,MAAM,KAAK,GAAG;IAChB,IAAI,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
|
package/build/ast.js
CHANGED
package/build/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import Parser from './parser.js';
|
|
|
3
3
|
import { ParseTargets } from './constants.js';
|
|
4
4
|
import type { ParseOptions } from './types.js';
|
|
5
5
|
declare const _default: {
|
|
6
|
-
parse: (filePath: string, opts
|
|
6
|
+
parse: (filePath: string, opts?: ParseOptions) => string | import("./ast.js").Assignment[];
|
|
7
7
|
};
|
|
8
8
|
export default _default;
|
|
9
9
|
export { Lexer, Parser, ParseTargets };
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,MAAM,MAAM,aAAa,CAAA;AAGhC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;;sBAGxB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,MAAM,MAAM,aAAa,CAAA;AAGhC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;;sBAGxB,MAAM,SAAQ,YAAY;;AADhD,wBAcC;AAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA"}
|
package/build/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import Parser from './parser.js';
|
|
|
3
3
|
import { transform as transformTS } from './transform/ts.js';
|
|
4
4
|
import { ParseTargets } from './constants.js';
|
|
5
5
|
export default {
|
|
6
|
-
parse: (filePath, opts) => {
|
|
6
|
+
parse: (filePath, opts = { target: ParseTargets.AST }) => {
|
|
7
7
|
const parser = new Parser(filePath);
|
|
8
8
|
const ast = parser.parse();
|
|
9
9
|
if (opts.target === ParseTargets.AST) {
|
package/build/parser.d.ts
CHANGED
package/build/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,YAAY,CAAA;AAE9B,OAAO,EAAE,KAAK,EAAU,MAAM,aAAa,CAAC;AAG5C,OAAO,EAE2C,UAAU,EAE3D,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,YAAY,CAAA;AAE9B,OAAO,EAAE,KAAK,EAAU,MAAM,aAAa,CAAC;AAG5C,OAAO,EAE2C,UAAU,EAE3D,MAAM,UAAU,CAAA;AAoBjB,MAAM,CAAC,OAAO,OAAO,MAAM;;IAEvB,CAAC,EAAE,KAAK,CAAC;IAET,QAAQ,EAAE,KAAK,CAAa;IAC5B,SAAS,EAAE,KAAK,CAAa;gBAEhB,QAAQ,EAAE,MAAM;IAQ7B,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,gBAAgB;IA2CxB,OAAO,CAAC,oBAAoB;IA6Y5B,OAAO,CAAC,wBAAwB;IAahC;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,iBAAiB;IA6HzB,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,kBAAkB;IAiD1B,OAAO,CAAC,gBAAgB;IA4DxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB,KAAK;IAaL,OAAO,CAAC,WAAW;CAKtB"}
|
package/build/parser.js
CHANGED
|
@@ -6,6 +6,21 @@ import { parseNumberValue } from './utils.js';
|
|
|
6
6
|
import { Type } from './ast.js';
|
|
7
7
|
const NIL_TOKEN = { Type: Tokens.ILLEGAL, Literal: '' };
|
|
8
8
|
const DEFAULT_OCCURRENCE = { n: 1, m: 1 }; // exactly one time
|
|
9
|
+
const OPERATORS = ['default', 'size', 'regexp', 'bits', 'and', 'within', 'eq', 'ne', 'lt', 'le', 'gt', 'ge'];
|
|
10
|
+
const OPERATORS_EXPECTING_VALUES = {
|
|
11
|
+
default: undefined,
|
|
12
|
+
size: ['literal', 'range'],
|
|
13
|
+
regexp: ['literal'],
|
|
14
|
+
bits: ['group'],
|
|
15
|
+
and: ['group'],
|
|
16
|
+
within: ['group'],
|
|
17
|
+
eq: ['group'],
|
|
18
|
+
ne: ['group'],
|
|
19
|
+
lt: ['group'],
|
|
20
|
+
le: ['group'],
|
|
21
|
+
gt: ['group'],
|
|
22
|
+
ge: ['group'],
|
|
23
|
+
};
|
|
9
24
|
export default class Parser {
|
|
10
25
|
#filePath;
|
|
11
26
|
l;
|
|
@@ -23,6 +38,10 @@ export default class Parser {
|
|
|
23
38
|
return true;
|
|
24
39
|
}
|
|
25
40
|
parseAssignments() {
|
|
41
|
+
const comments = [];
|
|
42
|
+
while (this.curToken.Type === Tokens.COMMENT) {
|
|
43
|
+
comments.push(this.parseComment());
|
|
44
|
+
}
|
|
26
45
|
/**
|
|
27
46
|
* expect group identifier, e.g.
|
|
28
47
|
* groupName =
|
|
@@ -45,7 +64,14 @@ export default class Parser {
|
|
|
45
64
|
this.nextToken(); // eat `/`
|
|
46
65
|
}
|
|
47
66
|
this.nextToken(); // eat `=`
|
|
48
|
-
|
|
67
|
+
const assignmentValue = this.parseAssignmentValue(groupName, isChoiceAddition);
|
|
68
|
+
// @ts-expect-error curToken can be changed by now but TS doesn't understand this
|
|
69
|
+
while (this.curToken.Type === Tokens.COMMENT) {
|
|
70
|
+
const comment = this.parseComment();
|
|
71
|
+
comment && comments.push(comment);
|
|
72
|
+
}
|
|
73
|
+
assignmentValue.Comments = comments;
|
|
74
|
+
return assignmentValue;
|
|
49
75
|
}
|
|
50
76
|
parseAssignmentValue(groupName, isChoiceAddition = false) {
|
|
51
77
|
let isChoice = false;
|
|
@@ -64,7 +90,8 @@ export default class Parser {
|
|
|
64
90
|
Type: 'variable',
|
|
65
91
|
Name: groupName,
|
|
66
92
|
IsChoiceAddition: isChoiceAddition,
|
|
67
|
-
PropertyType: this.parsePropertyTypes()
|
|
93
|
+
PropertyType: this.parsePropertyTypes(),
|
|
94
|
+
Comments: []
|
|
68
95
|
};
|
|
69
96
|
return variable;
|
|
70
97
|
}
|
|
@@ -101,18 +128,46 @@ export default class Parser {
|
|
|
101
128
|
Type: 'variable',
|
|
102
129
|
Name: groupName,
|
|
103
130
|
IsChoiceAddition: isChoiceAddition,
|
|
104
|
-
PropertyType: propertyType
|
|
131
|
+
PropertyType: propertyType,
|
|
132
|
+
Comments: []
|
|
105
133
|
};
|
|
134
|
+
if (this.isOperator()) {
|
|
135
|
+
variable.Operator = this.parseOperator();
|
|
136
|
+
}
|
|
106
137
|
return variable;
|
|
107
138
|
}
|
|
108
139
|
return propertyType;
|
|
109
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* parse operator assignments, e.g. `ip4 = (float .ge 0.0) .default 1.0`
|
|
143
|
+
*/
|
|
144
|
+
if (closingTokens.length === 1 && this.peekToken.Type === Tokens.DOT) {
|
|
145
|
+
const prop = {
|
|
146
|
+
Type: this.parsePropertyType(),
|
|
147
|
+
Operator: this.parseOperator()
|
|
148
|
+
};
|
|
149
|
+
this.nextToken(); // eat closing token
|
|
150
|
+
if (groupName) {
|
|
151
|
+
const variable = {
|
|
152
|
+
Type: 'variable',
|
|
153
|
+
Name: groupName,
|
|
154
|
+
IsChoiceAddition: isChoiceAddition,
|
|
155
|
+
PropertyType: prop,
|
|
156
|
+
Operator: this.parseOperator(),
|
|
157
|
+
Comments: []
|
|
158
|
+
};
|
|
159
|
+
return variable;
|
|
160
|
+
}
|
|
161
|
+
return [prop];
|
|
162
|
+
}
|
|
110
163
|
while (!closingTokens.includes(this.curToken.Type)) {
|
|
111
164
|
const propertyType = [];
|
|
165
|
+
const comments = [];
|
|
112
166
|
let isUnwrapped = false;
|
|
113
167
|
let hasCut = false;
|
|
114
168
|
let propertyName = '';
|
|
115
|
-
|
|
169
|
+
const leadingComment = this.parseComment(true);
|
|
170
|
+
leadingComment && comments.push(leadingComment);
|
|
116
171
|
const occurrence = this.parseOccurrences();
|
|
117
172
|
/**
|
|
118
173
|
* check if variable name is unwrapped
|
|
@@ -145,7 +200,7 @@ export default class Parser {
|
|
|
145
200
|
Occurrence: occurrence,
|
|
146
201
|
Name: '',
|
|
147
202
|
Type: innerGroup,
|
|
148
|
-
|
|
203
|
+
Comments: []
|
|
149
204
|
});
|
|
150
205
|
continue;
|
|
151
206
|
}
|
|
@@ -163,6 +218,7 @@ export default class Parser {
|
|
|
163
218
|
if (this.curToken.Type === Tokens.COMMA || closingTokens.includes(this.curToken.Type)) {
|
|
164
219
|
const tokenType = this.curToken.Type;
|
|
165
220
|
let parsedComments = false;
|
|
221
|
+
let comment;
|
|
166
222
|
/**
|
|
167
223
|
* check if line has a comment
|
|
168
224
|
*/
|
|
@@ -182,7 +238,7 @@ export default class Parser {
|
|
|
182
238
|
Value: propertyName,
|
|
183
239
|
Unwrapped: isUnwrapped
|
|
184
240
|
}],
|
|
185
|
-
|
|
241
|
+
Comments: comment ? [comment] : []
|
|
186
242
|
});
|
|
187
243
|
if (this.curToken.Literal === Tokens.COMMA || this.curToken.Literal === closingTokens[0]) {
|
|
188
244
|
if (this.curToken.Literal === Tokens.COMMA) {
|
|
@@ -224,11 +280,11 @@ export default class Parser {
|
|
|
224
280
|
Occurrence: occurrence,
|
|
225
281
|
Name: '',
|
|
226
282
|
Type: {
|
|
227
|
-
Type:
|
|
283
|
+
Type: 'group',
|
|
228
284
|
Value: propertyName,
|
|
229
285
|
Unwrapped: isUnwrapped
|
|
230
286
|
},
|
|
231
|
-
|
|
287
|
+
Comments: comments
|
|
232
288
|
};
|
|
233
289
|
if (isChoice) {
|
|
234
290
|
/**
|
|
@@ -258,6 +314,7 @@ export default class Parser {
|
|
|
258
314
|
* parse property value
|
|
259
315
|
*/
|
|
260
316
|
const props = this.parseAssignmentValue();
|
|
317
|
+
const operator = this.isOperator() ? this.parseOperator() : undefined;
|
|
261
318
|
if (Array.isArray(props)) {
|
|
262
319
|
/**
|
|
263
320
|
* property has multiple types (e.g. `float / tstr / int`)
|
|
@@ -278,13 +335,15 @@ export default class Parser {
|
|
|
278
335
|
flipIsChoice = true;
|
|
279
336
|
this.nextToken(); // eat ,
|
|
280
337
|
}
|
|
281
|
-
|
|
338
|
+
const trailingComment = this.parseComment();
|
|
339
|
+
trailingComment && comments.push(trailingComment);
|
|
282
340
|
const prop = {
|
|
283
341
|
HasCut: hasCut,
|
|
284
342
|
Occurrence: occurrence,
|
|
285
343
|
Name: propertyName,
|
|
286
344
|
Type: propertyType,
|
|
287
|
-
|
|
345
|
+
Comments: comments,
|
|
346
|
+
...(operator ? { Operator: operator } : {})
|
|
288
347
|
};
|
|
289
348
|
if (isChoice) {
|
|
290
349
|
valuesOrProperties[valuesOrProperties.length - 1].push(prop);
|
|
@@ -323,9 +382,35 @@ export default class Parser {
|
|
|
323
382
|
return {
|
|
324
383
|
Type: 'array',
|
|
325
384
|
Name: groupName || '',
|
|
326
|
-
Values: valuesOrProperties
|
|
385
|
+
Values: valuesOrProperties,
|
|
386
|
+
Comments: []
|
|
327
387
|
};
|
|
328
388
|
}
|
|
389
|
+
/**
|
|
390
|
+
* simplify wrapped types, e.g. from
|
|
391
|
+
* {
|
|
392
|
+
* "Type": "group",
|
|
393
|
+
* "Name": "",
|
|
394
|
+
* "Properties": [
|
|
395
|
+
* {
|
|
396
|
+
* "HasCut": false,
|
|
397
|
+
* "Occurrence": {
|
|
398
|
+
* "n": 1,
|
|
399
|
+
* "m": 1
|
|
400
|
+
* },
|
|
401
|
+
* "Name": "",
|
|
402
|
+
* "Type": "bool",
|
|
403
|
+
* "Comment": ""
|
|
404
|
+
* }
|
|
405
|
+
* ],
|
|
406
|
+
* "IsChoiceAddition": false
|
|
407
|
+
* }
|
|
408
|
+
* back to:
|
|
409
|
+
* bool
|
|
410
|
+
*/
|
|
411
|
+
if (!groupName && valuesOrProperties.length === 1 && PREDEFINED_IDENTIFIER.includes(valuesOrProperties[0].Type)) {
|
|
412
|
+
return valuesOrProperties[0].Type;
|
|
413
|
+
}
|
|
329
414
|
/**
|
|
330
415
|
* otherwise a group
|
|
331
416
|
*/
|
|
@@ -333,7 +418,8 @@ export default class Parser {
|
|
|
333
418
|
Type: 'group',
|
|
334
419
|
Name: groupName || '',
|
|
335
420
|
Properties: valuesOrProperties,
|
|
336
|
-
IsChoiceAddition: isChoiceAddition
|
|
421
|
+
IsChoiceAddition: isChoiceAddition,
|
|
422
|
+
Comments: []
|
|
337
423
|
};
|
|
338
424
|
}
|
|
339
425
|
isPropertyValueSeparator() {
|
|
@@ -382,8 +468,9 @@ export default class Parser {
|
|
|
382
468
|
throw this.parserError(`Expected property name, received ${this.curToken.Type}(${this.curToken.Literal}), ${this.peekToken.Type}(${this.peekToken.Literal})`);
|
|
383
469
|
}
|
|
384
470
|
parsePropertyType() {
|
|
385
|
-
let type;
|
|
471
|
+
let type = undefined;
|
|
386
472
|
let isUnwrapped = false;
|
|
473
|
+
let isGroupedRange = false;
|
|
387
474
|
/**
|
|
388
475
|
* check if variable name is unwrapped
|
|
389
476
|
*/
|
|
@@ -404,6 +491,8 @@ export default class Parser {
|
|
|
404
491
|
case Type.BYTES:
|
|
405
492
|
case Type.TSTR:
|
|
406
493
|
case Type.TEXT:
|
|
494
|
+
case Type.NIL:
|
|
495
|
+
case Type.NULL:
|
|
407
496
|
type = this.curToken.Literal;
|
|
408
497
|
break;
|
|
409
498
|
default: {
|
|
@@ -451,6 +540,15 @@ export default class Parser {
|
|
|
451
540
|
Unwrapped: isUnwrapped
|
|
452
541
|
};
|
|
453
542
|
}
|
|
543
|
+
else if (this.curToken.Literal === Tokens.LPAREN && this.peekToken.Type === Tokens.NUMBER) {
|
|
544
|
+
this.nextToken();
|
|
545
|
+
type = {
|
|
546
|
+
Type: 'literal',
|
|
547
|
+
Value: parseNumberValue(this.curToken),
|
|
548
|
+
Unwrapped: isUnwrapped
|
|
549
|
+
};
|
|
550
|
+
isGroupedRange = true;
|
|
551
|
+
}
|
|
454
552
|
else {
|
|
455
553
|
throw this.parserError(`Invalid property type "${this.curToken.Literal}"`);
|
|
456
554
|
}
|
|
@@ -484,13 +582,42 @@ export default class Parser {
|
|
|
484
582
|
},
|
|
485
583
|
Unwrapped: isUnwrapped
|
|
486
584
|
};
|
|
585
|
+
if (isGroupedRange) {
|
|
586
|
+
this.nextToken(); // eat ")"
|
|
587
|
+
}
|
|
487
588
|
}
|
|
488
589
|
return type;
|
|
489
590
|
}
|
|
591
|
+
parseOperator() {
|
|
592
|
+
const type = this.peekToken.Literal;
|
|
593
|
+
if (this.curToken.Literal !== Tokens.DOT || !OPERATORS.includes(this.peekToken.Literal)) {
|
|
594
|
+
throw new Error(`Operator ".${type}", expects a ${OPERATORS_EXPECTING_VALUES[type].join(' or ')} property, but found ${this.peekToken.Literal}!`);
|
|
595
|
+
}
|
|
596
|
+
this.nextToken(); // eat "."
|
|
597
|
+
this.nextToken(); // eat operator type
|
|
598
|
+
const value = this.parsePropertyType();
|
|
599
|
+
this.nextToken(); // eat operator value
|
|
600
|
+
return {
|
|
601
|
+
Type: type,
|
|
602
|
+
Value: value
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
isOperator() {
|
|
606
|
+
return this.curToken.Literal === Tokens.DOT && OPERATORS.includes(this.peekToken.Literal);
|
|
607
|
+
}
|
|
490
608
|
parsePropertyTypes() {
|
|
491
609
|
const propertyTypes = [];
|
|
492
|
-
|
|
493
|
-
this.
|
|
610
|
+
let prop = this.parsePropertyType();
|
|
611
|
+
if (this.isOperator()) {
|
|
612
|
+
prop = {
|
|
613
|
+
Type: prop,
|
|
614
|
+
Operator: this.parseOperator()
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
this.nextToken(); // eat `/`
|
|
619
|
+
}
|
|
620
|
+
propertyTypes.push(prop);
|
|
494
621
|
/**
|
|
495
622
|
* ensure we don't go into the next choice, e.g.:
|
|
496
623
|
* ```
|
|
@@ -576,26 +703,20 @@ export default class Parser {
|
|
|
576
703
|
/**
|
|
577
704
|
* check if line has a comment
|
|
578
705
|
*/
|
|
579
|
-
parseComment() {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
comment = this.curToken.Literal.slice(2);
|
|
583
|
-
this.nextToken();
|
|
706
|
+
parseComment(isLeading) {
|
|
707
|
+
if (this.curToken.Type !== Tokens.COMMENT) {
|
|
708
|
+
return;
|
|
584
709
|
}
|
|
585
|
-
|
|
710
|
+
const comment = this.curToken.Literal.replace(/^;(\s*)/, '');
|
|
711
|
+
this.nextToken();
|
|
712
|
+
if (comment.trim().length === 0) {
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
return { Type: 'comment', Content: comment, Leading: Boolean(isLeading) };
|
|
586
716
|
}
|
|
587
717
|
parse() {
|
|
588
718
|
const definition = [];
|
|
589
719
|
while (this.curToken.Type !== Tokens.EOF) {
|
|
590
|
-
if (this.curToken.Type === Tokens.COMMENT) {
|
|
591
|
-
const comment = {
|
|
592
|
-
Type: 'comment',
|
|
593
|
-
Content: this.curToken.Literal.slice(1).trim()
|
|
594
|
-
};
|
|
595
|
-
definition.push(comment);
|
|
596
|
-
this.nextToken();
|
|
597
|
-
continue;
|
|
598
|
-
}
|
|
599
720
|
const group = this.parseAssignments();
|
|
600
721
|
if (group) {
|
|
601
722
|
definition.push(group);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ts.d.ts","sourceRoot":"","sources":["../../src/transform/ts.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"ts.d.ts","sourceRoot":"","sources":["../../src/transform/ts.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAmG,MAAM,QAAQ,CAAA;AAmBzI,wBAAgB,SAAS,CAAE,WAAW,EAAE,UAAU,EAAE,UAkBnD"}
|
package/build/transform/ts.js
CHANGED
|
@@ -4,14 +4,17 @@ import typescriptParser from 'recast/parsers/typescript.js';
|
|
|
4
4
|
// @ts-ignore
|
|
5
5
|
import pkg from '../../package.json' assert { type: 'json' };
|
|
6
6
|
const b = types.builders;
|
|
7
|
-
const comments = [];
|
|
8
7
|
const NATIVE_TYPES = {
|
|
9
|
-
number:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
number: b.tsNumberKeyword(),
|
|
9
|
+
float: b.tsNumberKeyword(),
|
|
10
|
+
uint: b.tsNumberKeyword(),
|
|
11
|
+
bool: b.tsBooleanKeyword(),
|
|
12
|
+
str: b.tsStringKeyword(),
|
|
13
|
+
text: b.tsStringKeyword(),
|
|
14
|
+
tstr: b.tsStringKeyword(),
|
|
15
|
+
range: b.tsNumberKeyword(),
|
|
16
|
+
nil: b.tsNullKeyword(),
|
|
17
|
+
null: b.tsNullKeyword()
|
|
15
18
|
};
|
|
16
19
|
export function transform(assignments) {
|
|
17
20
|
let ast = parse(`// compiled with https://www.npmjs.com/package/cddl v${pkg.version}`, {
|
|
@@ -26,14 +29,9 @@ export function transform(assignments) {
|
|
|
26
29
|
}
|
|
27
30
|
ast.program.body.push(statement);
|
|
28
31
|
}
|
|
29
|
-
ast.program.comments = comments.map((c) => b.commentLine(c, false, false));
|
|
30
32
|
return print(ast).code;
|
|
31
33
|
}
|
|
32
34
|
function parseAssignment(ast, assignment) {
|
|
33
|
-
if (assignment.Type === 'comment') {
|
|
34
|
-
comments.push(assignment.Content);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
35
|
if (assignment.Type === 'variable') {
|
|
38
36
|
const propType = Array.isArray(assignment.PropertyType)
|
|
39
37
|
? assignment.PropertyType
|
|
@@ -48,13 +46,18 @@ function parseAssignment(ast, assignment) {
|
|
|
48
46
|
typeParameters = b.tsUnionType(propType.map(parsePropertyType));
|
|
49
47
|
}
|
|
50
48
|
const expr = b.tsTypeAliasDeclaration(id, typeParameters);
|
|
51
|
-
expr.comments =
|
|
49
|
+
expr.comments = assignment.Comments.map((c) => b.commentLine(` ${c.Content}`, true));
|
|
52
50
|
return expr;
|
|
53
51
|
}
|
|
54
52
|
if (assignment.Type === 'group') {
|
|
55
53
|
const id = b.identifier(camelcase(assignment.Name, { pascalCase: true }));
|
|
56
54
|
const objectType = parseObjectType(assignment.Properties);
|
|
57
|
-
const
|
|
55
|
+
const extendInterfaces = assignment.Properties
|
|
56
|
+
.filter((prop) => prop.Name === '')
|
|
57
|
+
.map((prop) => b.tsExpressionWithTypeArguments(b.identifier(camelcase(prop.Type[0].Value, { pascalCase: true }))));
|
|
58
|
+
const expr = b.tsInterfaceDeclaration(id, b.tsInterfaceBody(objectType));
|
|
59
|
+
expr.extends = extendInterfaces;
|
|
60
|
+
expr.comments = assignment.Comments.map((c) => b.commentLine(` ${c.Content}`, true));
|
|
58
61
|
return expr;
|
|
59
62
|
}
|
|
60
63
|
}
|
|
@@ -63,7 +66,7 @@ function parsePropertyType(propType) {
|
|
|
63
66
|
return b.tsStringKeyword();
|
|
64
67
|
}
|
|
65
68
|
if (propType.Type === 'group') {
|
|
66
|
-
return b.tsTypeReference(b.identifier(propType.Value.toString()));
|
|
69
|
+
return b.tsTypeReference(b.identifier(camelcase(propType.Value.toString(), { pascalCase: true })));
|
|
67
70
|
}
|
|
68
71
|
if (propType.Type === 'literal') {
|
|
69
72
|
return b.tsLiteralType(b.stringLiteral(propType.Value.toString()));
|
|
@@ -74,40 +77,109 @@ function parseObjectType(props) {
|
|
|
74
77
|
const propItems = [];
|
|
75
78
|
for (const prop of props) {
|
|
76
79
|
/**
|
|
77
|
-
*
|
|
80
|
+
* Empty groups like
|
|
81
|
+
* {
|
|
82
|
+
* HasCut: false,
|
|
83
|
+
* Occurrence: { n: 1, m: 1 },
|
|
84
|
+
* Name: '',
|
|
85
|
+
* Type: [ { Type: 'group', Value: 'Extensible', Unwrapped: false } ],
|
|
86
|
+
* Comment: ''
|
|
87
|
+
* }
|
|
88
|
+
* are ignored and later added as interface extensions
|
|
78
89
|
*/
|
|
79
90
|
if (prop.Name === '') {
|
|
80
|
-
propItems[propItems.length - 1].comments = [b.commentLine(`Missing: ${JSON.stringify(prop)}`)];
|
|
81
91
|
continue;
|
|
82
92
|
}
|
|
83
93
|
const id = b.identifier(camelcase(prop.Name));
|
|
84
94
|
const cddlType = Array.isArray(prop.Type) ? prop.Type : [prop.Type];
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return
|
|
98
|
-
/**
|
|
99
|
-
* transform native CDDL types into TypeScript types
|
|
100
|
-
*/
|
|
101
|
-
NATIVE_TYPES[value] ? value : camelcase(value.toString(), { pascalCase: true }));
|
|
102
|
-
}
|
|
103
|
-
else if (t.Type === 'literal' && typeof t.Value === 'string') {
|
|
104
|
-
return b.stringLiteralTypeAnnotation(t.Value, t.Value);
|
|
95
|
+
const comments = prop.Comments.map((c) => ` ${c.Content}`);
|
|
96
|
+
if (prop.Operator && prop.Operator.Type === 'default') {
|
|
97
|
+
const defaultValue = parseDefaultValue(prop.Operator);
|
|
98
|
+
defaultValue && comments.length && comments.push(''); // add empty line if we have previous comments
|
|
99
|
+
defaultValue && comments.push(` @default ${defaultValue}`);
|
|
100
|
+
}
|
|
101
|
+
const type = cddlType.map((t) => {
|
|
102
|
+
const unionType = parseUnionType(t);
|
|
103
|
+
if (unionType) {
|
|
104
|
+
const defaultValue = parseDefaultValue(t.Operator);
|
|
105
|
+
defaultValue && comments.length && comments.push(''); // add empty line if we have previous comments
|
|
106
|
+
defaultValue && comments.push(` @default ${defaultValue}`);
|
|
107
|
+
return unionType;
|
|
105
108
|
}
|
|
106
109
|
throw new Error(`Couldn't parse property ${JSON.stringify(t)}`);
|
|
107
|
-
})
|
|
110
|
+
});
|
|
111
|
+
const typeAnnotation = b.tsTypeAnnotation(b.tsUnionType(type));
|
|
108
112
|
const isOptional = prop.Occurrence.n === 0;
|
|
109
|
-
|
|
113
|
+
const propSignature = b.tsPropertySignature(id, typeAnnotation, isOptional);
|
|
114
|
+
propSignature.comments = comments.length ? [b.commentBlock(`*\n *${comments.join('\n *')}\n `)] : [];
|
|
115
|
+
propItems.push(propSignature);
|
|
116
|
+
}
|
|
117
|
+
return propItems;
|
|
118
|
+
}
|
|
119
|
+
function parseUnionType(t) {
|
|
120
|
+
if (typeof t === 'string') {
|
|
121
|
+
if (!NATIVE_TYPES[t]) {
|
|
122
|
+
throw new Error(`Unknown native type: "${t}`);
|
|
123
|
+
}
|
|
124
|
+
return NATIVE_TYPES[t];
|
|
125
|
+
}
|
|
126
|
+
else if (NATIVE_TYPES[t.Type]) {
|
|
127
|
+
return NATIVE_TYPES[t.Type];
|
|
128
|
+
}
|
|
129
|
+
else if (t.Value === 'null') {
|
|
130
|
+
return b.tsNullKeyword();
|
|
131
|
+
}
|
|
132
|
+
else if (t.Type === 'group') {
|
|
133
|
+
const value = t.Value;
|
|
134
|
+
/**
|
|
135
|
+
* check if we have
|
|
136
|
+
* ?attributes: {*text => text},
|
|
137
|
+
*/
|
|
138
|
+
if (!value && t.Properties) {
|
|
139
|
+
return b.tsTypeLiteral(parseObjectType(t.Properties));
|
|
140
|
+
}
|
|
141
|
+
return b.tsTypeReference(b.identifier(camelcase(value.toString(), { pascalCase: true })));
|
|
142
|
+
}
|
|
143
|
+
else if (t.Type === 'literal' && typeof t.Value === 'string') {
|
|
144
|
+
return b.tsLiteralType(b.stringLiteral(t.Value));
|
|
145
|
+
}
|
|
146
|
+
else if (t.Type === 'literal' && typeof t.Value === 'number') {
|
|
147
|
+
return b.tsLiteralType(b.numericLiteral(t.Value));
|
|
148
|
+
}
|
|
149
|
+
else if (t.Type === 'array') {
|
|
150
|
+
const types = t.Values[0].Type;
|
|
151
|
+
const typedTypes = (Array.isArray(types) ? types : [types]).map((val) => {
|
|
152
|
+
return typeof val === 'string' && NATIVE_TYPES[val]
|
|
153
|
+
? NATIVE_TYPES[val]
|
|
154
|
+
: b.tsTypeReference(b.identifier(camelcase(val.Value, { pascalCase: true })));
|
|
155
|
+
});
|
|
156
|
+
return b.tsArrayType(typedTypes.length > 1
|
|
157
|
+
? b.tsParenthesizedType(b.tsUnionType(typedTypes))
|
|
158
|
+
: b.tsUnionType(typedTypes));
|
|
159
|
+
}
|
|
160
|
+
else if (typeof t.Type === 'object' && t.Type.Type === 'range') {
|
|
161
|
+
return b.tsNumberKeyword();
|
|
162
|
+
}
|
|
163
|
+
else if (typeof t.Type === 'object' && t.Type.Type === 'group') {
|
|
164
|
+
/**
|
|
165
|
+
* e.g. ?pointerType: input.PointerType .default "mouse"
|
|
166
|
+
*/
|
|
167
|
+
const referenceValue = camelcase(t.Type.Value, { pascalCase: true });
|
|
168
|
+
return b.tsTypeReference(b.identifier(referenceValue));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function parseDefaultValue(operator) {
|
|
172
|
+
if (!operator || operator.Type !== 'default') {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const operatorValue = operator.Value;
|
|
176
|
+
if (operator.Value === 'null') {
|
|
177
|
+
return operator.Value;
|
|
178
|
+
}
|
|
179
|
+
if (operatorValue.Type !== 'literal') {
|
|
180
|
+
throw new Error(`Can't parse operator default value of ${JSON.stringify(operator)}`);
|
|
110
181
|
}
|
|
111
|
-
|
|
112
|
-
|
|
182
|
+
return typeof operatorValue.Value === 'string'
|
|
183
|
+
? `'${operatorValue.Value}'`
|
|
184
|
+
: operatorValue.Value;
|
|
113
185
|
}
|
package/package.json
CHANGED