@aeriajs/compiler 0.0.41 → 0.0.42

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 CHANGED
@@ -66,6 +66,7 @@ export type CollectionNode = NodeBase<'collection'> & {
66
66
  functions?: Record<string, {
67
67
  accessCondition: AccessCondition;
68
68
  }>;
69
+ functionSets?: [string, symbol][];
69
70
  required?: RequiredProperties;
70
71
  indexes?: readonly string[];
71
72
  presets?: DescriptionPreset[];
@@ -97,6 +98,7 @@ export type FunctionSetNode = NodeBase<'functionset'> & {
97
98
  accessCondition: AccessCondition;
98
99
  fromFunctionSet?: true;
99
100
  }>;
101
+ functionSets: [string, symbol][];
100
102
  };
101
103
  export type ProgramNode = NodeBase<'program'> & {
102
104
  collections: CollectionNode[];
@@ -1,5 +1,5 @@
1
1
  import type * as AST from '../ast.js';
2
- export declare const generateContracts: (ast: AST.Node[]) => false | {
2
+ export declare const generateContracts: (ast: AST.ProgramNode) => false | {
3
3
  js: string;
4
4
  dts: string;
5
5
  };
@@ -4,17 +4,16 @@ exports.generateContracts = void 0;
4
4
  const types_1 = require("@aeriajs/types");
5
5
  const utils_js_1 = require("./utils.js");
6
6
  const generateContracts = (ast) => {
7
- const contractNodes = ast.filter((node) => node.kind === 'contract');
8
- if (contractNodes.length === 0) {
7
+ if (ast.contracts.length === 0) {
9
8
  return false;
10
9
  }
11
10
  return {
12
- js: makeJSContractsCode(contractNodes),
13
- dts: makeTSContractsCode(contractNodes),
11
+ js: makeJSContractsCode(ast),
12
+ dts: makeTSContractsCode(ast),
14
13
  };
15
14
  };
16
15
  exports.generateContracts = generateContracts;
17
- const makeJSContractsCode = (contractAst) => {
16
+ const makeJSContractsCode = (ast) => {
18
17
  const imports = new Set(['defineContract']);
19
18
  const getCodeForResponse = (responseProperty) => {
20
19
  const { kind, modifier, ...propertyNode } = responseProperty;
@@ -29,8 +28,8 @@ const makeJSContractsCode = (contractAst) => {
29
28
  }
30
29
  return `${modifierSymbol}(${(0, utils_js_1.stringify)((0, utils_js_1.unwrapPropertyNode)(propertyNode))})`;
31
30
  };
32
- const declarations = contractAst.map((contractNode) => {
33
- const { name, kind, roles, response, ...contractProperty } = contractNode;
31
+ const declarations = ast.contracts.map((node) => {
32
+ const { name, kind, roles, response, ...contractProperty } = node;
34
33
  let responseString;
35
34
  if (response) {
36
35
  responseString = '';
@@ -69,9 +68,9 @@ const getResponseSchema = (response) => {
69
68
  (0, types_1.resultSchema)(responseSchema) :
70
69
  (0, types_1.errorSchema)(responseSchema);
71
70
  };
72
- const makeTSContractsCode = (contractAst) => {
73
- return contractAst.map((contractNode) => {
74
- const { name, kind, roles, ...contractSchema } = contractNode;
71
+ const makeTSContractsCode = (ast) => {
72
+ return ast.contracts.map((node) => {
73
+ const { name, kind, roles, ...contractSchema } = node;
75
74
  let responseSchema = null;
76
75
  if (contractSchema.response) {
77
76
  if (Array.isArray(contractSchema.response)) {
@@ -88,6 +87,6 @@ const makeTSContractsCode = (contractAst) => {
88
87
  if (roles) {
89
88
  contractProperties.roles = roles;
90
89
  }
91
- return `export declare const ${contractNode.name}: ${(0, utils_js_1.stringify)(contractProperties)}`;
90
+ return `export declare const ${node.name}: ${(0, utils_js_1.stringify)(contractProperties)}`;
92
91
  }).join('\n\n');
93
92
  };
@@ -2,16 +2,15 @@
2
2
  import { errorSchema, resultSchema } from "@aeriajs/types";
3
3
  import { recursivelyUnwrapPropertyNodes, unwrapPropertyNode, stringify, UnquotedSymbol } from "./utils.mjs";
4
4
  export const generateContracts = (ast) => {
5
- const contractNodes = ast.filter((node) => node.kind === "contract");
6
- if (contractNodes.length === 0) {
5
+ if (ast.contracts.length === 0) {
7
6
  return false;
8
7
  }
9
8
  return {
10
- js: makeJSContractsCode(contractNodes),
11
- dts: makeTSContractsCode(contractNodes)
9
+ js: makeJSContractsCode(ast),
10
+ dts: makeTSContractsCode(ast)
12
11
  };
13
12
  };
14
- const makeJSContractsCode = (contractAst) => {
13
+ const makeJSContractsCode = (ast) => {
15
14
  const imports = /* @__PURE__ */ new Set(["defineContract"]);
16
15
  const getCodeForResponse = (responseProperty) => {
17
16
  const { kind, modifier, ...propertyNode } = responseProperty;
@@ -24,8 +23,8 @@ const makeJSContractsCode = (contractAst) => {
24
23
  }
25
24
  return `${modifierSymbol}(${stringify(unwrapPropertyNode(propertyNode))})`;
26
25
  };
27
- const declarations = contractAst.map((contractNode) => {
28
- const { name, kind, roles, response, ...contractProperty } = contractNode;
26
+ const declarations = ast.contracts.map((node) => {
27
+ const { name, kind, roles, response, ...contractProperty } = node;
29
28
  let responseString;
30
29
  if (response) {
31
30
  responseString = "";
@@ -63,9 +62,9 @@ const getResponseSchema = (response) => {
63
62
  }
64
63
  return response.modifier === "Result" ? resultSchema(responseSchema) : errorSchema(responseSchema);
65
64
  };
66
- const makeTSContractsCode = (contractAst) => {
67
- return contractAst.map((contractNode) => {
68
- const { name, kind, roles, ...contractSchema } = contractNode;
65
+ const makeTSContractsCode = (ast) => {
66
+ return ast.contracts.map((node) => {
67
+ const { name, kind, roles, ...contractSchema } = node;
69
68
  let responseSchema = null;
70
69
  if (contractSchema.response) {
71
70
  if (Array.isArray(contractSchema.response)) {
@@ -81,6 +80,6 @@ const makeTSContractsCode = (contractAst) => {
81
80
  if (roles) {
82
81
  contractProperties.roles = roles;
83
82
  }
84
- return `export declare const ${contractNode.name}: ${stringify(contractProperties)}`;
83
+ return `export declare const ${node.name}: ${stringify(contractProperties)}`;
85
84
  }).join("\n\n");
86
85
  };
@@ -1,2 +1,2 @@
1
1
  import type * as AST from '../ast.js';
2
- export declare const generateJSCollections: (ast: AST.CollectionNode[]) => string;
2
+ export declare const generateJSCollections: (ast: AST.ProgramNode) => string;
@@ -8,7 +8,7 @@ const initialImportedFunctions = [
8
8
  ];
9
9
  const generateJSCollections = (ast) => {
10
10
  let javascriptCode = '';
11
- const importsResult = (0, utils_js_1.makeASTImports)(ast, {
11
+ const importsResult = (0, utils_js_1.makeASTImports)(ast.collections, {
12
12
  [utils_js_1.PACKAGE_NAME]: new Set(initialImportedFunctions),
13
13
  }, {
14
14
  includeRuntimeOnlyImports: true,
@@ -20,14 +20,14 @@ const generateJSCollections = (ast) => {
20
20
  exports.generateJSCollections = generateJSCollections;
21
21
  const makeJSCollections = (ast, modifiedSymbols) => {
22
22
  const collectionCodes = {};
23
- for (const collectionNode of ast) {
23
+ for (const collectionNode of ast.collections) {
24
24
  const id = (0, utils_js_1.getCollectionId)(collectionNode.name); // CollectionName -> collectionName
25
25
  const extendCollectionName = (0, utils_js_1.getExtendName)(collectionNode.name);
26
26
  const collectionDefinition = `export const ${id} = ${collectionNode.extends
27
27
  ? `extendCollection(${id in modifiedSymbols
28
28
  ? modifiedSymbols[id]
29
- : id}, ${makeJSCollectionSchema(collectionNode, id)})`
30
- : `defineCollection(${makeJSCollectionSchema(collectionNode, id)})`}`;
29
+ : id}, ${makeJSCollectionSchema(ast, collectionNode, id)})`
30
+ : `defineCollection(${makeJSCollectionSchema(ast, collectionNode, id)})`}`;
31
31
  const collectionDeclaration = `export const ${extendCollectionName} = (collection) => extendCollection(${id}, collection)`;
32
32
  collectionCodes[collectionNode.name] = [
33
33
  '//' + collectionNode.name,
@@ -37,7 +37,7 @@ const makeJSCollections = (ast, modifiedSymbols) => {
37
37
  }
38
38
  return Object.values(collectionCodes).join('\n\n');
39
39
  };
40
- const makeJSCollectionSchema = (collectionNode, collectionId) => {
40
+ const makeJSCollectionSchema = (ast, collectionNode, collectionId) => {
41
41
  const collectionSchema = {
42
42
  item: {},
43
43
  description: {
@@ -6,7 +6,7 @@ const initialImportedFunctions = [
6
6
  ];
7
7
  export const generateJSCollections = (ast) => {
8
8
  let javascriptCode = "";
9
- const importsResult = makeASTImports(ast, {
9
+ const importsResult = makeASTImports(ast.collections, {
10
10
  [PACKAGE_NAME]: new Set(initialImportedFunctions)
11
11
  }, {
12
12
  includeRuntimeOnlyImports: true
@@ -17,10 +17,10 @@ export const generateJSCollections = (ast) => {
17
17
  };
18
18
  const makeJSCollections = (ast, modifiedSymbols) => {
19
19
  const collectionCodes = {};
20
- for (const collectionNode of ast) {
20
+ for (const collectionNode of ast.collections) {
21
21
  const id = getCollectionId(collectionNode.name);
22
22
  const extendCollectionName = getExtendName(collectionNode.name);
23
- const collectionDefinition = `export const ${id} = ${collectionNode.extends ? `extendCollection(${id in modifiedSymbols ? modifiedSymbols[id] : id}, ${makeJSCollectionSchema(collectionNode, id)})` : `defineCollection(${makeJSCollectionSchema(collectionNode, id)})`}`;
23
+ const collectionDefinition = `export const ${id} = ${collectionNode.extends ? `extendCollection(${id in modifiedSymbols ? modifiedSymbols[id] : id}, ${makeJSCollectionSchema(ast, collectionNode, id)})` : `defineCollection(${makeJSCollectionSchema(ast, collectionNode, id)})`}`;
24
24
  const collectionDeclaration = `export const ${extendCollectionName} = (collection) => extendCollection(${id}, collection)`;
25
25
  collectionCodes[collectionNode.name] = [
26
26
  "//" + collectionNode.name,
@@ -30,7 +30,7 @@ const makeJSCollections = (ast, modifiedSymbols) => {
30
30
  }
31
31
  return Object.values(collectionCodes).join("\n\n");
32
32
  };
33
- const makeJSCollectionSchema = (collectionNode, collectionId) => {
33
+ const makeJSCollectionSchema = (ast, collectionNode, collectionId) => {
34
34
  const collectionSchema = {
35
35
  item: {},
36
36
  description: {
@@ -1,2 +1,2 @@
1
1
  import type * as AST from '../ast.js';
2
- export declare const generateTSCollections: (ast: AST.CollectionNode[]) => string;
2
+ export declare const generateTSCollections: (ast: AST.ProgramNode) => string;
@@ -11,7 +11,7 @@ const initialImportedTypes = [
11
11
  const generateTSCollections = (ast) => {
12
12
  let code = '';
13
13
  code += `import type { ${initialImportedTypes.join(', ')} } from '${utils_js_1.PACKAGE_NAME}'\n`; //Used types
14
- const importsResult = (0, utils_js_1.makeASTImports)(ast);
14
+ const importsResult = (0, utils_js_1.makeASTImports)(ast.collections);
15
15
  code += importsResult.code.join('\n') + '\n\n';
16
16
  code += makeTSCollections(ast, importsResult.modifiedSymbols) + '\n';
17
17
  return code;
@@ -19,7 +19,7 @@ const generateTSCollections = (ast) => {
19
19
  exports.generateTSCollections = generateTSCollections;
20
20
  const makeTSCollections = (ast, modifiedSymbols) => {
21
21
  const collectionCodes = {};
22
- for (const collectionNode of ast) {
22
+ for (const collectionNode of ast.collections) {
23
23
  const id = (0, utils_js_1.getCollectionId)(collectionNode.name); // CollectionName -> collectionName
24
24
  const schemaName = (0, utils_js_1.resizeFirstChar)(collectionNode.name, true); // collectionName -> CollectionName
25
25
  const typeName = id + 'Collection'; // Pet -> petCollection
@@ -10,14 +10,14 @@ export const generateTSCollections = (ast) => {
10
10
  let code = "";
11
11
  code += `import type { ${initialImportedTypes.join(", ")} } from '${PACKAGE_NAME}'
12
12
  `;
13
- const importsResult = makeASTImports(ast);
13
+ const importsResult = makeASTImports(ast.collections);
14
14
  code += importsResult.code.join("\n") + "\n\n";
15
15
  code += makeTSCollections(ast, importsResult.modifiedSymbols) + "\n";
16
16
  return code;
17
17
  };
18
18
  const makeTSCollections = (ast, modifiedSymbols) => {
19
19
  const collectionCodes = {};
20
- for (const collectionNode of ast) {
20
+ for (const collectionNode of ast.collections) {
21
21
  const id = getCollectionId(collectionNode.name);
22
22
  const schemaName = resizeFirstChar(collectionNode.name, true);
23
23
  const typeName = id + "Collection";
package/dist/codegen.js CHANGED
@@ -57,14 +57,14 @@ const generateFileMap = async (fileTree, outDir = '.') => {
57
57
  return mappedPaths;
58
58
  };
59
59
  const generateCode = async (ast, options) => {
60
- const contracts = (0, index_js_1.generateContracts)(ast.contracts);
60
+ const contracts = (0, index_js_1.generateContracts)(ast);
61
61
  const exports = (0, index_js_1.generateExports)(ast, {
62
62
  hasContracts: !!contracts,
63
63
  });
64
64
  const fileTree = {
65
65
  ['collections']: {
66
- ['collections.d.ts']: (0, index_js_1.generateTSCollections)(ast.collections),
67
- ['collections.js']: (0, index_js_1.generateJSCollections)(ast.collections),
66
+ ['collections.d.ts']: (0, index_js_1.generateTSCollections)(ast),
67
+ ['collections.js']: (0, index_js_1.generateJSCollections)(ast),
68
68
  ['index.d.ts']: exports.collections.dts,
69
69
  ['index.js']: exports.collections.js,
70
70
  },
package/dist/codegen.mjs CHANGED
@@ -22,14 +22,14 @@ const generateFileMap = async (fileTree, outDir = ".") => {
22
22
  return mappedPaths;
23
23
  };
24
24
  export const generateCode = async (ast, options) => {
25
- const contracts = generateContracts(ast.contracts);
25
+ const contracts = generateContracts(ast);
26
26
  const exports = generateExports(ast, {
27
27
  hasContracts: !!contracts
28
28
  });
29
29
  const fileTree = {
30
30
  ["collections"]: {
31
- ["collections.d.ts"]: generateTSCollections(ast.collections),
32
- ["collections.mjs"]: generateJSCollections(ast.collections),
31
+ ["collections.d.ts"]: generateTSCollections(ast),
32
+ ["collections.mjs"]: generateJSCollections(ast),
33
33
  ["index.d.ts"]: exports.collections.dts,
34
34
  ["index.mjs"]: exports.collections.js
35
35
  },
package/dist/compile.d.ts CHANGED
@@ -1,11 +1,15 @@
1
+ import type * as AST from './ast.js';
1
2
  import type { CompilationOptions, CompilationResult } from './types.js';
2
3
  import { Diagnostic } from './diagnostic.js';
3
4
  export declare const GLOB_PATTERN = "**/*.aeria";
5
+ export declare const postflight: (ast: AST.ProgramNode) => {
6
+ errors: Diagnostic[];
7
+ };
4
8
  export declare const parseAndCheck: (sources: Record<string, string>, options?: Pick<CompilationOptions, "languageServer">) => Promise<CompilationResult>;
5
9
  export declare const compileFromFiles: (options: CompilationOptions) => Promise<CompilationResult | {
6
10
  emittedFiles: Record<string, string>;
7
11
  success: boolean;
8
- ast?: import("./ast.js").ProgramNode;
12
+ ast?: AST.ProgramNode;
9
13
  errors: Diagnostic[];
10
14
  errorCount: number;
11
15
  }>;
package/dist/compile.js CHANGED
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.compileFromFiles = exports.parseAndCheck = exports.GLOB_PATTERN = void 0;
36
+ exports.compileFromFiles = exports.parseAndCheck = exports.postflight = exports.GLOB_PATTERN = void 0;
37
37
  const diagnostic_js_1 = require("./diagnostic.js");
38
38
  const lexer_js_1 = require("./lexer.js");
39
39
  const parser_js_1 = require("./parser.js");
@@ -41,12 +41,31 @@ const semantic_js_1 = require("./semantic.js");
41
41
  const codegen_js_1 = require("./codegen.js");
42
42
  const fs = __importStar(require("node:fs"));
43
43
  exports.GLOB_PATTERN = '**/*.aeria';
44
+ const postflight = (ast) => {
45
+ const errors = [];
46
+ for (const node of ast.collections) {
47
+ if (node.functionSets?.length) {
48
+ for (const [functionSetName, locationSymbol] of node.functionSets) {
49
+ const functionSet = ast.functionsets.find(({ name }) => name === functionSetName);
50
+ if (!functionSet) {
51
+ const location = parser_js_1.locationMap.get(locationSymbol);
52
+ errors.push(new diagnostic_js_1.Diagnostic(`invalid function set "${functionSetName}"`, location));
53
+ continue;
54
+ }
55
+ Object.assign(node.functions, functionSet.functions);
56
+ }
57
+ }
58
+ }
59
+ return {
60
+ errors,
61
+ };
62
+ };
63
+ exports.postflight = postflight;
44
64
  const parseAndCheck = async (sources, options = {}) => {
45
65
  const errors = [];
46
66
  const allTokens = [];
47
67
  for (const fileName in sources) {
48
- diagnostic_js_1.Diagnostic.currentFile = fileName;
49
- const { errors: lexerErrors, tokens } = (0, lexer_js_1.tokenize)(sources[fileName]);
68
+ const { errors: lexerErrors, tokens } = (0, lexer_js_1.tokenize)(sources[fileName], fileName);
50
69
  if (lexerErrors.length > 0) {
51
70
  errors.push(...lexerErrors);
52
71
  }
@@ -54,7 +73,8 @@ const parseAndCheck = async (sources, options = {}) => {
54
73
  }
55
74
  const { errors: parserErrors, ast } = (0, parser_js_1.parse)(allTokens);
56
75
  const { errors: semanticErrors } = await (0, semantic_js_1.analyze)(ast, options);
57
- errors.push(...parserErrors.concat(semanticErrors));
76
+ const { errors: postflightErrors } = (0, exports.postflight)(ast);
77
+ errors.push(...parserErrors.concat(semanticErrors, postflightErrors));
58
78
  return {
59
79
  success: errors.length === 0,
60
80
  errors,
package/dist/compile.mjs CHANGED
@@ -1,17 +1,35 @@
1
1
  "use strict";
2
2
  import { Diagnostic } from "./diagnostic.mjs";
3
3
  import { tokenize } from "./lexer.mjs";
4
- import { parse } from "./parser.mjs";
4
+ import { parse, locationMap } from "./parser.mjs";
5
5
  import { analyze } from "./semantic.mjs";
6
6
  import { generateCode } from "./codegen.mjs";
7
7
  import * as fs from "node:fs";
8
8
  export const GLOB_PATTERN = "**/*.aeria";
9
+ export const postflight = (ast) => {
10
+ const errors = [];
11
+ for (const node of ast.collections) {
12
+ if (node.functionSets?.length) {
13
+ for (const [functionSetName, locationSymbol] of node.functionSets) {
14
+ const functionSet = ast.functionsets.find(({ name }) => name === functionSetName);
15
+ if (!functionSet) {
16
+ const location = locationMap.get(locationSymbol);
17
+ errors.push(new Diagnostic(`invalid function set "${functionSetName}"`, location));
18
+ continue;
19
+ }
20
+ Object.assign(node.functions, functionSet.functions);
21
+ }
22
+ }
23
+ }
24
+ return {
25
+ errors
26
+ };
27
+ };
9
28
  export const parseAndCheck = async (sources, options = {}) => {
10
29
  const errors = [];
11
30
  const allTokens = [];
12
31
  for (const fileName in sources) {
13
- Diagnostic.currentFile = fileName;
14
- const { errors: lexerErrors, tokens } = tokenize(sources[fileName]);
32
+ const { errors: lexerErrors, tokens } = tokenize(sources[fileName], fileName);
15
33
  if (lexerErrors.length > 0) {
16
34
  errors.push(...lexerErrors);
17
35
  }
@@ -19,7 +37,8 @@ export const parseAndCheck = async (sources, options = {}) => {
19
37
  }
20
38
  const { errors: parserErrors, ast } = parse(allTokens);
21
39
  const { errors: semanticErrors } = await analyze(ast, options);
22
- errors.push(...parserErrors.concat(semanticErrors));
40
+ const { errors: postflightErrors } = postflight(ast);
41
+ errors.push(...parserErrors.concat(semanticErrors, postflightErrors));
23
42
  return {
24
43
  success: errors.length === 0,
25
44
  errors,
@@ -2,7 +2,5 @@ import type { Location } from './token.js';
2
2
  export declare class Diagnostic extends Error {
3
3
  message: string;
4
4
  location: Location;
5
- fileLocation: string | undefined;
6
- static currentFile: string | undefined;
7
- constructor(message: string, location?: Location, fileLocation?: string | undefined);
5
+ constructor(message: string, location?: Location);
8
6
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Diagnostic = void 0;
4
4
  const emptyLocation = {
5
+ file: '',
5
6
  index: 0,
6
7
  line: 0,
7
8
  start: 0,
@@ -10,13 +11,10 @@ const emptyLocation = {
10
11
  class Diagnostic extends Error {
11
12
  message;
12
13
  location;
13
- fileLocation;
14
- static currentFile;
15
- constructor(message, location = emptyLocation, fileLocation = Diagnostic.currentFile) {
14
+ constructor(message, location = emptyLocation) {
16
15
  super();
17
16
  this.message = message;
18
17
  this.location = location;
19
- this.fileLocation = fileLocation;
20
18
  if (process.env.NODE_ENV === 'debug') {
21
19
  console.error(message, location);
22
20
  }
@@ -1,19 +1,18 @@
1
1
  "use strict";
2
2
  const emptyLocation = {
3
+ file: "",
3
4
  index: 0,
4
5
  line: 0,
5
6
  start: 0,
6
7
  end: 0
7
8
  };
8
9
  export class Diagnostic extends Error {
9
- constructor(message, location = emptyLocation, fileLocation = Diagnostic.currentFile) {
10
+ constructor(message, location = emptyLocation) {
10
11
  super();
11
12
  this.message = message;
12
13
  this.location = location;
13
- this.fileLocation = fileLocation;
14
14
  if (false) {
15
15
  console.error(message, location);
16
16
  }
17
17
  }
18
- static currentFile;
19
18
  }
package/dist/lexer.d.ts CHANGED
@@ -13,7 +13,7 @@ export type Keyword = typeof COLLECTION_KEYWORDS[number] | typeof COLLECTION_ACT
13
13
  export declare const KEYWORDS: Keyword[];
14
14
  export declare const FINAL_OPERATORS: readonly ["==", "in", ">=", "<=", ">", "<", "!"];
15
15
  export declare const LOGICAL_OPERATORS: readonly ["&&", "||"];
16
- export declare const tokenize: (rawInput: string) => {
16
+ export declare const tokenize: (rawInput: string, fileLocation: string) => {
17
17
  tokens: Token[];
18
18
  errors: Diagnostic[];
19
19
  };
package/dist/lexer.js CHANGED
@@ -212,7 +212,7 @@ const TOKENS = [
212
212
  valueExtractor: (value) => value.slice(1),
213
213
  },
214
214
  ];
215
- const tokenize = function (rawInput) {
215
+ const tokenize = function (rawInput, fileLocation) {
216
216
  const input = rawInput.replace(/\r\n/g, '\n');
217
217
  let index = 0, line = 1, start = 0, end = 0;
218
218
  const tokens = [];
@@ -254,6 +254,7 @@ const tokenize = function (rawInput) {
254
254
  if (value) {
255
255
  let tokenValue;
256
256
  const location = {
257
+ file: fileLocation,
257
258
  index: index += value.length,
258
259
  line,
259
260
  end: end += value.length,
@@ -354,6 +355,7 @@ const tokenize = function (rawInput) {
354
355
  if (!hasMatch) {
355
356
  index += input.slice(index).search(/[ \t\n\{\}\(\)\[\]]/);
356
357
  errors.push(new diagnostic_js_1.Diagnostic('unexpected token', {
358
+ file: fileLocation,
357
359
  index,
358
360
  line,
359
361
  start,
package/dist/lexer.mjs CHANGED
@@ -220,7 +220,7 @@ const TOKENS = [
220
220
  valueExtractor: (value) => value.slice(1)
221
221
  }
222
222
  ];
223
- export const tokenize = function(rawInput) {
223
+ export const tokenize = function(rawInput, fileLocation) {
224
224
  const input = rawInput.replace(/\r\n/g, "\n");
225
225
  let index = 0, line = 1, start = 0, end = 0;
226
226
  const tokens = [];
@@ -260,6 +260,7 @@ export const tokenize = function(rawInput) {
260
260
  if (value) {
261
261
  let tokenValue;
262
262
  const location = {
263
+ file: fileLocation,
263
264
  index: index += value.length,
264
265
  line,
265
266
  end: end += value.length,
@@ -357,6 +358,7 @@ export const tokenize = function(rawInput) {
357
358
  if (!hasMatch) {
358
359
  index += input.slice(index).search(/[ \t\n\{\}\(\)\[\]]/);
359
360
  errors.push(new Diagnostic("unexpected token", {
361
+ file: fileLocation,
360
362
  index,
361
363
  line,
362
364
  start,
package/dist/parser.js CHANGED
@@ -667,7 +667,7 @@ const parse = (tokens) => {
667
667
  return checkForValidRoles(value, symbols);
668
668
  }
669
669
  };
670
- const parseCollection = (ast) => {
670
+ const parseCollection = () => {
671
671
  consume(token_js_1.TokenType.Keyword, 'collection');
672
672
  const { value: name } = consume(token_js_1.TokenType.Identifier);
673
673
  const node = {
@@ -719,7 +719,9 @@ const parse = (tokens) => {
719
719
  break;
720
720
  }
721
721
  case 'functions': {
722
- node[keyword] = parseFunctionsBlock(ast);
722
+ const { functions, functionSets } = parseFunctionsBlock();
723
+ node.functions = functions;
724
+ node.functionSets = functionSets;
723
725
  break;
724
726
  }
725
727
  case 'individualActions':
@@ -824,9 +826,10 @@ const parse = (tokens) => {
824
826
  consume(token_js_1.TokenType.RightBracket);
825
827
  return node;
826
828
  };
827
- const parseFunctionsBlock = (ast) => {
829
+ const parseFunctionsBlock = () => {
828
830
  consume(token_js_1.TokenType.LeftBracket);
829
831
  const functions = {};
832
+ const functionSets = [];
830
833
  while (!match(token_js_1.TokenType.RightBracket)) {
831
834
  try {
832
835
  if (match(token_js_1.TokenType.MacroName)) {
@@ -834,11 +837,12 @@ const parse = (tokens) => {
834
837
  switch (macroName) {
835
838
  case 'include': {
836
839
  const { value: functionSetName, location } = consume(token_js_1.TokenType.Identifier);
837
- const functionset = ast.functionsets.find((node) => node.name === functionSetName);
838
- if (!functionset) {
839
- throw new diagnostic_js_1.Diagnostic(`functionset "${functionSetName}" not found`, location);
840
- }
841
- Object.assign(functions, functionset.functions);
840
+ const functionSetSymbol = Symbol();
841
+ exports.locationMap.set(functionSetSymbol, location);
842
+ functionSets.push([
843
+ functionSetName,
844
+ functionSetSymbol,
845
+ ]);
842
846
  consume(token_js_1.TokenType.RightParens);
843
847
  break;
844
848
  }
@@ -880,15 +884,20 @@ const parse = (tokens) => {
880
884
  }
881
885
  }
882
886
  consume(token_js_1.TokenType.RightBracket);
883
- return functions;
887
+ return {
888
+ functions,
889
+ functionSets,
890
+ };
884
891
  };
885
- const parseFunctionSet = (ast) => {
892
+ const parseFunctionSet = () => {
886
893
  consume(token_js_1.TokenType.Keyword, 'functionset');
887
894
  const { value: name } = consume(token_js_1.TokenType.Identifier);
895
+ const { functions, functionSets } = parseFunctionsBlock();
888
896
  const node = {
889
897
  kind: 'functionset',
890
898
  name,
891
- functions: parseFunctionsBlock(ast),
899
+ functions,
900
+ functionSets,
892
901
  };
893
902
  return node;
894
903
  };
@@ -1272,7 +1281,7 @@ const parse = (tokens) => {
1272
1281
  try {
1273
1282
  switch (declType) {
1274
1283
  case 'collection': {
1275
- const collection = parseCollection(ast);
1284
+ const collection = parseCollection();
1276
1285
  if (collection.name === 'User') {
1277
1286
  const { properties } = collection;
1278
1287
  if ('roles' in properties && 'items' in properties.roles.property && 'enum' in properties.roles.property.items) {
@@ -1287,7 +1296,7 @@ const parse = (tokens) => {
1287
1296
  break;
1288
1297
  }
1289
1298
  case 'functionset': {
1290
- ast.functionsets.push(parseFunctionSet(ast));
1299
+ ast.functionsets.push(parseFunctionSet());
1291
1300
  break;
1292
1301
  }
1293
1302
  default:
package/dist/parser.mjs CHANGED
@@ -614,7 +614,7 @@ export const parse = (tokens) => {
614
614
  return checkForValidRoles(value, symbols);
615
615
  }
616
616
  };
617
- const parseCollection = (ast2) => {
617
+ const parseCollection = () => {
618
618
  consume(TokenType.Keyword, "collection");
619
619
  const { value: name } = consume(TokenType.Identifier);
620
620
  const node = {
@@ -665,7 +665,9 @@ export const parse = (tokens) => {
665
665
  break;
666
666
  }
667
667
  case "functions": {
668
- node[keyword] = parseFunctionsBlock(ast2);
668
+ const { functions, functionSets } = parseFunctionsBlock();
669
+ node.functions = functions;
670
+ node.functionSets = functionSets;
669
671
  break;
670
672
  }
671
673
  case "individualActions":
@@ -769,9 +771,10 @@ export const parse = (tokens) => {
769
771
  consume(TokenType.RightBracket);
770
772
  return node;
771
773
  };
772
- const parseFunctionsBlock = (ast2) => {
774
+ const parseFunctionsBlock = () => {
773
775
  consume(TokenType.LeftBracket);
774
776
  const functions = {};
777
+ const functionSets = [];
775
778
  while (!match(TokenType.RightBracket)) {
776
779
  try {
777
780
  if (match(TokenType.MacroName)) {
@@ -779,11 +782,12 @@ export const parse = (tokens) => {
779
782
  switch (macroName) {
780
783
  case "include": {
781
784
  const { value: functionSetName, location } = consume(TokenType.Identifier);
782
- const functionset = ast2.functionsets.find((node) => node.name === functionSetName);
783
- if (!functionset) {
784
- throw new Diagnostic(`functionset "${functionSetName}" not found`, location);
785
- }
786
- Object.assign(functions, functionset.functions);
785
+ const functionSetSymbol = Symbol();
786
+ locationMap.set(functionSetSymbol, location);
787
+ functionSets.push([
788
+ functionSetName,
789
+ functionSetSymbol
790
+ ]);
787
791
  consume(TokenType.RightParens);
788
792
  break;
789
793
  }
@@ -823,15 +827,20 @@ export const parse = (tokens) => {
823
827
  }
824
828
  }
825
829
  consume(TokenType.RightBracket);
826
- return functions;
830
+ return {
831
+ functions,
832
+ functionSets
833
+ };
827
834
  };
828
- const parseFunctionSet = (ast2) => {
835
+ const parseFunctionSet = () => {
829
836
  consume(TokenType.Keyword, "functionset");
830
837
  const { value: name } = consume(TokenType.Identifier);
838
+ const { functions, functionSets } = parseFunctionsBlock();
831
839
  const node = {
832
840
  kind: "functionset",
833
841
  name,
834
- functions: parseFunctionsBlock(ast2)
842
+ functions,
843
+ functionSets
835
844
  };
836
845
  return node;
837
846
  };
@@ -1209,7 +1218,7 @@ export const parse = (tokens) => {
1209
1218
  try {
1210
1219
  switch (declType) {
1211
1220
  case "collection": {
1212
- const collection = parseCollection(ast);
1221
+ const collection = parseCollection();
1213
1222
  if (collection.name === "User") {
1214
1223
  const { properties } = collection;
1215
1224
  if ("roles" in properties && "items" in properties.roles.property && "enum" in properties.roles.property.items) {
@@ -1224,7 +1233,7 @@ export const parse = (tokens) => {
1224
1233
  break;
1225
1234
  }
1226
1235
  case "functionset": {
1227
- ast.functionsets.push(parseFunctionSet(ast));
1236
+ ast.functionsets.push(parseFunctionSet());
1228
1237
  break;
1229
1238
  }
1230
1239
  default:
package/dist/token.d.ts CHANGED
@@ -29,6 +29,7 @@ export type TypeMap = {
29
29
  [TokenType.Range]: readonly [number, number];
30
30
  };
31
31
  export type Location = {
32
+ file: string;
32
33
  index: number;
33
34
  line: number;
34
35
  start: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aeriajs/compiler",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",