@aeriajs/compiler 0.0.24 → 0.0.25
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 +9 -2
- package/dist/lexer.js +17 -3
- package/dist/lexer.mjs +17 -3
- package/dist/parser.js +17 -3
- package/dist/parser.mjs +18 -4
- package/dist/semantic.js +22 -1
- package/dist/semantic.mjs +21 -1
- package/package.json +1 -1
package/dist/ast.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Property, AccessCondition, CollectionActions, SearchOptions, DescriptionPreset, Icon, OwnershipMode, Layout } from '@aeriajs/types';
|
|
1
|
+
import type { Property, AccessCondition, CollectionActions, SearchOptions, DescriptionPreset, Icon, OwnershipMode, Layout, LayoutOptions } from '@aeriajs/types';
|
|
2
2
|
import type { ArrayProperties } from './utils.js';
|
|
3
3
|
export declare const LOCATION_SYMBOL: unique symbol;
|
|
4
4
|
export declare const PropertyType: {
|
|
@@ -19,6 +19,13 @@ export type ExportSymbol = {
|
|
|
19
19
|
export type NodeBase<TType> = {
|
|
20
20
|
kind: TType;
|
|
21
21
|
};
|
|
22
|
+
export type LayoutNode = NodeBase<'layout'> & Layout & {
|
|
23
|
+
[LOCATION_SYMBOL]: {
|
|
24
|
+
options: {
|
|
25
|
+
[P in keyof LayoutOptions]?: readonly string[] extends LayoutOptions[P] ? symbol | symbol[] : symbol;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
};
|
|
22
29
|
export type PropertyNode = NodeBase<'property'> & {
|
|
23
30
|
modifier?: keyof typeof PropertyModifiers;
|
|
24
31
|
property: Property & {
|
|
@@ -53,7 +60,7 @@ export type CollectionNode = NodeBase<'collection'> & {
|
|
|
53
60
|
table?: string[];
|
|
54
61
|
filters?: string[];
|
|
55
62
|
search?: SearchOptions<any>;
|
|
56
|
-
layout?:
|
|
63
|
+
layout?: LayoutNode;
|
|
57
64
|
[LOCATION_SYMBOL]: {
|
|
58
65
|
arrays: {
|
|
59
66
|
[P in ArrayProperties<CollectionNode>]?: symbol[];
|
package/dist/lexer.js
CHANGED
|
@@ -149,7 +149,20 @@ const TOKENS = [
|
|
|
149
149
|
{
|
|
150
150
|
type: token_js_1.TokenType.Keyword,
|
|
151
151
|
matcher: Array.from(keywordsSet),
|
|
152
|
-
condition: (state) =>
|
|
152
|
+
condition: (state, lastToken) => {
|
|
153
|
+
if (state.inPropertiesStack.at(-1)) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
if (lastToken && lastToken.type === token_js_1.TokenType.Keyword) {
|
|
157
|
+
switch (lastToken.value) {
|
|
158
|
+
case 'badge':
|
|
159
|
+
case 'title': {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return true;
|
|
165
|
+
},
|
|
153
166
|
},
|
|
154
167
|
{
|
|
155
168
|
type: token_js_1.TokenType.MacroName,
|
|
@@ -184,8 +197,9 @@ const tokenize = function (rawInput) {
|
|
|
184
197
|
for (const { type, matcher, valueExtractor, construct, condition } of TOKENS) {
|
|
185
198
|
let value;
|
|
186
199
|
let token;
|
|
200
|
+
const lastToken = tokens.at(-1);
|
|
187
201
|
if (condition) {
|
|
188
|
-
if (!condition(state)) {
|
|
202
|
+
if (!condition(state, lastToken)) {
|
|
189
203
|
continue;
|
|
190
204
|
}
|
|
191
205
|
}
|
|
@@ -246,9 +260,9 @@ const tokenize = function (rawInput) {
|
|
|
246
260
|
};
|
|
247
261
|
switch (type) {
|
|
248
262
|
case token_js_1.TokenType.LeftBracket: {
|
|
249
|
-
const lastToken = tokens.at(-1);
|
|
250
263
|
if (lastToken && lastToken.type === token_js_1.TokenType.Keyword) {
|
|
251
264
|
switch (lastToken.value) {
|
|
265
|
+
case 'information':
|
|
252
266
|
case 'form':
|
|
253
267
|
case 'table':
|
|
254
268
|
case 'indexes':
|
package/dist/lexer.mjs
CHANGED
|
@@ -156,7 +156,20 @@ const TOKENS = [
|
|
|
156
156
|
{
|
|
157
157
|
type: TokenType.Keyword,
|
|
158
158
|
matcher: Array.from(keywordsSet),
|
|
159
|
-
condition: (state) =>
|
|
159
|
+
condition: (state, lastToken) => {
|
|
160
|
+
if (state.inPropertiesStack.at(-1)) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (lastToken && lastToken.type === TokenType.Keyword) {
|
|
164
|
+
switch (lastToken.value) {
|
|
165
|
+
case "badge":
|
|
166
|
+
case "title": {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
160
173
|
},
|
|
161
174
|
{
|
|
162
175
|
type: TokenType.MacroName,
|
|
@@ -191,8 +204,9 @@ export const tokenize = function(rawInput) {
|
|
|
191
204
|
for (const { type, matcher, valueExtractor, construct, condition } of TOKENS) {
|
|
192
205
|
let value;
|
|
193
206
|
let token;
|
|
207
|
+
const lastToken = tokens.at(-1);
|
|
194
208
|
if (condition) {
|
|
195
|
-
if (!condition(state)) {
|
|
209
|
+
if (!condition(state, lastToken)) {
|
|
196
210
|
continue;
|
|
197
211
|
}
|
|
198
212
|
}
|
|
@@ -248,9 +262,9 @@ export const tokenize = function(rawInput) {
|
|
|
248
262
|
};
|
|
249
263
|
switch (type) {
|
|
250
264
|
case TokenType.LeftBracket: {
|
|
251
|
-
const lastToken = tokens.at(-1);
|
|
252
265
|
if (lastToken && lastToken.type === TokenType.Keyword) {
|
|
253
266
|
switch (lastToken.value) {
|
|
267
|
+
case "information":
|
|
254
268
|
case "form":
|
|
255
269
|
case "table":
|
|
256
270
|
case "indexes":
|
package/dist/parser.js
CHANGED
|
@@ -985,6 +985,7 @@ const parse = (tokens) => {
|
|
|
985
985
|
const parseLayoutBlock = () => {
|
|
986
986
|
let name;
|
|
987
987
|
const options = {};
|
|
988
|
+
const optionsSymbols = {};
|
|
988
989
|
const { location } = consume(token_js_1.TokenType.LeftBracket);
|
|
989
990
|
while (!match(token_js_1.TokenType.RightBracket)) {
|
|
990
991
|
const { value: keyword } = consume(token_js_1.TokenType.Keyword, lexer.COLLECTION_LAYOUT_KEYWORDS);
|
|
@@ -1003,16 +1004,25 @@ const parse = (tokens) => {
|
|
|
1003
1004
|
case 'title':
|
|
1004
1005
|
case 'picture':
|
|
1005
1006
|
case 'badge': {
|
|
1006
|
-
const { value } = consume(token_js_1.TokenType.
|
|
1007
|
+
const { value, location } = consume(token_js_1.TokenType.Identifier);
|
|
1008
|
+
const symbol = Symbol();
|
|
1007
1009
|
options[optionsKeyword] = value;
|
|
1010
|
+
optionsSymbols[optionsKeyword] = symbol;
|
|
1011
|
+
exports.locationMap.set(symbol, location);
|
|
1008
1012
|
break;
|
|
1009
1013
|
}
|
|
1010
1014
|
case 'information': {
|
|
1011
1015
|
if (match(token_js_1.TokenType.LeftBracket)) {
|
|
1012
|
-
|
|
1016
|
+
const { value, symbols } = parseArrayBlock();
|
|
1017
|
+
options[optionsKeyword] = value;
|
|
1018
|
+
optionsSymbols[optionsKeyword] = symbols;
|
|
1013
1019
|
}
|
|
1014
1020
|
else {
|
|
1015
|
-
|
|
1021
|
+
const { value, location } = consume(token_js_1.TokenType.Identifier);
|
|
1022
|
+
const symbol = Symbol();
|
|
1023
|
+
options[optionsKeyword] = value;
|
|
1024
|
+
optionsSymbols[optionsKeyword] = symbol;
|
|
1025
|
+
exports.locationMap.set(symbol, location);
|
|
1016
1026
|
}
|
|
1017
1027
|
break;
|
|
1018
1028
|
}
|
|
@@ -1033,8 +1043,12 @@ const parse = (tokens) => {
|
|
|
1033
1043
|
}
|
|
1034
1044
|
consume(token_js_1.TokenType.RightBracket);
|
|
1035
1045
|
return {
|
|
1046
|
+
kind: 'layout',
|
|
1036
1047
|
name,
|
|
1037
1048
|
options,
|
|
1049
|
+
[AST.LOCATION_SYMBOL]: {
|
|
1050
|
+
options: optionsSymbols,
|
|
1051
|
+
},
|
|
1038
1052
|
};
|
|
1039
1053
|
};
|
|
1040
1054
|
while (index < tokens.length) {
|
package/dist/parser.mjs
CHANGED
|
@@ -926,6 +926,7 @@ export const parse = (tokens) => {
|
|
|
926
926
|
const parseLayoutBlock = () => {
|
|
927
927
|
let name;
|
|
928
928
|
const options = {};
|
|
929
|
+
const optionsSymbols = {};
|
|
929
930
|
const { location } = consume(TokenType.LeftBracket);
|
|
930
931
|
while (!match(TokenType.RightBracket)) {
|
|
931
932
|
const { value: keyword } = consume(TokenType.Keyword, lexer.COLLECTION_LAYOUT_KEYWORDS);
|
|
@@ -944,15 +945,24 @@ export const parse = (tokens) => {
|
|
|
944
945
|
case "title":
|
|
945
946
|
case "picture":
|
|
946
947
|
case "badge": {
|
|
947
|
-
const { value } = consume(TokenType.
|
|
948
|
+
const { value, location: location2 } = consume(TokenType.Identifier);
|
|
949
|
+
const symbol = Symbol();
|
|
948
950
|
options[optionsKeyword] = value;
|
|
951
|
+
optionsSymbols[optionsKeyword] = symbol;
|
|
952
|
+
locationMap.set(symbol, location2);
|
|
949
953
|
break;
|
|
950
954
|
}
|
|
951
955
|
case "information": {
|
|
952
956
|
if (match(TokenType.LeftBracket)) {
|
|
953
|
-
|
|
957
|
+
const { value, symbols } = parseArrayBlock();
|
|
958
|
+
options[optionsKeyword] = value;
|
|
959
|
+
optionsSymbols[optionsKeyword] = symbols;
|
|
954
960
|
} else {
|
|
955
|
-
|
|
961
|
+
const { value, location: location2 } = consume(TokenType.Identifier);
|
|
962
|
+
const symbol = Symbol();
|
|
963
|
+
options[optionsKeyword] = value;
|
|
964
|
+
optionsSymbols[optionsKeyword] = symbol;
|
|
965
|
+
locationMap.set(symbol, location2);
|
|
956
966
|
}
|
|
957
967
|
break;
|
|
958
968
|
}
|
|
@@ -973,8 +983,12 @@ export const parse = (tokens) => {
|
|
|
973
983
|
}
|
|
974
984
|
consume(TokenType.RightBracket);
|
|
975
985
|
return {
|
|
986
|
+
kind: "layout",
|
|
976
987
|
name,
|
|
977
|
-
options
|
|
988
|
+
options,
|
|
989
|
+
[AST.LOCATION_SYMBOL]: {
|
|
990
|
+
options: optionsSymbols
|
|
991
|
+
}
|
|
978
992
|
};
|
|
979
993
|
};
|
|
980
994
|
while (index < tokens.length) {
|
package/dist/semantic.js
CHANGED
|
@@ -92,7 +92,7 @@ const analyze = async (ast, options, errors = []) => {
|
|
|
92
92
|
const symbol = node.property[AST.LOCATION_SYMBOL].arrays[attributeName][index];
|
|
93
93
|
if (!(propName in node.property.properties)) {
|
|
94
94
|
const location = parser_js_1.locationMap.get(symbol);
|
|
95
|
-
errors.push(new diagnostic_js_1.Diagnostic(`object
|
|
95
|
+
errors.push(new diagnostic_js_1.Diagnostic(`object hasn't such property "${propName}"`, location));
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
};
|
|
@@ -139,6 +139,27 @@ const analyze = async (ast, options, errors = []) => {
|
|
|
139
139
|
const subNode = node.properties[propName];
|
|
140
140
|
await recurseProperty(subNode);
|
|
141
141
|
}
|
|
142
|
+
if (node.layout) {
|
|
143
|
+
if (node.layout.options) {
|
|
144
|
+
for (const [name, value] of Object.entries(node.layout[AST.LOCATION_SYMBOL].options)) {
|
|
145
|
+
const option = node.layout.options[name];
|
|
146
|
+
if (Array.isArray(option)) {
|
|
147
|
+
for (const [i, propName] of option.entries()) {
|
|
148
|
+
if (!(propName in node.properties)) {
|
|
149
|
+
const location = parser_js_1.locationMap.get(value[i]);
|
|
150
|
+
errors.push(new diagnostic_js_1.Diagnostic(`invalid property "${propName}"`, location));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
if (!(option in node.properties)) {
|
|
156
|
+
const location = parser_js_1.locationMap.get(value);
|
|
157
|
+
errors.push(new diagnostic_js_1.Diagnostic(`invalid property "${option}"`, location));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
142
163
|
}
|
|
143
164
|
for (const node of ast.contracts) {
|
|
144
165
|
if (node.payload) {
|
package/dist/semantic.mjs
CHANGED
|
@@ -57,7 +57,7 @@ export const analyze = async (ast, options, errors = []) => {
|
|
|
57
57
|
const symbol = node.property[AST.LOCATION_SYMBOL].arrays[attributeName][index];
|
|
58
58
|
if (!(propName in node.property.properties)) {
|
|
59
59
|
const location = locationMap.get(symbol);
|
|
60
|
-
errors.push(new Diagnostic(`object
|
|
60
|
+
errors.push(new Diagnostic(`object hasn't such property "${propName}"`, location));
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
};
|
|
@@ -102,6 +102,26 @@ export const analyze = async (ast, options, errors = []) => {
|
|
|
102
102
|
const subNode = node.properties[propName];
|
|
103
103
|
await recurseProperty(subNode);
|
|
104
104
|
}
|
|
105
|
+
if (node.layout) {
|
|
106
|
+
if (node.layout.options) {
|
|
107
|
+
for (const [name, value] of Object.entries(node.layout[AST.LOCATION_SYMBOL].options)) {
|
|
108
|
+
const option = node.layout.options[name];
|
|
109
|
+
if (Array.isArray(option)) {
|
|
110
|
+
for (const [i, propName] of option.entries()) {
|
|
111
|
+
if (!(propName in node.properties)) {
|
|
112
|
+
const location = locationMap.get(value[i]);
|
|
113
|
+
errors.push(new Diagnostic(`invalid property "${propName}"`, location));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
if (!(option in node.properties)) {
|
|
118
|
+
const location = locationMap.get(value);
|
|
119
|
+
errors.push(new Diagnostic(`invalid property "${option}"`, location));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
105
125
|
}
|
|
106
126
|
for (const node of ast.contracts) {
|
|
107
127
|
if (node.payload) {
|