@malloydata/malloy 0.0.80-dev230906223653 → 0.0.80-dev230907131802

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.
@@ -92,6 +92,8 @@ import { BlockSQLDefContext } from "./MalloyParser";
92
92
  import { SqlStringContext } from "./MalloyParser";
93
93
  import { SqlInterpolationContext } from "./MalloyParser";
94
94
  import { ImportStatementContext } from "./MalloyParser";
95
+ import { ImportSelectContext } from "./MalloyParser";
96
+ import { ImportItemContext } from "./MalloyParser";
95
97
  import { ImportURLContext } from "./MalloyParser";
96
98
  import { DocAnnotationsContext } from "./MalloyParser";
97
99
  import { IgnoredObjectAnnotationsContext } from "./MalloyParser";
@@ -1297,6 +1299,26 @@ export interface MalloyParserListener extends ParseTreeListener {
1297
1299
  * @param ctx the parse tree
1298
1300
  */
1299
1301
  exitImportStatement?: (ctx: ImportStatementContext) => void;
1302
+ /**
1303
+ * Enter a parse tree produced by `MalloyParser.importSelect`.
1304
+ * @param ctx the parse tree
1305
+ */
1306
+ enterImportSelect?: (ctx: ImportSelectContext) => void;
1307
+ /**
1308
+ * Exit a parse tree produced by `MalloyParser.importSelect`.
1309
+ * @param ctx the parse tree
1310
+ */
1311
+ exitImportSelect?: (ctx: ImportSelectContext) => void;
1312
+ /**
1313
+ * Enter a parse tree produced by `MalloyParser.importItem`.
1314
+ * @param ctx the parse tree
1315
+ */
1316
+ enterImportItem?: (ctx: ImportItemContext) => void;
1317
+ /**
1318
+ * Exit a parse tree produced by `MalloyParser.importItem`.
1319
+ * @param ctx the parse tree
1320
+ */
1321
+ exitImportItem?: (ctx: ImportItemContext) => void;
1300
1322
  /**
1301
1323
  * Enter a parse tree produced by `MalloyParser.importURL`.
1302
1324
  * @param ctx the parse tree
@@ -92,6 +92,8 @@ import { BlockSQLDefContext } from "./MalloyParser";
92
92
  import { SqlStringContext } from "./MalloyParser";
93
93
  import { SqlInterpolationContext } from "./MalloyParser";
94
94
  import { ImportStatementContext } from "./MalloyParser";
95
+ import { ImportSelectContext } from "./MalloyParser";
96
+ import { ImportItemContext } from "./MalloyParser";
95
97
  import { ImportURLContext } from "./MalloyParser";
96
98
  import { DocAnnotationsContext } from "./MalloyParser";
97
99
  import { IgnoredObjectAnnotationsContext } from "./MalloyParser";
@@ -849,6 +851,18 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
849
851
  * @return the visitor result
850
852
  */
851
853
  visitImportStatement?: (ctx: ImportStatementContext) => Result;
854
+ /**
855
+ * Visit a parse tree produced by `MalloyParser.importSelect`.
856
+ * @param ctx the parse tree
857
+ * @return the visitor result
858
+ */
859
+ visitImportSelect?: (ctx: ImportSelectContext) => Result;
860
+ /**
861
+ * Visit a parse tree produced by `MalloyParser.importItem`.
862
+ * @param ctx the parse tree
863
+ * @return the visitor result
864
+ */
865
+ visitImportItem?: (ctx: ImportItemContext) => Result;
852
866
  /**
853
867
  * Visit a parse tree produced by `MalloyParser.importURL`.
854
868
  * @param ctx the parse tree
@@ -303,6 +303,10 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
303
303
  const source = this.visitUnextendableSource(pcx.unextendableSource());
304
304
  const query = new ast.FullQuery(source);
305
305
  query.turtleName = this.getFieldName(pcx);
306
+ const idTxt = pcx.id().text;
307
+ if (this.m4WarningsEnabled() && pcx.ARROW()) {
308
+ this.contextError(pcx, `Use '.${idTxt}' instead of '->${idTxt}' to reference the query contained in the source`, 'warn');
309
+ }
306
310
  return this.astAt(query, pcx);
307
311
  }
308
312
  visitQueryByName(pcx) {
@@ -1199,7 +1203,18 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
1199
1203
  }
1200
1204
  visitImportStatement(pcx) {
1201
1205
  const url = this.getPlainString(pcx.importURL());
1202
- return this.astAt(new ast.ImportStatement(url, this.parseInfo.sourceURL), pcx);
1206
+ const importStmt = this.astAt(new ast.ImportStatement(url, this.parseInfo.sourceURL), pcx);
1207
+ const selectCx = pcx.importSelect();
1208
+ if (selectCx) {
1209
+ for (const item of selectCx.importItem()) {
1210
+ const ids = item.id();
1211
+ const oldName = ids[1]
1212
+ ? this.astAt(new ast.ImportSourceName((0, parse_utils_1.idToStr)(ids[1])), ids[1])
1213
+ : undefined;
1214
+ importStmt.push(this.astAt(new ast.ImportSelect((0, parse_utils_1.idToStr)(ids[0]), oldName), ids[0]));
1215
+ }
1216
+ }
1217
+ return importStmt;
1203
1218
  }
1204
1219
  visitJustExpr(pcx) {
1205
1220
  return this.getFieldExpr(pcx.fieldExpr());
@@ -35,6 +35,7 @@ export type HasID = ParserRuleContext & {
35
35
  * @returns The indenftifier text
36
36
  */
37
37
  export declare function getId(cx: HasID): string;
38
+ export declare function idToStr(cx: IdContext): string;
38
39
  export declare function getOptionalId(cx: ParserRuleContext): string | undefined;
39
40
  export declare function unIndent(parts: (string | unknown)[]): void;
40
41
  export {};
@@ -22,7 +22,7 @@
22
22
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.unIndent = exports.getOptionalId = exports.getId = exports.parseString = exports.getStringParts = exports.getStringIfShort = exports.getShortString = void 0;
25
+ exports.unIndent = exports.getOptionalId = exports.idToStr = exports.getId = exports.parseString = exports.getStringParts = exports.getStringIfShort = exports.getShortString = void 0;
26
26
  /**
27
27
  * Take the text of a matched string, including the matching quote
28
28
  * characters, and return the actual contents of the string after
@@ -152,13 +152,17 @@ exports.parseString = parseString;
152
152
  * @returns The indenftifier text
153
153
  */
154
154
  function getId(cx) {
155
- const quoted = cx.id().BQ_STRING();
155
+ return idToStr(cx.id());
156
+ }
157
+ exports.getId = getId;
158
+ function idToStr(cx) {
159
+ const quoted = cx.BQ_STRING();
156
160
  if (quoted) {
157
161
  return parseString(quoted.text, '`');
158
162
  }
159
- return cx.id().text;
163
+ return cx.text;
160
164
  }
161
- exports.getId = getId;
165
+ exports.idToStr = idToStr;
162
166
  function getOptionalId(cx) {
163
167
  function containsID(cx) {
164
168
  return 'id' in cx;
@@ -159,5 +159,71 @@ source: botProjQSrc is from(->botProjQ)
159
159
  }
160
160
  }
161
161
  });
162
+ test('selective import of source', () => {
163
+ const docParse = new test_translator_1.TestTranslator('import { bb } from "child"');
164
+ const xr = docParse.unresolved();
165
+ expect(docParse).toParse();
166
+ expect(xr).toEqual({ urls: ['internal://test/langtests/child'] });
167
+ docParse.update({
168
+ urls: {
169
+ 'internal://test/langtests/child': 'source: aa is a; source: bb is a',
170
+ },
171
+ });
172
+ expect(docParse).toTranslate();
173
+ const bb = docParse.getSourceDef('bb');
174
+ expect(bb).toBeDefined();
175
+ const aa = docParse.getSourceDef('aa');
176
+ expect(aa).toBeUndefined();
177
+ });
178
+ test('renaming import of source', () => {
179
+ const docParse = new test_translator_1.TestTranslator('import { bb is aa } from "child"');
180
+ const xr = docParse.unresolved();
181
+ expect(docParse).toParse();
182
+ expect(xr).toEqual({ urls: ['internal://test/langtests/child'] });
183
+ docParse.update({
184
+ urls: { 'internal://test/langtests/child': 'source: aa is a' },
185
+ });
186
+ expect(docParse).toTranslate();
187
+ const bb = docParse.getSourceDef('bb');
188
+ expect(bb).toBeDefined();
189
+ });
190
+ test('selective import of source, not found', () => {
191
+ const doc = (0, test_translator_1.model) `import { ${'bb'} } from "child"`;
192
+ const xr = doc.translator.unresolved();
193
+ expect(doc).toParse();
194
+ expect(xr).toEqual({ urls: ['internal://test/langtests/child'] });
195
+ doc.translator.update({
196
+ urls: {
197
+ 'internal://test/langtests/child': 'source: aa is a',
198
+ },
199
+ });
200
+ expect(doc.translator).translationToFailWith("Cannot find 'bb', not imported");
201
+ });
202
+ test('selective renamed import of source, not found', () => {
203
+ const doc = (0, test_translator_1.model) `import { cc is ${'bb'} } from "child"`;
204
+ const xr = doc.translator.unresolved();
205
+ expect(doc).toParse();
206
+ expect(xr).toEqual({ urls: ['internal://test/langtests/child'] });
207
+ doc.translator.update({
208
+ urls: {
209
+ 'internal://test/langtests/child': 'source: aa is a',
210
+ },
211
+ });
212
+ expect(doc.translator).translationToFailWith("Cannot find 'bb', not imported");
213
+ });
214
+ test('selective import of source, no-redefinition', () => {
215
+ const doc = (0, test_translator_1.model) `
216
+ import { cc is ${'bb'} } from "child"
217
+ import { cc is ${'bb'} } from "child"`;
218
+ const xr = doc.translator.unresolved();
219
+ expect(doc).toParse();
220
+ expect(xr).toEqual({ urls: ['internal://test/langtests/child'] });
221
+ doc.translator.update({
222
+ urls: {
223
+ 'internal://test/langtests/child': 'source: bb is a',
224
+ },
225
+ });
226
+ expect(doc.translator).translationToFailWith("Cannot redefine 'cc'");
227
+ });
162
228
  });
163
229
  //# sourceMappingURL=imports.spec.js.map
@@ -64,17 +64,22 @@ describe('query:', () => {
64
64
  test('from(query) refined into query', () => {
65
65
  expect('query: from(ab -> {group_by: astr}) { dimension: bigstr is upper(astr) } -> { group_by: bigstr }').toTranslate();
66
66
  });
67
+ test('arrow turtle geenrates m4 warning', () => {
68
+ expect(`##! m4warnings
69
+ run: ab -> aturtle
70
+ `).toTranslateWithWarnings("Use '.aturtle' instead of '->aturtle' to reference the query contained in the source");
71
+ });
67
72
  test('query with shortcut filtered turtle', () => {
68
- expect("query: allA is ab->aturtle {? astr ~ 'a%' }").toTranslate();
73
+ expect("query: allA is ab.aturtle {? astr ~ 'a%' }").toTranslate();
69
74
  });
70
75
  test('query with shortcut filtered turtle m4warning', () => {
71
76
  expect(`
72
77
  ##! m4warnings
73
- query: allA is ab->aturtle refine {? astr ~ 'a%' }
78
+ query: allA is ab.aturtle refine {? astr ~ 'a%' }
74
79
  `).toTranslateWithWarnings('Filter shortcut `{? condition }` is deprecated; use `{ where: condition } instead');
75
80
  });
76
81
  test('query with filtered turtle', () => {
77
- expect("query: allA is ab->aturtle { where: astr ~ 'a%' }").toTranslate();
82
+ expect("query: allA is ab.aturtle { where: astr ~ 'a%' }").toTranslate();
78
83
  });
79
84
  test('nest: in group_by:', () => {
80
85
  expect(`
@@ -903,7 +908,7 @@ describe('query:', () => {
903
908
  declare: aratio is ai / acount
904
909
  }
905
910
  }
906
- query: nab -> xturtle + { aggregate: aratio }
911
+ query: nab.xturtle + { aggregate: aratio }
907
912
  `);
908
913
  expect(m).toTranslate();
909
914
  const t = m.translate();
@@ -925,7 +930,7 @@ describe('query:', () => {
925
930
  });
926
931
  test('refine query source with field', () => {
927
932
  const m = new test_translator_1.TestTranslator(`
928
- query: ab -> aturtle + {
933
+ query: ab.aturtle + {
929
934
  declare: aratio is ai / acount
930
935
  aggregate: aratio
931
936
  }
@@ -949,7 +954,7 @@ describe('query:', () => {
949
954
  });
950
955
  test('refine query source with join', () => {
951
956
  const m = new test_translator_1.TestTranslator(`
952
- query: ab -> aturtle + {
957
+ query: ab.aturtle + {
953
958
  join_one: bb is b on bb.astr = astr
954
959
  group_by: foo is bb.astr
955
960
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.80-dev230906223653",
3
+ "version": "0.0.80-dev230907131802",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",