@malloydata/malloy 0.0.55-dev230707183945 → 0.0.55

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.
@@ -1,6 +1,6 @@
1
1
  import { CodePointCharStream, CommonTokenStream, ParserRuleContext, Token } from 'antlr4ts';
2
2
  import { ParseTree } from 'antlr4ts/tree';
3
- import { DocumentLocation, DocumentPosition, DocumentRange, DocumentReference, ModelDef, NamedModelObject, Query, SQLBlockStructDef, StructDef } from '../model/malloy_types';
3
+ import { DocumentLocation, DocumentPosition, DocumentRange, DocumentReference, ImportLocation, ModelDef, NamedModelObject, Query, SQLBlockStructDef, StructDef } from '../model/malloy_types';
4
4
  import { LogMessage, MessageLog } from './parse-log';
5
5
  import { Zone, ZoneData } from './zone';
6
6
  import { ReferenceList } from './reference-list';
@@ -104,6 +104,7 @@ export declare abstract class MalloyTranslation {
104
104
  queryList: Query[];
105
105
  sqlBlocks: SQLBlockStructDef[];
106
106
  modelDef: ModelDef;
107
+ imports: ImportLocation[];
107
108
  readonly parseStep: ParseStep;
108
109
  readonly importsAndTablesStep: ImportsAndTablesStep;
109
110
  readonly astStep: ASTStep;
@@ -134,6 +135,8 @@ export declare abstract class MalloyTranslation {
134
135
  getChildExports(importURL: string): Record<string, NamedModelObject>;
135
136
  private finalAnswer?;
136
137
  translate(extendingModel?: ModelDef): TranslateResponse;
138
+ importAt(position: DocumentPosition): ImportLocation | undefined;
139
+ private buildImports;
137
140
  metadata(): MetadataResponse;
138
141
  completions(position: {
139
142
  line: number;
@@ -61,6 +61,7 @@ const document_help_context_walker_1 = require("./parse-tree-walkers/document-he
61
61
  const reference_list_1 = require("./reference-list");
62
62
  const translate_response_1 = require("./translate-response");
63
63
  const parse_error_handler_1 = require("./parse-error-handler");
64
+ const utils_1 = require("./utils");
64
65
  /**
65
66
  * This ignores a -> popMode when the mode stack is empty, which is a hack,
66
67
  * but it let's us parse }%
@@ -507,6 +508,7 @@ class MalloyTranslation {
507
508
  this.grammarRule = grammarRule;
508
509
  this.queryList = [];
509
510
  this.sqlBlocks = [];
511
+ this.imports = [];
510
512
  this.childTranslators = new Map();
511
513
  this.modelDef = {
512
514
  name: sourceURL,
@@ -642,9 +644,30 @@ class MalloyTranslation {
642
644
  const attempt = this.translateStep.step(this, extendingModel);
643
645
  if (attempt.final) {
644
646
  this.finalAnswer = attempt;
647
+ this.buildImports();
645
648
  }
646
649
  return attempt;
647
650
  }
651
+ importAt(position) {
652
+ // Here we assume that imports DO NOT overlap. And then we do a linear
653
+ // search to find the one we're looking for.
654
+ for (let index = 0; index < this.imports.length; index++) {
655
+ const imp = this.imports[index];
656
+ if ((0, utils_1.locationContainsPosition)(imp.location, position)) {
657
+ return imp;
658
+ }
659
+ }
660
+ return undefined;
661
+ }
662
+ buildImports() {
663
+ for (const [key, value] of Object.entries(this.root.importZone.location)) {
664
+ // Ignore any import in another file
665
+ if (value.url !== this.sourceURL) {
666
+ continue;
667
+ }
668
+ this.imports.push({ importURL: key, location: value });
669
+ }
670
+ }
648
671
  metadata() {
649
672
  return this.metadataStep.step(this);
650
673
  }
@@ -23,6 +23,7 @@
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.ReferenceList = void 0;
26
+ const utils_1 = require("./utils");
26
27
  class ReferenceList {
27
28
  constructor(sourceURL) {
28
29
  this.sourceURL = sourceURL;
@@ -75,12 +76,7 @@ class ReferenceList {
75
76
  return undefined;
76
77
  }
77
78
  const reference = this.references[index];
78
- if (reference.location.range.start.line <= position.line &&
79
- reference.location.range.end.line >= position.line &&
80
- (position.line !== reference.location.range.start.line ||
81
- position.character >= reference.location.range.start.character) &&
82
- (position.line !== reference.location.range.end.line ||
83
- position.character <= reference.location.range.end.character)) {
79
+ if ((0, utils_1.locationContainsPosition)(reference.location, position)) {
84
80
  return reference;
85
81
  }
86
82
  return undefined;
@@ -2407,6 +2407,25 @@ describe('source references', () => {
2407
2407
  });
2408
2408
  });
2409
2409
  });
2410
+ describe('translate imports', () => {
2411
+ test('import at', () => {
2412
+ const source = (0, test_translator_1.markSource) `import ${'"myfile.malloy"'}`;
2413
+ const m = new test_translator_1.TestTranslator(source.code);
2414
+ const resp1 = m.translate();
2415
+ expect(resp1.final).toBeUndefined();
2416
+ m.update({
2417
+ urls: {
2418
+ 'internal://test/langtests/myfile.malloy': 'query: ab -> { project: * }',
2419
+ },
2420
+ });
2421
+ const resp2 = m.translate();
2422
+ expect(resp2.final).toBeDefined();
2423
+ const im = m.importAt({ line: 0, character: 10 });
2424
+ expect(im === null || im === void 0 ? void 0 : im.importURL).toEqual('internal://test/langtests/myfile.malloy');
2425
+ expect(im === null || im === void 0 ? void 0 : im.location.url).toEqual('internal://test/langtests/root.malloy');
2426
+ expect(im === null || im === void 0 ? void 0 : im.location).toMatchObject(source.locations[0]);
2427
+ });
2428
+ });
2410
2429
  describe('translation need error locations', () => {
2411
2430
  test('import error location', () => {
2412
2431
  const source = (0, test_translator_1.model) `import ${'"badfile"'}`;
@@ -0,0 +1,2 @@
1
+ import { DocumentLocation, DocumentPosition } from '../model/malloy_types';
2
+ export declare function locationContainsPosition(location: DocumentLocation, position: DocumentPosition): boolean;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2023 Google LLC
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files
7
+ * (the "Software"), to deal in the Software without restriction,
8
+ * including without limitation the rights to use, copy, modify, merge,
9
+ * publish, distribute, sublicense, and/or sell copies of the Software,
10
+ * and to permit persons to whom the Software is furnished to do so,
11
+ * subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.locationContainsPosition = void 0;
26
+ function locationContainsPosition(location, position) {
27
+ return (location.range.start.line <= position.line &&
28
+ location.range.end.line >= position.line &&
29
+ (position.line !== location.range.start.line ||
30
+ position.character >= location.range.start.character) &&
31
+ (position.line !== location.range.end.line ||
32
+ position.character <= location.range.end.character));
33
+ }
34
+ exports.locationContainsPosition = locationContainsPosition;
35
+ //# sourceMappingURL=utils.js.map
package/dist/malloy.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  import { RunSQLOptions } from './run_sql_options';
3
3
  import { DocumentCompletion as DocumentCompletionDefinition, DocumentHighlight as DocumentHighlightDefinition, DocumentSymbol as DocumentSymbolDefinition, LogMessage, MalloyTranslator } from './lang';
4
4
  import { DocumentHelpContext } from './lang/parse-tree-walkers/document-help-context-walker';
5
- import { CompiledQuery, DocumentReference, FieldBooleanDef, FieldDateDef, FieldJSONDef, FieldNumberDef, FieldStringDef, FieldTimestampDef, FieldTypeDef, FilterExpression, Query as InternalQuery, ModelDef, DocumentPosition as ModelDocumentPosition, NamedQuery, QueryData, QueryDataRow, QueryResult, SQLBlock, SQLBlockStructDef, SearchIndexResult, SearchValueMapResult, StructDef, TurtleDef, FieldUnsupportedDef, QueryRunStats } from './model';
5
+ import { CompiledQuery, DocumentReference, FieldBooleanDef, FieldDateDef, FieldJSONDef, FieldNumberDef, FieldStringDef, FieldTimestampDef, FieldTypeDef, FilterExpression, Query as InternalQuery, ModelDef, DocumentPosition as ModelDocumentPosition, NamedQuery, QueryData, QueryDataRow, QueryResult, SQLBlock, SQLBlockStructDef, SearchIndexResult, SearchValueMapResult, StructDef, TurtleDef, FieldUnsupportedDef, QueryRunStats, ImportLocation } from './model';
6
6
  import { Connection, InfoConnection, LookupConnection, ModelString, ModelURL, QueryString, QueryURL, URLReader } from './runtime_types';
7
7
  import { Taggable, Tags } from './tags';
8
8
  export interface Loggable {
@@ -149,8 +149,9 @@ export declare class Model implements Taggable {
149
149
  private queryList;
150
150
  private sqlBlocks;
151
151
  _referenceAt: (location: ModelDocumentPosition) => DocumentReference | undefined;
152
+ _importAt: (location: ModelDocumentPosition) => ImportLocation | undefined;
152
153
  readonly problems: LogMessage[];
153
- constructor(modelDef: ModelDef, queryList: InternalQuery[], sqlBlocks: SQLBlockStructDef[], problems: LogMessage[], referenceAt?: (location: ModelDocumentPosition) => DocumentReference | undefined);
154
+ constructor(modelDef: ModelDef, queryList: InternalQuery[], sqlBlocks: SQLBlockStructDef[], problems: LogMessage[], referenceAt?: (location: ModelDocumentPosition) => DocumentReference | undefined, importAt?: (location: ModelDocumentPosition) => ImportLocation | undefined);
154
155
  getTags(): Tags;
155
156
  /**
156
157
  * Retrieve a document reference for the token at the given position within
@@ -160,6 +161,14 @@ export declare class Model implements Taggable {
160
161
  * @return A `DocumentReference` at that position if one exists.
161
162
  */
162
163
  getReference(position: ModelDocumentPosition): DocumentReference | undefined;
164
+ /**
165
+ * Retrieve an import for the token at the given position within
166
+ * the document that produced this model.
167
+ *
168
+ * @param position A position within the document.
169
+ * @return An `ImportLocation` at that position if one exists.
170
+ */
171
+ getImport(position: ModelDocumentPosition): ImportLocation | undefined;
163
172
  /**
164
173
  * Retrieve a prepared query by the name of a query at the top level of the model.
165
174
  *
package/dist/malloy.js CHANGED
@@ -79,7 +79,7 @@ class Malloy {
79
79
  const result = translator.translate(model === null || model === void 0 ? void 0 : model._modelDef);
80
80
  if (result.final) {
81
81
  if (result.translated) {
82
- return new Model(result.translated.modelDef, result.translated.queryList, result.translated.sqlBlocks, result.problems || [], (position) => translator.referenceAt(position));
82
+ return new Model(result.translated.modelDef, result.translated.queryList, result.translated.sqlBlocks, result.problems || [], (position) => translator.referenceAt(position), (position) => translator.importAt(position));
83
83
  }
84
84
  else {
85
85
  const errors = result.problems || [];
@@ -317,11 +317,12 @@ exports.MalloyError = MalloyError;
317
317
  * A compiled Malloy document.
318
318
  */
319
319
  class Model {
320
- constructor(modelDef, queryList, sqlBlocks, problems, referenceAt = () => undefined) {
320
+ constructor(modelDef, queryList, sqlBlocks, problems, referenceAt = () => undefined, importAt = () => undefined) {
321
321
  this.modelDef = modelDef;
322
322
  this.queryList = queryList;
323
323
  this.sqlBlocks = sqlBlocks;
324
324
  this._referenceAt = referenceAt;
325
+ this._importAt = importAt;
325
326
  this.problems = problems;
326
327
  }
327
328
  getTags() {
@@ -337,6 +338,16 @@ class Model {
337
338
  getReference(position) {
338
339
  return this._referenceAt(position);
339
340
  }
341
+ /**
342
+ * Retrieve an import for the token at the given position within
343
+ * the document that produced this model.
344
+ *
345
+ * @param position A position within the document.
346
+ * @return An `ImportLocation` at that position if one exists.
347
+ */
348
+ getImport(position) {
349
+ return this._importAt(position);
350
+ }
340
351
  /**
341
352
  * Retrieve a prepared query by the name of a query at the top level of the model.
342
353
  *
@@ -24,6 +24,10 @@ export interface DocumentPosition {
24
24
  line: number;
25
25
  character: number;
26
26
  }
27
+ export interface ImportLocation {
28
+ importURL: string;
29
+ location: DocumentLocation;
30
+ }
27
31
  export interface DocumentLocation {
28
32
  url: string;
29
33
  range: DocumentRange;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.55-dev230707183945",
3
+ "version": "0.0.55",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",