@malloydata/malloy 0.0.415 → 0.0.416
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/lang/ast/expressions/expr-granular-time.js +16 -1
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +142 -60
- package/dist/lang/lib/Malloy/MalloyParser.js +2983 -2220
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +22 -0
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +14 -0
- package/dist/lang/lib/Malloy/keyword-display-names.d.ts +1 -0
- package/dist/lang/lib/Malloy/keyword-display-names.js +121 -0
- package/dist/lang/malloy-to-ast.js +27 -5
- package/dist/lang/malloy-to-stable-query.js +14 -10
- package/dist/lang/parse-log.d.ts +1 -0
- package/dist/lang/syntax-errors/malloy-error-strategy.d.ts +9 -6
- package/dist/lang/syntax-errors/malloy-error-strategy.js +43 -6
- package/dist/lang/syntax-errors/token-names.d.ts +3 -0
- package/dist/lang/syntax-errors/token-names.js +66 -0
- package/dist/model/utils.js +5 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/femto-config.motly +11 -1
- package/package.json +11 -11
|
@@ -216,6 +216,8 @@ import { GroupedByStatementContext } from "./MalloyParser";
|
|
|
216
216
|
import { OrderByStatementContext } from "./MalloyParser";
|
|
217
217
|
import { OrderingContext } from "./MalloyParser";
|
|
218
218
|
import { OrderBySpecContext } from "./MalloyParser";
|
|
219
|
+
import { PossibleBadPathContext } from "./MalloyParser";
|
|
220
|
+
import { BadWordContext } from "./MalloyParser";
|
|
219
221
|
import { LimitStatementContext } from "./MalloyParser";
|
|
220
222
|
import { BySpecContext } from "./MalloyParser";
|
|
221
223
|
import { TopStatementContext } from "./MalloyParser";
|
|
@@ -2632,6 +2634,26 @@ export interface MalloyParserListener extends ParseTreeListener {
|
|
|
2632
2634
|
* @param ctx the parse tree
|
|
2633
2635
|
*/
|
|
2634
2636
|
exitOrderBySpec?: (ctx: OrderBySpecContext) => void;
|
|
2637
|
+
/**
|
|
2638
|
+
* Enter a parse tree produced by `MalloyParser.possibleBadPath`.
|
|
2639
|
+
* @param ctx the parse tree
|
|
2640
|
+
*/
|
|
2641
|
+
enterPossibleBadPath?: (ctx: PossibleBadPathContext) => void;
|
|
2642
|
+
/**
|
|
2643
|
+
* Exit a parse tree produced by `MalloyParser.possibleBadPath`.
|
|
2644
|
+
* @param ctx the parse tree
|
|
2645
|
+
*/
|
|
2646
|
+
exitPossibleBadPath?: (ctx: PossibleBadPathContext) => void;
|
|
2647
|
+
/**
|
|
2648
|
+
* Enter a parse tree produced by `MalloyParser.badWord`.
|
|
2649
|
+
* @param ctx the parse tree
|
|
2650
|
+
*/
|
|
2651
|
+
enterBadWord?: (ctx: BadWordContext) => void;
|
|
2652
|
+
/**
|
|
2653
|
+
* Exit a parse tree produced by `MalloyParser.badWord`.
|
|
2654
|
+
* @param ctx the parse tree
|
|
2655
|
+
*/
|
|
2656
|
+
exitBadWord?: (ctx: BadWordContext) => void;
|
|
2635
2657
|
/**
|
|
2636
2658
|
* Enter a parse tree produced by `MalloyParser.limitStatement`.
|
|
2637
2659
|
* @param ctx the parse tree
|
|
@@ -216,6 +216,8 @@ import { GroupedByStatementContext } from "./MalloyParser";
|
|
|
216
216
|
import { OrderByStatementContext } from "./MalloyParser";
|
|
217
217
|
import { OrderingContext } from "./MalloyParser";
|
|
218
218
|
import { OrderBySpecContext } from "./MalloyParser";
|
|
219
|
+
import { PossibleBadPathContext } from "./MalloyParser";
|
|
220
|
+
import { BadWordContext } from "./MalloyParser";
|
|
219
221
|
import { LimitStatementContext } from "./MalloyParser";
|
|
220
222
|
import { BySpecContext } from "./MalloyParser";
|
|
221
223
|
import { TopStatementContext } from "./MalloyParser";
|
|
@@ -1676,6 +1678,18 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
|
|
|
1676
1678
|
* @return the visitor result
|
|
1677
1679
|
*/
|
|
1678
1680
|
visitOrderBySpec?: (ctx: OrderBySpecContext) => Result;
|
|
1681
|
+
/**
|
|
1682
|
+
* Visit a parse tree produced by `MalloyParser.possibleBadPath`.
|
|
1683
|
+
* @param ctx the parse tree
|
|
1684
|
+
* @return the visitor result
|
|
1685
|
+
*/
|
|
1686
|
+
visitPossibleBadPath?: (ctx: PossibleBadPathContext) => Result;
|
|
1687
|
+
/**
|
|
1688
|
+
* Visit a parse tree produced by `MalloyParser.badWord`.
|
|
1689
|
+
* @param ctx the parse tree
|
|
1690
|
+
* @return the visitor result
|
|
1691
|
+
*/
|
|
1692
|
+
visitBadWord?: (ctx: BadWordContext) => Result;
|
|
1679
1693
|
/**
|
|
1680
1694
|
* Visit a parse tree produced by `MalloyParser.limitStatement`.
|
|
1681
1695
|
* @param ctx the parse tree
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const KEYWORD_DISPLAY_NAMES: Record<string, string>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Contributors to the Malloy project
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.KEYWORD_DISPLAY_NAMES = void 0;
|
|
8
|
+
// GENERATED by src/lang/grammar/build_token_names.js from the
|
|
9
|
+
// KEYWORDS-BEGIN..KEYWORDS-END section of MalloyLexer.g4. Do not edit by hand.
|
|
10
|
+
// Maps a keyword token's symbolic name to the spelling a user types (including
|
|
11
|
+
// the trailing colon for statement keywords), for parser error messages.
|
|
12
|
+
// Run `npm run codegen` to regenerate.
|
|
13
|
+
exports.KEYWORD_DISPLAY_NAMES = {
|
|
14
|
+
ACCEPT: "accept:",
|
|
15
|
+
AGGREGATE: "aggregate:",
|
|
16
|
+
ALL: "all",
|
|
17
|
+
AND: "and",
|
|
18
|
+
AS: "as",
|
|
19
|
+
ASC: "asc",
|
|
20
|
+
AVG: "avg",
|
|
21
|
+
BOOLEAN: "boolean",
|
|
22
|
+
BY: "by",
|
|
23
|
+
CALCULATE: "calculate:",
|
|
24
|
+
CALCULATION: "calculation:",
|
|
25
|
+
CASE: "case",
|
|
26
|
+
CAST: "cast",
|
|
27
|
+
COMPOSE: "compose",
|
|
28
|
+
CONNECTION: "connection:",
|
|
29
|
+
COUNT: "count",
|
|
30
|
+
DATE: "date",
|
|
31
|
+
DAY: "day",
|
|
32
|
+
DECLARE: "declare:",
|
|
33
|
+
DESC: "desc",
|
|
34
|
+
DIMENSION: "dimension:",
|
|
35
|
+
DISTINCT: "distinct",
|
|
36
|
+
DRILL: "drill:",
|
|
37
|
+
ELSE: "else",
|
|
38
|
+
END: "end",
|
|
39
|
+
EXCEPT: "except:",
|
|
40
|
+
EXCLUDE: "exclude",
|
|
41
|
+
EXPORT: "export",
|
|
42
|
+
EXTEND: "extend",
|
|
43
|
+
EXTENDQ: "extend:",
|
|
44
|
+
FALSE: "false",
|
|
45
|
+
FILTER: "filter",
|
|
46
|
+
FOR: "for",
|
|
47
|
+
FROM: "from",
|
|
48
|
+
FULL: "full",
|
|
49
|
+
GIVEN: "given:",
|
|
50
|
+
GROUPED_BY: "grouped_by:",
|
|
51
|
+
GROUP_BY: "group_by:",
|
|
52
|
+
HAS: "has",
|
|
53
|
+
HAVING: "having:",
|
|
54
|
+
HOUR: "hour",
|
|
55
|
+
IMPORT: "import",
|
|
56
|
+
IN: "in",
|
|
57
|
+
INCLUDE: "include",
|
|
58
|
+
INDEX: "index:",
|
|
59
|
+
INNER: "inner",
|
|
60
|
+
INTERNAL: "internal:",
|
|
61
|
+
INTERNAL_KW: "internal",
|
|
62
|
+
IS: "is",
|
|
63
|
+
JOIN_CROSS: "join_cross:",
|
|
64
|
+
JOIN_MANY: "join_many:",
|
|
65
|
+
JOIN_ONE: "join_one:",
|
|
66
|
+
JSON: "json",
|
|
67
|
+
LEFT: "left",
|
|
68
|
+
LIKE: "like",
|
|
69
|
+
LIMIT: "limit:",
|
|
70
|
+
MAX: "max",
|
|
71
|
+
MEASURE: "measure:",
|
|
72
|
+
MIN: "min",
|
|
73
|
+
MINUTE: "minute",
|
|
74
|
+
MONTH: "month",
|
|
75
|
+
NEST: "nest:",
|
|
76
|
+
NOT: "not",
|
|
77
|
+
NOW: "now",
|
|
78
|
+
NULL: "null",
|
|
79
|
+
NUMBER: "number",
|
|
80
|
+
ON: "on",
|
|
81
|
+
OR: "or",
|
|
82
|
+
ORDER_BY: "order_by:",
|
|
83
|
+
PARTITION_BY: "partition_by:",
|
|
84
|
+
PICK: "pick",
|
|
85
|
+
PRIMARY_KEY: "primary_key:",
|
|
86
|
+
PRIVATE: "private:",
|
|
87
|
+
PRIVATE_KW: "private",
|
|
88
|
+
PUBLIC: "public:",
|
|
89
|
+
PUBLIC_KW: "public",
|
|
90
|
+
QUARTER: "quarter",
|
|
91
|
+
QUERY: "query:",
|
|
92
|
+
RENAME: "rename:",
|
|
93
|
+
RIGHT: "right",
|
|
94
|
+
RUN: "run:",
|
|
95
|
+
SAMPLE: "sample:",
|
|
96
|
+
SECOND: "second",
|
|
97
|
+
SELECT: "select:",
|
|
98
|
+
SOURCE: "source:",
|
|
99
|
+
SOURCE_KW: "source",
|
|
100
|
+
SQL: "sql",
|
|
101
|
+
STRING: "string",
|
|
102
|
+
SUM: "sum",
|
|
103
|
+
TABLE: "table",
|
|
104
|
+
THEN: "then",
|
|
105
|
+
THIS: "this",
|
|
106
|
+
TIMESTAMP: "timestamp",
|
|
107
|
+
TIMESTAMPTZ: "timestamptz",
|
|
108
|
+
TIMEZONE: "timezone:",
|
|
109
|
+
TO: "to",
|
|
110
|
+
TOP: "top:",
|
|
111
|
+
TRUE: "true",
|
|
112
|
+
TYPE: "type:",
|
|
113
|
+
VIEW: "view:",
|
|
114
|
+
VIRTUAL: "virtual",
|
|
115
|
+
WEEK: "week",
|
|
116
|
+
WHEN: "when",
|
|
117
|
+
WHERE: "where:",
|
|
118
|
+
WITH: "with",
|
|
119
|
+
YEAR: "year",
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=keyword-display-names.js.map
|
|
@@ -979,11 +979,33 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
979
979
|
if (ncx) {
|
|
980
980
|
return new ast.OrderBy(this.getNumber(ncx), dir);
|
|
981
981
|
}
|
|
982
|
-
const
|
|
983
|
-
if (
|
|
984
|
-
|
|
985
|
-
}
|
|
986
|
-
|
|
982
|
+
const pathCx = pcx.possibleBadPath();
|
|
983
|
+
if (!pathCx) {
|
|
984
|
+
throw this.internalError(pcx, "can't parse order_by specification");
|
|
985
|
+
}
|
|
986
|
+
const words = pathCx.badWord();
|
|
987
|
+
const firstField = words[0].fieldName();
|
|
988
|
+
if (words.length === 1 && firstField) {
|
|
989
|
+
// A lone ordinary identifier -- the normal, valid order_by target.
|
|
990
|
+
return new ast.OrderBy(this.getFieldName(firstField), dir);
|
|
991
|
+
}
|
|
992
|
+
// Otherwise illegal: a dotted path, and/or a reserved-word segment that
|
|
993
|
+
// would have to be quoted. Logging an error here prevents translation, so
|
|
994
|
+
// the throwaway OrderBy below is never evaluated -- it only satisfies the
|
|
995
|
+
// visitor's contract.
|
|
996
|
+
const last = words[words.length - 1];
|
|
997
|
+
const lastFieldCx = last.fieldName();
|
|
998
|
+
const lastName = lastFieldCx ? lastFieldCx.text : '`' + last.text + '`';
|
|
999
|
+
const message = words.length > 1
|
|
1000
|
+
? `order_by takes the name of a field in the query output, not a path ('${pathCx.text}'). ` +
|
|
1001
|
+
`To order by '${last.text}', make it an output field and order by its name` +
|
|
1002
|
+
(lastFieldCx === undefined
|
|
1003
|
+
? `, quoting it because '${last.text}' is a reserved word: ${lastName}`
|
|
1004
|
+
: `: ${lastName}`) +
|
|
1005
|
+
'.'
|
|
1006
|
+
: `'${last.text}' is a reserved word, so to order by it you must quote it: ${lastName}`;
|
|
1007
|
+
this.contextError(pathCx, 'order-by-bad-reference', message);
|
|
1008
|
+
return new ast.OrderBy(new ast.FieldName('internal_error'), dir);
|
|
987
1009
|
}
|
|
988
1010
|
visitOrdering(pcx) {
|
|
989
1011
|
const orderList = pcx.orderBySpec().map(o => this.visitOrderBySpec(o));
|
|
@@ -368,24 +368,28 @@ class MalloyToQuery extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor
|
|
|
368
368
|
});
|
|
369
369
|
}
|
|
370
370
|
getOrderByStatement(obcx) {
|
|
371
|
+
var _a, _b;
|
|
371
372
|
const specs = obcx.ordering().orderBySpec();
|
|
372
373
|
const orders = [];
|
|
373
374
|
for (const spec of specs) {
|
|
374
375
|
if (spec.INTEGER_LITERAL()) {
|
|
375
376
|
this.notAllowed(spec, 'Indexed order by statements');
|
|
377
|
+
continue;
|
|
376
378
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
direction,
|
|
383
|
-
field_reference: { name: fieldName },
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
else {
|
|
379
|
+
// A valid order_by target is a single ordinary name; a dotted path or a
|
|
380
|
+
// bare reserved word is not representable as a stable query.
|
|
381
|
+
const words = (_b = (_a = spec.possibleBadPath()) === null || _a === void 0 ? void 0 : _a.badWord()) !== null && _b !== void 0 ? _b : [];
|
|
382
|
+
const firstField = words.length === 1 ? words[0].fieldName() : undefined;
|
|
383
|
+
if (!firstField) {
|
|
387
384
|
return null;
|
|
388
385
|
}
|
|
386
|
+
const fieldName = (0, parse_utils_1.getId)(firstField);
|
|
387
|
+
const direction = spec.ASC() ? 'asc' : spec.DESC() ? 'desc' : undefined;
|
|
388
|
+
orders.push({
|
|
389
|
+
kind: 'order_by',
|
|
390
|
+
direction,
|
|
391
|
+
field_reference: { name: fieldName },
|
|
392
|
+
});
|
|
389
393
|
}
|
|
390
394
|
return orders;
|
|
391
395
|
}
|
package/dist/lang/parse-log.d.ts
CHANGED
|
@@ -222,6 +222,7 @@ type MessageParameterTypes = {
|
|
|
222
222
|
'aggregate-in-where': string;
|
|
223
223
|
'order-by-not-found-in-output': string;
|
|
224
224
|
'order-by-analytic': string;
|
|
225
|
+
'order-by-bad-reference': string;
|
|
225
226
|
'illegal-index-operation': string;
|
|
226
227
|
'illegal-project-operation': string;
|
|
227
228
|
'illegal-grouping-operation': string;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import type { InputMismatchException, Parser } from 'antlr4ts';
|
|
1
2
|
import { DefaultErrorStrategy } from 'antlr4ts';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
+
* Overrides the three DefaultErrorStrategy methods that paste the parser's
|
|
5
|
+
* expected-token set into the message: tokens are named the way the user types
|
|
6
|
+
* them (via describeExpected) and the set is dropped once too large to be a hint.
|
|
4
7
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* For more details, read the documentation in DefaultErrorStrategy.d.ts
|
|
8
|
-
* or reference the superclass at:
|
|
9
|
-
* https://github.com/tunnelvisionlabs/antlr4ts/blob/master/src/DefaultErrorStrategy.ts
|
|
8
|
+
* Fallback only — MalloyParserErrorListener's custom-error cases run first and
|
|
9
|
+
* override these when they match.
|
|
10
10
|
*/
|
|
11
11
|
export declare class MalloyErrorStrategy extends DefaultErrorStrategy {
|
|
12
|
+
protected reportInputMismatch(recognizer: Parser, e: InputMismatchException): void;
|
|
13
|
+
protected reportUnwantedToken(recognizer: Parser): void;
|
|
14
|
+
protected reportMissingToken(recognizer: Parser): void;
|
|
12
15
|
}
|
|
@@ -6,16 +6,53 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.MalloyErrorStrategy = void 0;
|
|
8
8
|
const antlr4ts_1 = require("antlr4ts");
|
|
9
|
+
const token_names_1 = require("./token-names");
|
|
10
|
+
function unexpected(offending, clause) {
|
|
11
|
+
return clause
|
|
12
|
+
? `unexpected ${offending}, expected ${clause}`
|
|
13
|
+
: `unexpected ${offending}`;
|
|
14
|
+
}
|
|
9
15
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
16
|
+
* Overrides the three DefaultErrorStrategy methods that paste the parser's
|
|
17
|
+
* expected-token set into the message: tokens are named the way the user types
|
|
18
|
+
* them (via describeExpected) and the set is dropped once too large to be a hint.
|
|
13
19
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* https://github.com/tunnelvisionlabs/antlr4ts/blob/master/src/DefaultErrorStrategy.ts
|
|
20
|
+
* Fallback only — MalloyParserErrorListener's custom-error cases run first and
|
|
21
|
+
* override these when they match.
|
|
17
22
|
*/
|
|
18
23
|
class MalloyErrorStrategy extends antlr4ts_1.DefaultErrorStrategy {
|
|
24
|
+
reportInputMismatch(recognizer, e) {
|
|
25
|
+
var _a, _b;
|
|
26
|
+
const offending = this.getTokenErrorDisplay(e.getOffendingToken(recognizer));
|
|
27
|
+
const expected = (_b = (_a = e.expectedTokens) === null || _a === void 0 ? void 0 : _a.toArray()) !== null && _b !== void 0 ? _b : [];
|
|
28
|
+
const clause = (0, token_names_1.describeExpected)(expected, recognizer.vocabulary);
|
|
29
|
+
this.notifyErrorListeners(recognizer, unexpected(offending, clause), e);
|
|
30
|
+
}
|
|
31
|
+
reportUnwantedToken(recognizer) {
|
|
32
|
+
if (this.inErrorRecoveryMode(recognizer)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.beginErrorCondition(recognizer);
|
|
36
|
+
const t = recognizer.currentToken;
|
|
37
|
+
const offending = this.getTokenErrorDisplay(t);
|
|
38
|
+
const expected = this.getExpectedTokens(recognizer).toArray();
|
|
39
|
+
const clause = (0, token_names_1.describeExpected)(expected, recognizer.vocabulary);
|
|
40
|
+
recognizer.notifyErrorListeners(unexpected(offending, clause), t, undefined);
|
|
41
|
+
}
|
|
42
|
+
reportMissingToken(recognizer) {
|
|
43
|
+
if (this.inErrorRecoveryMode(recognizer)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
this.beginErrorCondition(recognizer);
|
|
47
|
+
const t = recognizer.currentToken;
|
|
48
|
+
const offending = this.getTokenErrorDisplay(t);
|
|
49
|
+
const expected = this.getExpectedTokens(recognizer).toArray();
|
|
50
|
+
const clause = (0, token_names_1.describeExpected)(expected, recognizer.vocabulary);
|
|
51
|
+
const msg = clause
|
|
52
|
+
? `missing ${clause} before ${offending}`
|
|
53
|
+
: `something is missing before ${offending}`;
|
|
54
|
+
recognizer.notifyErrorListeners(msg, t, undefined);
|
|
55
|
+
}
|
|
19
56
|
}
|
|
20
57
|
exports.MalloyErrorStrategy = MalloyErrorStrategy;
|
|
21
58
|
//# sourceMappingURL=malloy-error-strategy.js.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Contributors to the Malloy project
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.describeToken = describeToken;
|
|
8
|
+
exports.describeExpected = describeExpected;
|
|
9
|
+
const antlr4ts_1 = require("antlr4ts");
|
|
10
|
+
const keyword_display_names_1 = require("../lib/Malloy/keyword-display-names");
|
|
11
|
+
// Pattern tokens have neither a literal nor a keyword spelling to show, so they
|
|
12
|
+
// get hand-written prose instead of their SHOUTING symbolic name.
|
|
13
|
+
const CLASS_TOKEN_DISPLAY_NAMES = {
|
|
14
|
+
IDENTIFIER: 'a name',
|
|
15
|
+
BQ_STRING: 'a `quoted` name',
|
|
16
|
+
SQ_STRING: 'a quoted string',
|
|
17
|
+
DQ_STRING: 'a quoted string',
|
|
18
|
+
NUMERIC_LITERAL: 'a number',
|
|
19
|
+
INTEGER_LITERAL: 'a number',
|
|
20
|
+
PERCENT_LITERAL: 'a percentage',
|
|
21
|
+
GIVEN_REF: 'a $given reference',
|
|
22
|
+
};
|
|
23
|
+
// Past this many alternatives the expected-set is the parser's follow-set, not
|
|
24
|
+
// a hint, so describeExpected drops it.
|
|
25
|
+
const MAX_EXPECTED_NAMED = 3;
|
|
26
|
+
function describeToken(type, vocabulary) {
|
|
27
|
+
if (type === antlr4ts_1.Token.EOF)
|
|
28
|
+
return 'end of input';
|
|
29
|
+
const symbolic = vocabulary.getSymbolicName(type);
|
|
30
|
+
if (symbolic !== undefined) {
|
|
31
|
+
const prose = CLASS_TOKEN_DISPLAY_NAMES[symbolic];
|
|
32
|
+
if (prose !== undefined)
|
|
33
|
+
return prose;
|
|
34
|
+
const keyword = keyword_display_names_1.KEYWORD_DISPLAY_NAMES[symbolic];
|
|
35
|
+
if (keyword !== undefined)
|
|
36
|
+
return `'${keyword}'`;
|
|
37
|
+
}
|
|
38
|
+
// Punctuation already carries a quoted literal name, e.g. "'{'".
|
|
39
|
+
const literal = vocabulary.getLiteralName(type);
|
|
40
|
+
if (literal !== undefined)
|
|
41
|
+
return literal;
|
|
42
|
+
return symbolic !== null && symbolic !== void 0 ? symbolic : `<token ${type}>`;
|
|
43
|
+
}
|
|
44
|
+
function joinOr(items) {
|
|
45
|
+
if (items.length === 1)
|
|
46
|
+
return items[0];
|
|
47
|
+
return `${items.slice(0, -1).join(', ')} or ${items[items.length - 1]}`;
|
|
48
|
+
}
|
|
49
|
+
function describeExpected(types, vocabulary) {
|
|
50
|
+
const displays = [];
|
|
51
|
+
const seen = new Set();
|
|
52
|
+
for (const type of types) {
|
|
53
|
+
if (type < antlr4ts_1.Token.MIN_USER_TOKEN_TYPE && type !== antlr4ts_1.Token.EOF)
|
|
54
|
+
continue;
|
|
55
|
+
const display = describeToken(type, vocabulary);
|
|
56
|
+
if (!seen.has(display)) {
|
|
57
|
+
seen.add(display);
|
|
58
|
+
displays.push(display);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (displays.length === 0 || displays.length > MAX_EXPECTED_NAMED) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
return joinOr(displays);
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=token-names.js.map
|
package/dist/model/utils.js
CHANGED
|
@@ -23,8 +23,8 @@ exports.caseGroup = caseGroup;
|
|
|
23
23
|
exports.mkModelID = mkModelID;
|
|
24
24
|
exports.mkModelDef = mkModelDef;
|
|
25
25
|
const uuid_1 = require("uuid");
|
|
26
|
-
const
|
|
27
|
-
const
|
|
26
|
+
const sha2_js_1 = require("@noble/hashes/sha2.js");
|
|
27
|
+
const utils_js_1 = require("@noble/hashes/utils.js");
|
|
28
28
|
const malloy_types_1 = require("./malloy_types");
|
|
29
29
|
/**
|
|
30
30
|
* Format a typeDef as user-readable Malloy type syntax. Used in error
|
|
@@ -155,7 +155,9 @@ function makeDigest(...parts) {
|
|
|
155
155
|
const combined = parts
|
|
156
156
|
.map(p => (p === undefined ? '{undefined}' : `${p.length}:${p}`))
|
|
157
157
|
.join('/');
|
|
158
|
-
|
|
158
|
+
// @noble/hashes v2 dropped implicit string hashing; v1 accepted a string and
|
|
159
|
+
// UTF-8 encoded it internally, so utf8ToBytes here yields the identical digest.
|
|
160
|
+
return (0, utils_js_1.bytesToHex)((0, sha2_js_1.sha256)((0, utils_js_1.utf8ToBytes)(combined)));
|
|
159
161
|
}
|
|
160
162
|
function joinWith(els, sep) {
|
|
161
163
|
const result = [];
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const MALLOY_VERSION = "0.0.
|
|
1
|
+
export declare const MALLOY_VERSION = "0.0.416";
|
package/dist/version.js
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MALLOY_VERSION = void 0;
|
|
4
4
|
// generated with 'generate-version-file' script; do not edit manually
|
|
5
|
-
exports.MALLOY_VERSION = '0.0.
|
|
5
|
+
exports.MALLOY_VERSION = '0.0.416';
|
|
6
6
|
//# sourceMappingURL=version.js.map
|
package/femto-config.motly
CHANGED
|
@@ -16,6 +16,16 @@ parser: {
|
|
|
16
16
|
]
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
tokenNames: {
|
|
20
|
+
deps = [lexer]
|
|
21
|
+
inputs = [
|
|
22
|
+
"src/lang/grammar/MalloyLexer.g4",
|
|
23
|
+
"src/lang/grammar/build_token_names.js"
|
|
24
|
+
]
|
|
25
|
+
outputs = ["src/lang/lib/Malloy/keyword-display-names.ts"]
|
|
26
|
+
commands = ["node src/lang/grammar/build_token_names.js"]
|
|
27
|
+
}
|
|
28
|
+
|
|
19
29
|
codegen: {
|
|
20
|
-
deps = [parser]
|
|
30
|
+
deps = [parser, tokenNames]
|
|
21
31
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@malloydata/malloy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.416",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dist/index.js",
|
|
@@ -51,22 +51,22 @@
|
|
|
51
51
|
"generate-version-file": "VERSION=$(npm pkg get version --workspaces=false | tr -d \\\")\necho \"// generated with 'generate-version-file' script; do not edit manually\\nexport const MALLOY_VERSION = '$VERSION';\" > src/version.ts"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@malloydata/malloy-filter": "0.0.
|
|
55
|
-
"@malloydata/malloy-interfaces": "0.0.
|
|
56
|
-
"@malloydata/malloy-tag": "0.0.
|
|
57
|
-
"@noble/hashes": "^
|
|
54
|
+
"@malloydata/malloy-filter": "0.0.416",
|
|
55
|
+
"@malloydata/malloy-interfaces": "0.0.416",
|
|
56
|
+
"@malloydata/malloy-tag": "0.0.416",
|
|
57
|
+
"@noble/hashes": "^2.2.0",
|
|
58
58
|
"antlr4ts": "^0.5.0-alpha.4",
|
|
59
59
|
"assert": "^2.0.0",
|
|
60
60
|
"jaro-winkler": "^0.2.8",
|
|
61
|
-
"jest-diff": "^29.6.2",
|
|
62
61
|
"lodash": "^4.18.1",
|
|
63
|
-
"luxon": "^3.
|
|
64
|
-
"uuid": "^
|
|
62
|
+
"luxon": "^3.7.2",
|
|
63
|
+
"uuid": "^14.0.0"
|
|
65
64
|
},
|
|
66
65
|
"devDependencies": {
|
|
67
66
|
"@types/jaro-winkler": "^0.2.3",
|
|
68
|
-
"@types/lodash": "^4.
|
|
69
|
-
"@types/luxon": "^3.
|
|
70
|
-
"antlr4ts-cli": "^0.5.0-alpha.4"
|
|
67
|
+
"@types/lodash": "^4.17.24",
|
|
68
|
+
"@types/luxon": "^3.7.2",
|
|
69
|
+
"antlr4ts-cli": "^0.5.0-alpha.4",
|
|
70
|
+
"jest-diff": "^30.4.1"
|
|
71
71
|
}
|
|
72
72
|
}
|