@malloydata/malloy 0.0.416 → 0.0.418

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.
@@ -207,7 +207,7 @@ export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElem
207
207
  visitExprString(pcx: parse.ExprStringContext): ast.ExprString;
208
208
  visitRawString(pcx: parse.RawStringContext): ast.ExprString;
209
209
  visitExprRegex(pcx: parse.ExprRegexContext): ast.ExprRegEx;
210
- visitExprNow(_pcx: parse.ExprNowContext): ast.ExprNow;
210
+ visitExprNow(pcx: parse.ExprNowContext): ast.ExprNow;
211
211
  visitExprNumber(pcx: parse.ExprNumberContext): ast.ExprNumber;
212
212
  visitExprFieldPath(pcx: parse.ExprFieldPathContext): ast.ExprIdReference;
213
213
  visitExprGivenRef(pcx: parse.ExprGivenRefContext): ast.GivenReference;
@@ -1157,7 +1157,11 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
1157
1157
  const malloyRegex = pcx.HACKY_REGEX().text;
1158
1158
  return new ast.ExprRegEx(malloyRegex.slice(2, -1));
1159
1159
  }
1160
- visitExprNow(_pcx) {
1160
+ visitExprNow(pcx) {
1161
+ if (pcx.OPAREN()) {
1162
+ // `now` is a value, not a function; accept `now()`, warn, compile as `now`.
1163
+ this.contextError(pcx, 'now-is-not-a-function', "'now' is a value, not a function; the parentheses are unnecessary. Write 'now'.", { severity: 'warn' });
1164
+ }
1161
1165
  return new ast.ExprNow();
1162
1166
  }
1163
1167
  visitExprNumber(pcx) {
@@ -223,6 +223,7 @@ type MessageParameterTypes = {
223
223
  'order-by-not-found-in-output': string;
224
224
  'order-by-analytic': string;
225
225
  'order-by-bad-reference': string;
226
+ 'now-is-not-a-function': string;
226
227
  'illegal-index-operation': string;
227
228
  'illegal-project-operation': string;
228
229
  'illegal-grouping-operation': string;
@@ -1,10 +1,13 @@
1
- import type { InputMismatchException, Parser } from 'antlr4ts';
1
+ import type { InputMismatchException, NoViableAltException, Parser } from 'antlr4ts';
2
2
  import { DefaultErrorStrategy } from 'antlr4ts';
3
3
  /**
4
- * Overrides the three DefaultErrorStrategy methods that paste the parser's
4
+ * Overrides the DefaultErrorStrategy methods that paste the parser's
5
5
  * expected-token set into the message: tokens are named the way the user types
6
6
  * them (via describeExpected) and the set is dropped once too large to be a hint.
7
7
  *
8
+ * Each path also checks reservedNameMessage first, so a reserved word used where
9
+ * a name was expected (`group_by: year`) says "quote it".
10
+ *
8
11
  * Fallback only — MalloyParserErrorListener's custom-error cases run first and
9
12
  * override these when they match.
10
13
  */
@@ -12,4 +15,5 @@ export declare class MalloyErrorStrategy extends DefaultErrorStrategy {
12
15
  protected reportInputMismatch(recognizer: Parser, e: InputMismatchException): void;
13
16
  protected reportUnwantedToken(recognizer: Parser): void;
14
17
  protected reportMissingToken(recognizer: Parser): void;
18
+ protected reportNoViableAlternative(recognizer: Parser, e: NoViableAltException): void;
15
19
  }
@@ -13,18 +13,27 @@ function unexpected(offending, clause) {
13
13
  : `unexpected ${offending}`;
14
14
  }
15
15
  /**
16
- * Overrides the three DefaultErrorStrategy methods that paste the parser's
16
+ * Overrides the DefaultErrorStrategy methods that paste the parser's
17
17
  * expected-token set into the message: tokens are named the way the user types
18
18
  * them (via describeExpected) and the set is dropped once too large to be a hint.
19
19
  *
20
+ * Each path also checks reservedNameMessage first, so a reserved word used where
21
+ * a name was expected (`group_by: year`) says "quote it".
22
+ *
20
23
  * Fallback only — MalloyParserErrorListener's custom-error cases run first and
21
24
  * override these when they match.
22
25
  */
23
26
  class MalloyErrorStrategy extends antlr4ts_1.DefaultErrorStrategy {
24
27
  reportInputMismatch(recognizer, e) {
25
28
  var _a, _b;
26
- const offending = this.getTokenErrorDisplay(e.getOffendingToken(recognizer));
29
+ const offendingToken = e.getOffendingToken(recognizer);
27
30
  const expected = (_b = (_a = e.expectedTokens) === null || _a === void 0 ? void 0 : _a.toArray()) !== null && _b !== void 0 ? _b : [];
31
+ const reserved = (0, token_names_1.reservedNameMessage)(offendingToken, expected, recognizer);
32
+ if (reserved) {
33
+ this.notifyErrorListeners(recognizer, reserved, e);
34
+ return;
35
+ }
36
+ const offending = this.getTokenErrorDisplay(offendingToken);
28
37
  const clause = (0, token_names_1.describeExpected)(expected, recognizer.vocabulary);
29
38
  this.notifyErrorListeners(recognizer, unexpected(offending, clause), e);
30
39
  }
@@ -34,8 +43,13 @@ class MalloyErrorStrategy extends antlr4ts_1.DefaultErrorStrategy {
34
43
  }
35
44
  this.beginErrorCondition(recognizer);
36
45
  const t = recognizer.currentToken;
37
- const offending = this.getTokenErrorDisplay(t);
38
46
  const expected = this.getExpectedTokens(recognizer).toArray();
47
+ const reserved = (0, token_names_1.reservedNameMessage)(t, expected, recognizer);
48
+ if (reserved) {
49
+ recognizer.notifyErrorListeners(reserved, t, undefined);
50
+ return;
51
+ }
52
+ const offending = this.getTokenErrorDisplay(t);
39
53
  const clause = (0, token_names_1.describeExpected)(expected, recognizer.vocabulary);
40
54
  recognizer.notifyErrorListeners(unexpected(offending, clause), t, undefined);
41
55
  }
@@ -45,14 +59,32 @@ class MalloyErrorStrategy extends antlr4ts_1.DefaultErrorStrategy {
45
59
  }
46
60
  this.beginErrorCondition(recognizer);
47
61
  const t = recognizer.currentToken;
48
- const offending = this.getTokenErrorDisplay(t);
49
62
  const expected = this.getExpectedTokens(recognizer).toArray();
63
+ const reserved = (0, token_names_1.reservedNameMessage)(t, expected, recognizer);
64
+ if (reserved) {
65
+ recognizer.notifyErrorListeners(reserved, t, undefined);
66
+ return;
67
+ }
68
+ const offending = this.getTokenErrorDisplay(t);
50
69
  const clause = (0, token_names_1.describeExpected)(expected, recognizer.vocabulary);
51
70
  const msg = clause
52
71
  ? `missing ${clause} before ${offending}`
53
72
  : `something is missing before ${offending}`;
54
73
  recognizer.notifyErrorListeners(msg, t, undefined);
55
74
  }
75
+ // Dispatched from reportError (already in error condition), unlike the inline-
76
+ // recovery methods above — an inErrorRecoveryMode guard here would swallow the
77
+ // error. Short-circuit to the reserved-word hint, else defer to super.
78
+ reportNoViableAlternative(recognizer, e) {
79
+ const t = recognizer.currentToken;
80
+ const expected = this.getExpectedTokens(recognizer).toArray();
81
+ const reserved = (0, token_names_1.reservedNameMessage)(t, expected, recognizer);
82
+ if (reserved) {
83
+ this.notifyErrorListeners(recognizer, reserved, e);
84
+ return;
85
+ }
86
+ super.reportNoViableAlternative(recognizer, e);
87
+ }
56
88
  }
57
89
  exports.MalloyErrorStrategy = MalloyErrorStrategy;
58
90
  //# sourceMappingURL=malloy-error-strategy.js.map
@@ -1,3 +1,5 @@
1
- import type { Vocabulary } from 'antlr4ts';
1
+ import type { Parser, Vocabulary } from 'antlr4ts';
2
+ import { Token } from 'antlr4ts';
2
3
  export declare function describeToken(type: number, vocabulary: Vocabulary): string;
3
4
  export declare function describeExpected(types: number[], vocabulary: Vocabulary): string | undefined;
5
+ export declare function reservedNameMessage(offending: Token | undefined, expected: number[], recognizer: Parser): string | undefined;
@@ -6,7 +6,9 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.describeToken = describeToken;
8
8
  exports.describeExpected = describeExpected;
9
+ exports.reservedNameMessage = reservedNameMessage;
9
10
  const antlr4ts_1 = require("antlr4ts");
11
+ const MalloyParser_1 = require("../lib/Malloy/MalloyParser");
10
12
  const keyword_display_names_1 = require("../lib/Malloy/keyword-display-names");
11
13
  // Pattern tokens have neither a literal nor a keyword spelling to show, so they
12
14
  // get hand-written prose instead of their SHOUTING symbolic name.
@@ -63,4 +65,25 @@ function describeExpected(types, vocabulary) {
63
65
  }
64
66
  return joinOr(displays);
65
67
  }
68
+ // When a bare-word reserved token appears where a name (IDENTIFIER) was legal,
69
+ // the user meant it as a field name; return a "quote it" message. undefined
70
+ // otherwise, so the caller keeps its normal message.
71
+ function reservedNameMessage(offending, expected, recognizer) {
72
+ const text = offending === null || offending === void 0 ? void 0 : offending.text;
73
+ if (!text || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(text))
74
+ return undefined;
75
+ const symbolic = recognizer.vocabulary.getSymbolicName(offending.type);
76
+ if (symbolic === undefined || keyword_display_names_1.KEYWORD_DISPLAY_NAMES[symbolic] === undefined) {
77
+ return undefined;
78
+ }
79
+ if (!expected.includes(MalloyParser_1.MalloyParser.IDENTIFIER))
80
+ return undefined;
81
+ // A reserved word followed by '(' is a function call (count()), not a name.
82
+ // offending is the current token here, so LA(2) is the next on-channel token;
83
+ // LA fetches it lazily rather than pre-filling the stream.
84
+ if (recognizer.inputStream.LA(2) === MalloyParser_1.MalloyParser.OPAREN) {
85
+ return undefined;
86
+ }
87
+ return `'${text}' is a reserved word, so to use it as a name you must quote it: \`${text}\``;
88
+ }
66
89
  //# sourceMappingURL=token-names.js.map
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const MALLOY_VERSION = "0.0.416";
1
+ export declare const MALLOY_VERSION = "0.0.418";
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.416';
5
+ exports.MALLOY_VERSION = '0.0.418';
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.416",
3
+ "version": "0.0.418",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
@@ -51,9 +51,9 @@
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.416",
55
- "@malloydata/malloy-interfaces": "0.0.416",
56
- "@malloydata/malloy-tag": "0.0.416",
54
+ "@malloydata/malloy-filter": "0.0.418",
55
+ "@malloydata/malloy-interfaces": "0.0.418",
56
+ "@malloydata/malloy-tag": "0.0.418",
57
57
  "@noble/hashes": "^2.2.0",
58
58
  "antlr4ts": "^0.5.0-alpha.4",
59
59
  "assert": "^2.0.0",