@aeriajs/compiler 0.0.14 → 0.0.16
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/dist/ast.d.ts +2 -0
- package/dist/ast.js +1 -0
- package/dist/ast.mjs +2 -1
- package/dist/codegen/generateContracts.d.ts +1 -1
- package/dist/codegen/generateContracts.js +1 -1
- package/dist/codegen/generateContracts.mjs +1 -1
- package/dist/codegen/generateExports.d.ts +3 -3
- package/dist/codegen/generateExports.js +3 -3
- package/dist/codegen/generateExports.mjs +3 -3
- package/dist/codegen/generateJSCollections.js +2 -2
- package/dist/codegen/generateJSCollections.mjs +2 -2
- package/dist/codegen/utils.d.ts +1 -1
- package/dist/codegen.js +4 -4
- package/dist/codegen.mjs +4 -4
- package/dist/compile.d.ts +1 -1
- package/dist/compile.js +11 -16
- package/dist/compile.mjs +11 -15
- package/dist/parser.js +36 -5
- package/dist/parser.mjs +37 -6
- package/dist/semantic.js +3 -1
- package/dist/semantic.mjs +3 -1
- package/dist/token.d.ts +2 -0
- package/dist/token.js +1 -0
- package/dist/token.mjs +1 -0
- package/package.json +1 -1
package/dist/ast.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare const PropertyType: {
|
|
|
9
9
|
readonly enum: "enum";
|
|
10
10
|
readonly date: "string";
|
|
11
11
|
readonly datetime: "string";
|
|
12
|
+
readonly const: "const";
|
|
12
13
|
};
|
|
13
14
|
export declare const PropertyModifiers: Record<'Error' | 'Result', ExportSymbol>;
|
|
14
15
|
export type ExportSymbol = {
|
|
@@ -22,6 +23,7 @@ export type PropertyNode = NodeBase<'property'> & {
|
|
|
22
23
|
modifier?: keyof typeof PropertyModifiers;
|
|
23
24
|
property: Property & {
|
|
24
25
|
[LOCATION_SYMBOL]?: {
|
|
26
|
+
type: symbol;
|
|
25
27
|
attributes: Record<string, symbol>;
|
|
26
28
|
arrays: {
|
|
27
29
|
[P in ArrayProperties<Extract<Property, {
|
package/dist/ast.js
CHANGED
package/dist/ast.mjs
CHANGED
|
@@ -2,14 +2,14 @@ import type * as AST from '../ast.js';
|
|
|
2
2
|
export declare const generateExports: (ast: AST.ProgramNode, hasContracts?: boolean) => {
|
|
3
3
|
main: {
|
|
4
4
|
js: string;
|
|
5
|
-
|
|
5
|
+
dts: string;
|
|
6
6
|
};
|
|
7
7
|
collections: {
|
|
8
8
|
js: string;
|
|
9
|
-
|
|
9
|
+
dts: string;
|
|
10
10
|
};
|
|
11
11
|
contracts?: {
|
|
12
12
|
js: string;
|
|
13
|
-
|
|
13
|
+
dts: string;
|
|
14
14
|
};
|
|
15
15
|
};
|
|
@@ -15,7 +15,7 @@ const generateExports = (ast, hasContracts = false) => {
|
|
|
15
15
|
const exports = {
|
|
16
16
|
collections: {
|
|
17
17
|
js: `export { ${symbolsToExport.map((symbol) => `${symbol.id}`).join(', ')} } from './collections.js'`,
|
|
18
|
-
|
|
18
|
+
dts: `export { ${symbolsToExport.map((symbol) => `${symbol.id}`).join(', ')} } from './collections.js'`,
|
|
19
19
|
},
|
|
20
20
|
main: {
|
|
21
21
|
js: (hasContracts
|
|
@@ -23,7 +23,7 @@ const generateExports = (ast, hasContracts = false) => {
|
|
|
23
23
|
: '') +
|
|
24
24
|
'export * as collections from \'./collections/index.js\'\n' +
|
|
25
25
|
`export { ${symbolsToExport.map((symbol) => symbol.extend).join(', ')} } from './collections/collections.js'`,
|
|
26
|
-
|
|
26
|
+
dts: (hasContracts
|
|
27
27
|
? 'export * as contracts from \'./contracts/index.js\'\n'
|
|
28
28
|
: '') +
|
|
29
29
|
'export * as collections from \'./collections/index.js\'\n' +
|
|
@@ -33,7 +33,7 @@ const generateExports = (ast, hasContracts = false) => {
|
|
|
33
33
|
if (hasContracts) {
|
|
34
34
|
exports.contracts = {
|
|
35
35
|
js: 'export * from \'./contracts.js\'',
|
|
36
|
-
|
|
36
|
+
dts: 'export * from \'./contracts.js\'',
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
return exports;
|
|
@@ -13,19 +13,19 @@ export const generateExports = (ast, hasContracts = false) => {
|
|
|
13
13
|
const exports = {
|
|
14
14
|
collections: {
|
|
15
15
|
js: `export { ${symbolsToExport.map((symbol) => `${symbol.id}`).join(", ")} } from './collections.mjs'`,
|
|
16
|
-
|
|
16
|
+
dts: `export { ${symbolsToExport.map((symbol) => `${symbol.id}`).join(", ")} } from './collections.mjs'`
|
|
17
17
|
},
|
|
18
18
|
main: {
|
|
19
19
|
js: (hasContracts ? "export * as contracts from './contracts/index.mjs'\n" : "") + `export * as collections from './collections/index.mjs'
|
|
20
20
|
export { ${symbolsToExport.map((symbol) => symbol.extend).join(", ")} } from './collections/collections.mjs'`,
|
|
21
|
-
|
|
21
|
+
dts: (hasContracts ? "export * as contracts from './contracts/index.mjs'\n" : "") + `export * as collections from './collections/index.mjs'
|
|
22
22
|
export { ${symbolsToExport.map((symbol) => `${symbol.extend}, ${symbol.schema}`).join(", ")} } from './collections/collections.mjs'`
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
if (hasContracts) {
|
|
26
26
|
exports.contracts = {
|
|
27
27
|
js: "export * from './contracts.mjs'",
|
|
28
|
-
|
|
28
|
+
dts: "export * from './contracts.mjs'"
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
return exports;
|
|
@@ -47,10 +47,10 @@ const makeJSCollectionSchema = (collectionNode, collectionId) => {
|
|
|
47
47
|
}
|
|
48
48
|
switch (key) {
|
|
49
49
|
case 'properties':
|
|
50
|
-
collectionSchema.description
|
|
50
|
+
collectionSchema.description[key] = (0, utils_js_1.getProperties)(collectionNode[key]);
|
|
51
51
|
break;
|
|
52
52
|
case 'owned':
|
|
53
|
-
collectionSchema.description
|
|
53
|
+
collectionSchema.description[key] = collectionNode[key];
|
|
54
54
|
break;
|
|
55
55
|
case 'functions':
|
|
56
56
|
collectionSchema.functions = {
|
|
@@ -40,10 +40,10 @@ const makeJSCollectionSchema = (collectionNode, collectionId) => {
|
|
|
40
40
|
}
|
|
41
41
|
switch (key) {
|
|
42
42
|
case "properties":
|
|
43
|
-
collectionSchema.description
|
|
43
|
+
collectionSchema.description[key] = getProperties(collectionNode[key]);
|
|
44
44
|
break;
|
|
45
45
|
case "owned":
|
|
46
|
-
collectionSchema.description
|
|
46
|
+
collectionSchema.description[key] = collectionNode[key];
|
|
47
47
|
break;
|
|
48
48
|
case "functions":
|
|
49
49
|
collectionSchema.functions = {
|
package/dist/codegen/utils.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare const makeASTImports: (ast: AST.Node[], initialImports?: Record<s
|
|
|
15
15
|
};
|
|
16
16
|
export declare const propertyToSchema: ({ property, nestedProperties }: Pick<AST.PropertyNode, "property" | "nestedProperties">) => Property;
|
|
17
17
|
/** Transforms the AST properties to the format of aeria schema properties */
|
|
18
|
-
export declare const getProperties: <TProperties extends Record<string, AST.PropertyNode | AST.PropertyNode[]>, TReturnType = TProperties[keyof TProperties] extends unknown
|
|
18
|
+
export declare const getProperties: <TProperties extends Record<string, AST.PropertyNode | AST.PropertyNode[]>, TReturnType = TProperties[keyof TProperties] extends Array<unknown> ? Record<string, Property[]> : Record<string, Property>>(properties: TProperties) => TReturnType;
|
|
19
19
|
export declare const UnquotedSymbol: unique symbol;
|
|
20
20
|
/** Serves to know if the value must be unquoted on strinfigy function */
|
|
21
21
|
export type StringifyProperty = unknown | {
|
package/dist/codegen.js
CHANGED
|
@@ -77,17 +77,17 @@ const generateCode = async (ast, options) => {
|
|
|
77
77
|
['collections']: {
|
|
78
78
|
['collections.d.ts']: (0, index_js_1.generateTSCollections)(ast.collections),
|
|
79
79
|
['collections.js']: (0, index_js_1.generateJSCollections)(ast.collections),
|
|
80
|
-
['index.d.ts']: exports.collections.
|
|
80
|
+
['index.d.ts']: exports.collections.dts,
|
|
81
81
|
['index.js']: exports.collections.js,
|
|
82
82
|
},
|
|
83
|
-
['index.d.ts']: exports.main.
|
|
83
|
+
['index.d.ts']: exports.main.dts,
|
|
84
84
|
['index.js']: exports.main.js,
|
|
85
85
|
};
|
|
86
86
|
if (contracts) {
|
|
87
87
|
fileTree.contracts = {
|
|
88
88
|
['contracts.js']: contracts.js,
|
|
89
|
-
['contracts.d.ts']: contracts.
|
|
90
|
-
['index.d.ts']: exports.contracts.
|
|
89
|
+
['contracts.d.ts']: contracts.dts,
|
|
90
|
+
['index.d.ts']: exports.contracts.dts,
|
|
91
91
|
['index.js']: exports.contracts.js,
|
|
92
92
|
};
|
|
93
93
|
}
|
package/dist/codegen.mjs
CHANGED
|
@@ -28,17 +28,17 @@ export const generateCode = async (ast, options) => {
|
|
|
28
28
|
["collections"]: {
|
|
29
29
|
["collections.d.ts"]: generateTSCollections(ast.collections),
|
|
30
30
|
["collections.mjs"]: generateJSCollections(ast.collections),
|
|
31
|
-
["index.d.ts"]: exports.collections.
|
|
31
|
+
["index.d.ts"]: exports.collections.dts,
|
|
32
32
|
["index.mjs"]: exports.collections.js
|
|
33
33
|
},
|
|
34
|
-
["index.d.ts"]: exports.main.
|
|
34
|
+
["index.d.ts"]: exports.main.dts,
|
|
35
35
|
["index.mjs"]: exports.main.js
|
|
36
36
|
};
|
|
37
37
|
if (contracts) {
|
|
38
38
|
fileTree.contracts = {
|
|
39
39
|
["contracts.mjs"]: contracts.js,
|
|
40
|
-
["contracts.d.ts"]: contracts.
|
|
41
|
-
["index.d.ts"]: exports.contracts.
|
|
40
|
+
["contracts.d.ts"]: contracts.dts,
|
|
41
|
+
["index.d.ts"]: exports.contracts.dts,
|
|
42
42
|
["index.mjs"]: exports.contracts.js
|
|
43
43
|
};
|
|
44
44
|
}
|
package/dist/compile.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Diagnostic } from './diagnostic.js';
|
|
|
3
3
|
export declare const FILE_PRECEDENCE: string[];
|
|
4
4
|
export declare const parseAndCheck: (sources: Record<string, string>, options?: Pick<CompilationOptions, "languageServer">) => Promise<CompilationResult>;
|
|
5
5
|
export declare const generateScaffolding: (options: CompilationOptions) => Promise<string[]>;
|
|
6
|
-
export declare const compileFromFiles: (
|
|
6
|
+
export declare const compileFromFiles: (globPattern: string, options: CompilationOptions) => Promise<CompilationResult | {
|
|
7
7
|
emittedFiles: Record<string, string>;
|
|
8
8
|
success: boolean;
|
|
9
9
|
ast?: import("./ast.js").ProgramNode;
|
package/dist/compile.js
CHANGED
|
@@ -44,28 +44,23 @@ const fs = __importStar(require("node:fs"));
|
|
|
44
44
|
exports.FILE_PRECEDENCE = ['contract'];
|
|
45
45
|
const parseAndCheck = async (sources, options = {}) => {
|
|
46
46
|
const errors = [];
|
|
47
|
-
let errorCount = 0;
|
|
48
47
|
let ast;
|
|
48
|
+
const allTokens = [];
|
|
49
49
|
for (const fileName in sources) {
|
|
50
50
|
diagnostic_js_1.Diagnostic.currentFile = fileName;
|
|
51
51
|
const { errors: lexerErrors, tokens } = (0, lexer_js_1.tokenize)(sources[fileName]);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
errors.push(...lexerErrors.concat(parserErrors, semanticErrors));
|
|
55
|
-
errorCount += errors.length;
|
|
56
|
-
if (!ast) {
|
|
57
|
-
ast = currentAst;
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
ast.collections.push(...currentAst.collections);
|
|
61
|
-
ast.contracts.push(...currentAst.contracts);
|
|
62
|
-
ast.functionsets.push(...currentAst.functionsets);
|
|
52
|
+
if (lexerErrors.length > 0) {
|
|
53
|
+
errors.push(...lexerErrors);
|
|
63
54
|
}
|
|
55
|
+
allTokens.push(...tokens);
|
|
64
56
|
}
|
|
57
|
+
const { errors: parserErrors, ast: currentAst } = (0, parser_js_1.parse)(allTokens);
|
|
58
|
+
const { errors: semanticErrors } = await (0, semantic_js_1.analyze)(currentAst, options);
|
|
59
|
+
errors.push(...parserErrors.concat(semanticErrors));
|
|
65
60
|
return {
|
|
66
|
-
success:
|
|
61
|
+
success: errors.length === 0,
|
|
67
62
|
errors,
|
|
68
|
-
errorCount,
|
|
63
|
+
errorCount: errors.length,
|
|
69
64
|
ast,
|
|
70
65
|
};
|
|
71
66
|
};
|
|
@@ -80,8 +75,8 @@ const generateScaffolding = async (options) => {
|
|
|
80
75
|
return directories;
|
|
81
76
|
};
|
|
82
77
|
exports.generateScaffolding = generateScaffolding;
|
|
83
|
-
const compileFromFiles = async (
|
|
84
|
-
const fileList = await Array.fromAsync(fs.promises.glob(
|
|
78
|
+
const compileFromFiles = async (globPattern, options) => {
|
|
79
|
+
const fileList = await Array.fromAsync(fs.promises.glob(globPattern));
|
|
85
80
|
const sortedFileList = fileList.sort((a, b) => {
|
|
86
81
|
const aIndex = exports.FILE_PRECEDENCE.findIndex((file) => a.split('/').at(-1).startsWith(file));
|
|
87
82
|
const bIndex = exports.FILE_PRECEDENCE.findIndex((file) => b.split('/').at(-1).startsWith(file));
|
package/dist/compile.mjs
CHANGED
|
@@ -9,27 +9,23 @@ import * as fs from "node:fs";
|
|
|
9
9
|
export const FILE_PRECEDENCE = ["contract"];
|
|
10
10
|
export const parseAndCheck = async (sources, options = {}) => {
|
|
11
11
|
const errors = [];
|
|
12
|
-
let errorCount = 0;
|
|
13
12
|
let ast;
|
|
13
|
+
const allTokens = [];
|
|
14
14
|
for (const fileName in sources) {
|
|
15
15
|
Diagnostic.currentFile = fileName;
|
|
16
16
|
const { errors: lexerErrors, tokens } = tokenize(sources[fileName]);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
errors.push(...lexerErrors.concat(parserErrors, semanticErrors));
|
|
20
|
-
errorCount += errors.length;
|
|
21
|
-
if (!ast) {
|
|
22
|
-
ast = currentAst;
|
|
23
|
-
} else {
|
|
24
|
-
ast.collections.push(...currentAst.collections);
|
|
25
|
-
ast.contracts.push(...currentAst.contracts);
|
|
26
|
-
ast.functionsets.push(...currentAst.functionsets);
|
|
17
|
+
if (lexerErrors.length > 0) {
|
|
18
|
+
errors.push(...lexerErrors);
|
|
27
19
|
}
|
|
20
|
+
allTokens.push(...tokens);
|
|
28
21
|
}
|
|
22
|
+
const { errors: parserErrors, ast: currentAst } = parse(allTokens);
|
|
23
|
+
const { errors: semanticErrors } = await analyze(currentAst, options);
|
|
24
|
+
errors.push(...parserErrors.concat(semanticErrors));
|
|
29
25
|
return {
|
|
30
|
-
success:
|
|
26
|
+
success: errors.length === 0,
|
|
31
27
|
errors,
|
|
32
|
-
errorCount,
|
|
28
|
+
errorCount: errors.length,
|
|
33
29
|
ast
|
|
34
30
|
};
|
|
35
31
|
};
|
|
@@ -42,8 +38,8 @@ export const generateScaffolding = async (options) => {
|
|
|
42
38
|
}
|
|
43
39
|
return directories;
|
|
44
40
|
};
|
|
45
|
-
export const compileFromFiles = async (
|
|
46
|
-
const fileList = await Array.fromAsync(fs.promises.glob(
|
|
41
|
+
export const compileFromFiles = async (globPattern, options) => {
|
|
42
|
+
const fileList = await Array.fromAsync(fs.promises.glob(globPattern));
|
|
47
43
|
const sortedFileList = fileList.sort((a, b) => {
|
|
48
44
|
const aIndex = FILE_PRECEDENCE.findIndex((file) => a.split("/").at(-1).startsWith(file));
|
|
49
45
|
const bIndex = FILE_PRECEDENCE.findIndex((file) => b.split("/").at(-1).startsWith(file));
|
package/dist/parser.js
CHANGED
|
@@ -179,6 +179,9 @@ const parse = (tokens) => {
|
|
|
179
179
|
array.push(identifier);
|
|
180
180
|
symbols.push(elemSymbol);
|
|
181
181
|
exports.locationMap.set(elemSymbol, location);
|
|
182
|
+
if (match(token_js_1.TokenType.Comma)) {
|
|
183
|
+
consume(token_js_1.TokenType.Comma);
|
|
184
|
+
}
|
|
182
185
|
}
|
|
183
186
|
consume(token_js_1.TokenType.RightBracket);
|
|
184
187
|
return {
|
|
@@ -225,6 +228,22 @@ const parse = (tokens) => {
|
|
|
225
228
|
]).value;
|
|
226
229
|
return;
|
|
227
230
|
}
|
|
231
|
+
if ('const' in property && attributeName === 'value') {
|
|
232
|
+
const token = current();
|
|
233
|
+
advance();
|
|
234
|
+
switch (token.type) {
|
|
235
|
+
case token_js_1.TokenType.Number:
|
|
236
|
+
case token_js_1.TokenType.Boolean:
|
|
237
|
+
case token_js_1.TokenType.Null:
|
|
238
|
+
case token_js_1.TokenType.QuotedString: {
|
|
239
|
+
property.const = token.value;
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
default: {
|
|
243
|
+
throw new diagnostic_js_1.Diagnostic(`const received invalid value: "${token.value}"`, location);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
228
247
|
switch (attributeName) {
|
|
229
248
|
case 'icon': {
|
|
230
249
|
const { value } = consume(token_js_1.TokenType.QuotedString, ICON_NAMES);
|
|
@@ -360,6 +379,8 @@ const parse = (tokens) => {
|
|
|
360
379
|
let property;
|
|
361
380
|
let nestedProperties;
|
|
362
381
|
let modifierToken;
|
|
382
|
+
const typeSymbol = Symbol();
|
|
383
|
+
exports.locationMap.set(typeSymbol, next().location);
|
|
363
384
|
if (match(token_js_1.TokenType.LeftSquareBracket)) {
|
|
364
385
|
consume(token_js_1.TokenType.LeftSquareBracket);
|
|
365
386
|
const arrayProperty = {
|
|
@@ -368,6 +389,7 @@ const parse = (tokens) => {
|
|
|
368
389
|
while (!match(token_js_1.TokenType.RightSquareBracket)) {
|
|
369
390
|
const attributeSymbol = Symbol();
|
|
370
391
|
arrayProperty[AST.LOCATION_SYMBOL] ??= {
|
|
392
|
+
type: typeSymbol,
|
|
371
393
|
attributes: {},
|
|
372
394
|
arrays: {},
|
|
373
395
|
};
|
|
@@ -425,6 +447,7 @@ const parse = (tokens) => {
|
|
|
425
447
|
type: 'object',
|
|
426
448
|
properties: {},
|
|
427
449
|
[AST.LOCATION_SYMBOL]: {
|
|
450
|
+
type: typeSymbol,
|
|
428
451
|
attributes: {},
|
|
429
452
|
arrays: {},
|
|
430
453
|
},
|
|
@@ -452,7 +475,7 @@ const parse = (tokens) => {
|
|
|
452
475
|
consume(token_js_1.TokenType.RightBracket);
|
|
453
476
|
}
|
|
454
477
|
else {
|
|
455
|
-
const { value: identifier
|
|
478
|
+
const { value: identifier } = consume(token_js_1.TokenType.Identifier);
|
|
456
479
|
if (guards.isNativePropertyType(identifier)) {
|
|
457
480
|
switch (identifier) {
|
|
458
481
|
case 'enum': {
|
|
@@ -461,6 +484,12 @@ const parse = (tokens) => {
|
|
|
461
484
|
};
|
|
462
485
|
break;
|
|
463
486
|
}
|
|
487
|
+
case 'const': {
|
|
488
|
+
property = {
|
|
489
|
+
const: null,
|
|
490
|
+
};
|
|
491
|
+
break;
|
|
492
|
+
}
|
|
464
493
|
case 'date': {
|
|
465
494
|
property = {
|
|
466
495
|
type: 'string',
|
|
@@ -482,12 +511,13 @@ const parse = (tokens) => {
|
|
|
482
511
|
}
|
|
483
512
|
}
|
|
484
513
|
else {
|
|
485
|
-
const collection = ast.collections.find((node) => node.name === identifier);
|
|
486
|
-
if (!collection) {
|
|
487
|
-
throw new diagnostic_js_1.Diagnostic(`invalid reference "${identifier}"`, location);
|
|
488
|
-
}
|
|
489
514
|
property = {
|
|
490
515
|
$ref: identifier,
|
|
516
|
+
[AST.LOCATION_SYMBOL]: {
|
|
517
|
+
type: typeSymbol,
|
|
518
|
+
attributes: {},
|
|
519
|
+
arrays: {},
|
|
520
|
+
},
|
|
491
521
|
};
|
|
492
522
|
}
|
|
493
523
|
}
|
|
@@ -498,6 +528,7 @@ const parse = (tokens) => {
|
|
|
498
528
|
const attributeSymbol = Symbol();
|
|
499
529
|
exports.locationMap.set(attributeSymbol, next().location);
|
|
500
530
|
property[AST.LOCATION_SYMBOL] ??= {
|
|
531
|
+
type: typeSymbol,
|
|
501
532
|
attributes: {},
|
|
502
533
|
arrays: {},
|
|
503
534
|
};
|
package/dist/parser.mjs
CHANGED
|
@@ -141,6 +141,9 @@ export const parse = (tokens) => {
|
|
|
141
141
|
array.push(identifier);
|
|
142
142
|
symbols.push(elemSymbol);
|
|
143
143
|
locationMap.set(elemSymbol, location);
|
|
144
|
+
if (match(TokenType.Comma)) {
|
|
145
|
+
consume(TokenType.Comma);
|
|
146
|
+
}
|
|
144
147
|
}
|
|
145
148
|
consume(TokenType.RightBracket);
|
|
146
149
|
return {
|
|
@@ -184,6 +187,22 @@ export const parse = (tokens) => {
|
|
|
184
187
|
]).value;
|
|
185
188
|
return;
|
|
186
189
|
}
|
|
190
|
+
if ("const" in property && attributeName === "value") {
|
|
191
|
+
const token = current();
|
|
192
|
+
advance();
|
|
193
|
+
switch (token.type) {
|
|
194
|
+
case TokenType.Number:
|
|
195
|
+
case TokenType.Boolean:
|
|
196
|
+
case TokenType.Null:
|
|
197
|
+
case TokenType.QuotedString: {
|
|
198
|
+
property.const = token.value;
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
default: {
|
|
202
|
+
throw new Diagnostic(`const received invalid value: "${token.value}"`, location);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
187
206
|
switch (attributeName) {
|
|
188
207
|
case "icon": {
|
|
189
208
|
const { value } = consume(TokenType.QuotedString, ICON_NAMES);
|
|
@@ -318,6 +337,8 @@ export const parse = (tokens) => {
|
|
|
318
337
|
let property;
|
|
319
338
|
let nestedProperties;
|
|
320
339
|
let modifierToken;
|
|
340
|
+
const typeSymbol = Symbol();
|
|
341
|
+
locationMap.set(typeSymbol, next().location);
|
|
321
342
|
if (match(TokenType.LeftSquareBracket)) {
|
|
322
343
|
consume(TokenType.LeftSquareBracket);
|
|
323
344
|
const arrayProperty = {
|
|
@@ -326,6 +347,7 @@ export const parse = (tokens) => {
|
|
|
326
347
|
while (!match(TokenType.RightSquareBracket)) {
|
|
327
348
|
const attributeSymbol = Symbol();
|
|
328
349
|
arrayProperty[AST.LOCATION_SYMBOL] ??= {
|
|
350
|
+
type: typeSymbol,
|
|
329
351
|
attributes: {},
|
|
330
352
|
arrays: {}
|
|
331
353
|
};
|
|
@@ -381,6 +403,7 @@ export const parse = (tokens) => {
|
|
|
381
403
|
type: "object",
|
|
382
404
|
properties: {},
|
|
383
405
|
[AST.LOCATION_SYMBOL]: {
|
|
406
|
+
type: typeSymbol,
|
|
384
407
|
attributes: {},
|
|
385
408
|
arrays: {}
|
|
386
409
|
}
|
|
@@ -407,7 +430,7 @@ export const parse = (tokens) => {
|
|
|
407
430
|
}
|
|
408
431
|
consume(TokenType.RightBracket);
|
|
409
432
|
} else {
|
|
410
|
-
const { value: identifier
|
|
433
|
+
const { value: identifier } = consume(TokenType.Identifier);
|
|
411
434
|
if (guards.isNativePropertyType(identifier)) {
|
|
412
435
|
switch (identifier) {
|
|
413
436
|
case "enum": {
|
|
@@ -416,6 +439,12 @@ export const parse = (tokens) => {
|
|
|
416
439
|
};
|
|
417
440
|
break;
|
|
418
441
|
}
|
|
442
|
+
case "const": {
|
|
443
|
+
property = {
|
|
444
|
+
const: null
|
|
445
|
+
};
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
419
448
|
case "date": {
|
|
420
449
|
property = {
|
|
421
450
|
type: "string",
|
|
@@ -436,12 +465,13 @@ export const parse = (tokens) => {
|
|
|
436
465
|
};
|
|
437
466
|
}
|
|
438
467
|
} else {
|
|
439
|
-
const collection = ast.collections.find((node2) => node2.name === identifier);
|
|
440
|
-
if (!collection) {
|
|
441
|
-
throw new Diagnostic(`invalid reference "${identifier}"`, location);
|
|
442
|
-
}
|
|
443
468
|
property = {
|
|
444
|
-
$ref: identifier
|
|
469
|
+
$ref: identifier,
|
|
470
|
+
[AST.LOCATION_SYMBOL]: {
|
|
471
|
+
type: typeSymbol,
|
|
472
|
+
attributes: {},
|
|
473
|
+
arrays: {}
|
|
474
|
+
}
|
|
445
475
|
};
|
|
446
476
|
}
|
|
447
477
|
}
|
|
@@ -452,6 +482,7 @@ export const parse = (tokens) => {
|
|
|
452
482
|
const attributeSymbol = Symbol();
|
|
453
483
|
locationMap.set(attributeSymbol, next().location);
|
|
454
484
|
property[AST.LOCATION_SYMBOL] ??= {
|
|
485
|
+
type: typeSymbol,
|
|
455
486
|
attributes: {},
|
|
456
487
|
arrays: {}
|
|
457
488
|
};
|
package/dist/semantic.js
CHANGED
|
@@ -110,7 +110,9 @@ const analyze = async (ast, options, errors = []) => {
|
|
|
110
110
|
const refName = node.property.$ref;
|
|
111
111
|
const foreignCollection = ast.collections.find(({ name }) => name === refName);
|
|
112
112
|
if (!foreignCollection) {
|
|
113
|
-
|
|
113
|
+
const location = parser_js_1.locationMap.get(node.property[AST.LOCATION_SYMBOL].type);
|
|
114
|
+
errors.push(new diagnostic_js_1.Diagnostic(`invalid reference "${refName}"`, location));
|
|
115
|
+
return;
|
|
114
116
|
}
|
|
115
117
|
await checkCollectionForeignProperties(foreignCollection, node.property, 'indexes');
|
|
116
118
|
await checkCollectionForeignProperties(foreignCollection, node.property, 'populate');
|
package/dist/semantic.mjs
CHANGED
|
@@ -74,7 +74,9 @@ export const analyze = async (ast, options, errors = []) => {
|
|
|
74
74
|
const refName = node.property.$ref;
|
|
75
75
|
const foreignCollection = ast.collections.find(({ name }) => name === refName);
|
|
76
76
|
if (!foreignCollection) {
|
|
77
|
-
|
|
77
|
+
const location = locationMap.get(node.property[AST.LOCATION_SYMBOL].type);
|
|
78
|
+
errors.push(new Diagnostic(`invalid reference "${refName}"`, location));
|
|
79
|
+
return;
|
|
78
80
|
}
|
|
79
81
|
await checkCollectionForeignProperties(foreignCollection, node.property, "indexes");
|
|
80
82
|
await checkCollectionForeignProperties(foreignCollection, node.property, "populate");
|
package/dist/token.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare const TokenType: {
|
|
|
12
12
|
readonly Dot: "DOT";
|
|
13
13
|
readonly Number: "NUMBER";
|
|
14
14
|
readonly Boolean: "BOOLEAN";
|
|
15
|
+
readonly Null: "NULL";
|
|
15
16
|
readonly Keyword: "KEYWORD";
|
|
16
17
|
readonly Identifier: "IDENTIFIER";
|
|
17
18
|
readonly QuotedString: "QUOTED_STRING";
|
|
@@ -23,6 +24,7 @@ export type TokenType = typeof TokenType[keyof typeof TokenType];
|
|
|
23
24
|
export type TypeMap = {
|
|
24
25
|
[TokenType.Number]: number;
|
|
25
26
|
[TokenType.Boolean]: boolean;
|
|
27
|
+
[TokenType.Null]: null;
|
|
26
28
|
[TokenType.Range]: readonly [number, number];
|
|
27
29
|
};
|
|
28
30
|
export type Location = {
|
package/dist/token.js
CHANGED
package/dist/token.mjs
CHANGED