@malloydata/malloy 0.0.225-dev250111002123 → 0.0.225-dev250113200903
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/statements/import-statement.js +2 -1
- package/dist/lang/ast/types/document-compile-result.d.ts +1 -3
- package/dist/lang/ast/types/malloy-element.d.ts +1 -3
- package/dist/lang/ast/types/malloy-element.js +11 -26
- package/dist/lang/index.d.ts +1 -1
- package/dist/lang/index.js +2 -1
- package/dist/lang/parse-malloy.d.ts +21 -6
- package/dist/lang/parse-malloy.js +86 -24
- package/dist/lang/test/annotation.spec.js +5 -5
- package/dist/lang/test/expressions.spec.js +2 -2
- package/dist/lang/test/imports.spec.js +29 -1
- package/dist/lang/test/parse-expects.js +1 -1
- package/dist/lang/test/pretranslate.spec.d.ts +1 -0
- package/dist/lang/test/pretranslate.spec.js +80 -0
- package/dist/lang/test/query.spec.js +6 -6
- package/dist/lang/test/sql-block.spec.js +3 -3
- package/dist/lang/test/test-translator.js +9 -9
- package/dist/lang/translate-response.d.ts +2 -6
- package/dist/malloy.d.ts +1 -2
- package/dist/malloy.js +16 -11
- package/dist/model/malloy_types.d.ts +5 -0
- package/package.json +1 -1
|
@@ -82,8 +82,9 @@ class ImportStatement extends malloy_element_1.ListOf {
|
|
|
82
82
|
this.logError('no-translator-for-import', 'Cannot import without translation context');
|
|
83
83
|
}
|
|
84
84
|
else if (this.fullURL) {
|
|
85
|
+
const pretranslated = trans.root.pretranslatedModels.get(this.fullURL);
|
|
85
86
|
const src = trans.root.importZone.getEntry(this.fullURL);
|
|
86
|
-
if (src.status === 'present') {
|
|
87
|
+
if (pretranslated || src.status === 'present') {
|
|
87
88
|
const importable = trans.getChildExports(this.fullURL);
|
|
88
89
|
if (this.notEmpty()) {
|
|
89
90
|
// just import the named objects
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { ModelDef
|
|
1
|
+
import { ModelDef } from '../../../model/malloy_types';
|
|
2
2
|
import { ModelDataRequest } from '../../translate-response';
|
|
3
3
|
export interface DocumentCompileResult {
|
|
4
4
|
modelDef: ModelDef;
|
|
5
|
-
queryList: Query[];
|
|
6
|
-
sqlBlocks: SQLSourceDef[];
|
|
7
5
|
needs: ModelDataRequest;
|
|
8
6
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Annotation, DocumentLocation, DocumentReference, ModelDef, ModelAnnotation, NamedModelObject, Query,
|
|
1
|
+
import { Annotation, DocumentLocation, DocumentReference, ModelDef, ModelAnnotation, NamedModelObject, Query, StructDef } from '../../../model/malloy_types';
|
|
2
2
|
import { Tag } from '../../../tags';
|
|
3
3
|
import { LogMessageOptions, MessageLogger, MessageParameterType, MessageCode } from '../../parse-log';
|
|
4
4
|
import { MalloyTranslation } from '../../parse-malloy';
|
|
@@ -121,7 +121,6 @@ export declare class Document extends MalloyElement implements NameSpace {
|
|
|
121
121
|
globalNameSpace: NameSpace;
|
|
122
122
|
documentModel: Record<string, ModelEntry>;
|
|
123
123
|
queryList: Query[];
|
|
124
|
-
sqlBlocks: SQLSourceDef[];
|
|
125
124
|
statements: DocStatementList;
|
|
126
125
|
didInitModel: boolean;
|
|
127
126
|
annotation: Annotation;
|
|
@@ -134,7 +133,6 @@ export declare class Document extends MalloyElement implements NameSpace {
|
|
|
134
133
|
hasAnnotation(): boolean;
|
|
135
134
|
currentModelAnnotation(): ModelAnnotation | undefined;
|
|
136
135
|
modelDef(): ModelDef;
|
|
137
|
-
defineSQL(sql: SQLSourceDef, name?: string): boolean;
|
|
138
136
|
getEntry(str: string): ModelEntry;
|
|
139
137
|
setEntry(str: string, ent: ModelEntry): void;
|
|
140
138
|
/**
|
|
@@ -430,7 +430,6 @@ class Document extends MalloyElement {
|
|
|
430
430
|
this.globalNameSpace = new global_name_space_1.GlobalNameSpace();
|
|
431
431
|
this.documentModel = {};
|
|
432
432
|
this.queryList = [];
|
|
433
|
-
this.sqlBlocks = [];
|
|
434
433
|
this.didInitModel = false;
|
|
435
434
|
this.annotation = {};
|
|
436
435
|
this.experiments = new tags_1.Tag({});
|
|
@@ -445,7 +444,6 @@ class Document extends MalloyElement {
|
|
|
445
444
|
}
|
|
446
445
|
this.documentModel = {};
|
|
447
446
|
this.queryList = [];
|
|
448
|
-
this.sqlBlocks = [];
|
|
449
447
|
if (extendingModelDef) {
|
|
450
448
|
if (extendingModelDef.annotation) {
|
|
451
449
|
this.annotation.inherits = extendingModelDef.annotation;
|
|
@@ -471,11 +469,6 @@ class Document extends MalloyElement {
|
|
|
471
469
|
q.modelAnnotation = modelDef.annotation;
|
|
472
470
|
}
|
|
473
471
|
}
|
|
474
|
-
for (const q of this.sqlBlocks) {
|
|
475
|
-
if (q.modelAnnotation === undefined && modelDef.annotation) {
|
|
476
|
-
q.modelAnnotation = modelDef.annotation;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
472
|
}
|
|
480
473
|
if (modelDef.annotation) {
|
|
481
474
|
for (const sd of this.modelAnnotationTodoList) {
|
|
@@ -483,9 +476,10 @@ class Document extends MalloyElement {
|
|
|
483
476
|
}
|
|
484
477
|
}
|
|
485
478
|
const ret = {
|
|
486
|
-
modelDef
|
|
487
|
-
|
|
488
|
-
|
|
479
|
+
modelDef: {
|
|
480
|
+
...modelDef,
|
|
481
|
+
queryList: this.queryList,
|
|
482
|
+
},
|
|
489
483
|
needs,
|
|
490
484
|
};
|
|
491
485
|
return ret;
|
|
@@ -505,7 +499,13 @@ class Document extends MalloyElement {
|
|
|
505
499
|
}
|
|
506
500
|
}
|
|
507
501
|
modelDef() {
|
|
508
|
-
const def = {
|
|
502
|
+
const def = {
|
|
503
|
+
name: '',
|
|
504
|
+
exports: [],
|
|
505
|
+
contents: {},
|
|
506
|
+
queryList: [],
|
|
507
|
+
dependencies: {},
|
|
508
|
+
};
|
|
509
509
|
if (this.hasAnnotation()) {
|
|
510
510
|
def.annotation = this.currentModelAnnotation();
|
|
511
511
|
}
|
|
@@ -524,21 +524,6 @@ class Document extends MalloyElement {
|
|
|
524
524
|
}
|
|
525
525
|
return def;
|
|
526
526
|
}
|
|
527
|
-
defineSQL(sql, name) {
|
|
528
|
-
const ret = {
|
|
529
|
-
...sql,
|
|
530
|
-
as: `$${this.sqlBlocks.length}`,
|
|
531
|
-
};
|
|
532
|
-
if (name) {
|
|
533
|
-
if (this.getEntry(name)) {
|
|
534
|
-
return false;
|
|
535
|
-
}
|
|
536
|
-
ret.as = name;
|
|
537
|
-
this.setEntry(name, { entry: ret });
|
|
538
|
-
}
|
|
539
|
-
this.sqlBlocks.push(ret);
|
|
540
|
-
return true;
|
|
541
|
-
}
|
|
542
527
|
getEntry(str) {
|
|
543
528
|
var _a;
|
|
544
529
|
return (_a = this.globalNameSpace.getEntry(str)) !== null && _a !== void 0 ? _a : this.documentModel[str];
|
package/dist/lang/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { MalloyTranslator } from './parse-malloy';
|
|
1
|
+
export { MalloyTranslator, MalloyTranslation } from './parse-malloy';
|
|
2
2
|
export type { UpdateData, SchemaData, URLData, SQLSources as SQLBlockData, } from './parse-malloy';
|
|
3
3
|
export type { TranslateResponse } from './translate-response';
|
|
4
4
|
export { exploreQueryWalkerBuilder } from './parse-tree-walkers/explore-query-walker';
|
package/dist/lang/index.js
CHANGED
|
@@ -22,9 +22,10 @@
|
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.exploreQueryWalkerBuilder = exports.MalloyTranslator = void 0;
|
|
25
|
+
exports.exploreQueryWalkerBuilder = exports.MalloyTranslation = exports.MalloyTranslator = void 0;
|
|
26
26
|
var parse_malloy_1 = require("./parse-malloy");
|
|
27
27
|
Object.defineProperty(exports, "MalloyTranslator", { enumerable: true, get: function () { return parse_malloy_1.MalloyTranslator; } });
|
|
28
|
+
Object.defineProperty(exports, "MalloyTranslation", { enumerable: true, get: function () { return parse_malloy_1.MalloyTranslation; } });
|
|
28
29
|
var explore_query_walker_1 = require("./parse-tree-walkers/explore-query-walker");
|
|
29
30
|
Object.defineProperty(exports, "exploreQueryWalkerBuilder", { enumerable: true, get: function () { return explore_query_walker_1.exploreQueryWalkerBuilder; } });
|
|
30
31
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ANTLRErrorListener, ParserRuleContext, Token } from 'antlr4ts';
|
|
2
|
-
import { DocumentLocation, DocumentPosition, DocumentRange, DocumentReference, ImportLocation, ModelDef, NamedModelObject,
|
|
2
|
+
import { DocumentLocation, DocumentPosition, DocumentRange, DocumentReference, ImportLocation, ModelDef, NamedModelObject, SourceDef, SQLSourceDef, DependencyTree } from '../model/malloy_types';
|
|
3
3
|
import { BaseMessageLogger, LogMessage, LogMessageOptions, MessageCode, MessageLogger, MessageParameterType } from './parse-log';
|
|
4
4
|
import { Zone, ZoneData } from './zone';
|
|
5
5
|
import { ReferenceList } from './reference-list';
|
|
@@ -7,7 +7,7 @@ import { ASTResponse, CompletionsResponse, DataRequestResponse, ProblemResponse,
|
|
|
7
7
|
import { Tag } from '../tags';
|
|
8
8
|
import { MalloyParseInfo } from './malloy-parse-info';
|
|
9
9
|
import { EventStream } from '../runtime_types';
|
|
10
|
-
export type StepResponses = DataRequestResponse | ASTResponse | TranslateResponse | ParseResponse | MetadataResponse;
|
|
10
|
+
export type StepResponses = DataRequestResponse | ASTResponse | TranslateResponse | ParseResponse | MetadataResponse | PretranslatedResponse;
|
|
11
11
|
/**
|
|
12
12
|
* A Translation is a series of translation steps. Each step can depend
|
|
13
13
|
* on other steps, in which case the preceeding steps will be passed
|
|
@@ -27,6 +27,10 @@ interface ParseData extends ProblemResponse, NeedURLData, FinalResponse {
|
|
|
27
27
|
parse: MalloyParseInfo;
|
|
28
28
|
}
|
|
29
29
|
export type ParseResponse = Partial<ParseData>;
|
|
30
|
+
interface PretranslatedData {
|
|
31
|
+
translation: ModelDef;
|
|
32
|
+
}
|
|
33
|
+
export type PretranslatedResponse = PretranslatedData | null;
|
|
30
34
|
/**
|
|
31
35
|
* ParseStep -- Parse the source URL
|
|
32
36
|
*/
|
|
@@ -109,9 +113,7 @@ export declare abstract class MalloyTranslation {
|
|
|
109
113
|
grammarRule: string;
|
|
110
114
|
abstract root: MalloyTranslator;
|
|
111
115
|
childTranslators: Map<string, MalloyTranslation>;
|
|
112
|
-
|
|
113
|
-
queryList: Query[];
|
|
114
|
-
sqlBlocks: SQLSourceDef[];
|
|
116
|
+
sqlSources: SQLSourceDef[];
|
|
115
117
|
modelDef: ModelDef;
|
|
116
118
|
imports: ImportLocation[];
|
|
117
119
|
compilerFlags: Tag;
|
|
@@ -126,8 +128,15 @@ export declare abstract class MalloyTranslation {
|
|
|
126
128
|
readonly translateStep: TranslateStep;
|
|
127
129
|
readonly references: ReferenceList;
|
|
128
130
|
constructor(sourceURL: string, importBaseURL?: string | null, grammarRule?: string);
|
|
131
|
+
_urlIsFullPath: boolean | undefined;
|
|
132
|
+
get urlIsFullPath(): boolean;
|
|
129
133
|
addChild(url: string): void;
|
|
130
134
|
getDependencies(): string[];
|
|
135
|
+
getDependencyTree(): DependencyTree;
|
|
136
|
+
newlyTranslatedDependencies(): {
|
|
137
|
+
url: string;
|
|
138
|
+
modelDef: ModelDef;
|
|
139
|
+
}[];
|
|
131
140
|
addReference(reference: DocumentReference): void;
|
|
132
141
|
referenceAt(position: DocumentPosition): DocumentReference | undefined;
|
|
133
142
|
/**
|
|
@@ -149,6 +158,7 @@ export declare abstract class MalloyTranslation {
|
|
|
149
158
|
getChildExports(importURL: string): Record<string, NamedModelObject>;
|
|
150
159
|
private finalAnswer?;
|
|
151
160
|
translate(extendingModel?: ModelDef): TranslateResponse;
|
|
161
|
+
translatorForDependency(url: string): MalloyTranslation | undefined;
|
|
152
162
|
importAt(position: DocumentPosition): ImportLocation | undefined;
|
|
153
163
|
metadata(): MetadataResponse;
|
|
154
164
|
modelAnnotation(extendingModel?: ModelDef): ModelAnnotationResponse;
|
|
@@ -188,6 +198,7 @@ export declare class MalloyTranslator extends MalloyTranslation {
|
|
|
188
198
|
private readonly eventStream;
|
|
189
199
|
schemaZone: Zone<SourceDef>;
|
|
190
200
|
importZone: Zone<string>;
|
|
201
|
+
pretranslatedModels: Map<string, ModelDef>;
|
|
191
202
|
sqlQueryZone: Zone<SQLSourceDef>;
|
|
192
203
|
logger: BaseMessageLogger;
|
|
193
204
|
readonly root: MalloyTranslator;
|
|
@@ -199,17 +210,21 @@ interface ErrorData {
|
|
|
199
210
|
tables: Record<string, string>;
|
|
200
211
|
urls: Record<string, string>;
|
|
201
212
|
compileSQL: Record<string, string>;
|
|
213
|
+
translations: Record<string, string>;
|
|
202
214
|
}
|
|
203
215
|
export interface URLData {
|
|
204
216
|
urls: ZoneData<string>;
|
|
205
217
|
}
|
|
218
|
+
export interface ModelData {
|
|
219
|
+
translations: ZoneData<ModelDef>;
|
|
220
|
+
}
|
|
206
221
|
export interface SchemaData {
|
|
207
222
|
tables: ZoneData<SourceDef>;
|
|
208
223
|
}
|
|
209
224
|
export interface SQLSources {
|
|
210
225
|
compileSQL: ZoneData<SQLSourceDef>;
|
|
211
226
|
}
|
|
212
|
-
export interface UpdateData extends URLData, SchemaData, SQLSources {
|
|
227
|
+
export interface UpdateData extends URLData, SchemaData, SQLSources, ModelData {
|
|
213
228
|
errors: Partial<ErrorData>;
|
|
214
229
|
}
|
|
215
230
|
export type ParseUpdate = Partial<UpdateData>;
|
|
@@ -81,17 +81,6 @@ class ParseStep {
|
|
|
81
81
|
if (this.response) {
|
|
82
82
|
return this.response;
|
|
83
83
|
}
|
|
84
|
-
if (that.urlIsFullPath === undefined) {
|
|
85
|
-
try {
|
|
86
|
-
const _checkFull = new URL(that.sourceURL);
|
|
87
|
-
that.urlIsFullPath = true;
|
|
88
|
-
}
|
|
89
|
-
catch (e) {
|
|
90
|
-
const msg = e instanceof Error ? e.message : '';
|
|
91
|
-
that.urlIsFullPath = false;
|
|
92
|
-
that.root.logError('failed-to-compute-absolute-import-url', `Could not compute full path URL: ${msg}`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
84
|
if (!that.urlIsFullPath) {
|
|
96
85
|
return that.fatalResponse();
|
|
97
86
|
}
|
|
@@ -196,6 +185,7 @@ class ImportsAndTablesStep {
|
|
|
196
185
|
this.parseReferences = undefined;
|
|
197
186
|
}
|
|
198
187
|
step(that) {
|
|
188
|
+
var _a;
|
|
199
189
|
const parseReq = this.parseStep.step(that);
|
|
200
190
|
if (parseReq.parse === undefined) {
|
|
201
191
|
return parseReq;
|
|
@@ -248,14 +238,17 @@ class ImportsAndTablesStep {
|
|
|
248
238
|
}
|
|
249
239
|
allMissing = { tables };
|
|
250
240
|
}
|
|
251
|
-
const missingImports = that.root.importZone.getUndefined();
|
|
252
|
-
if (missingImports) {
|
|
241
|
+
const missingImports = ((_a = that.root.importZone.getUndefined()) !== null && _a !== void 0 ? _a : []).filter(url => that.root.pretranslatedModels.get(url) === undefined);
|
|
242
|
+
if (missingImports.length > 0) {
|
|
253
243
|
allMissing = { ...allMissing, urls: missingImports };
|
|
254
244
|
}
|
|
255
245
|
if ((0, translate_response_1.isNeedResponse)(allMissing)) {
|
|
256
246
|
return allMissing;
|
|
257
247
|
}
|
|
258
248
|
for (const child of that.childTranslators.values()) {
|
|
249
|
+
if (that.root.pretranslatedModels.get(child.sourceURL)) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
259
252
|
const kidNeeds = child.importsAndTablesStep.step(child);
|
|
260
253
|
if ((0, translate_response_1.isNeedResponse)(kidNeeds)) {
|
|
261
254
|
return kidNeeds;
|
|
@@ -311,6 +304,9 @@ class ASTStep {
|
|
|
311
304
|
// Now make sure that every child has fully translated itself
|
|
312
305
|
// before this tree is ready to also translate ...
|
|
313
306
|
for (const child of that.childTranslators.values()) {
|
|
307
|
+
if (that.root.pretranslatedModels.get(child.sourceURL)) {
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
314
310
|
const kidNeeds = child.astStep.step(child);
|
|
315
311
|
if ((0, translate_response_1.isNeedResponse)(kidNeeds)) {
|
|
316
312
|
return kidNeeds;
|
|
@@ -460,6 +456,15 @@ class TranslateStep {
|
|
|
460
456
|
if (this.response) {
|
|
461
457
|
return this.response;
|
|
462
458
|
}
|
|
459
|
+
const pretranslate = that.root.pretranslatedModels.get(that.sourceURL);
|
|
460
|
+
if (pretranslate !== undefined) {
|
|
461
|
+
that.modelDef = pretranslate;
|
|
462
|
+
return {
|
|
463
|
+
modelDef: pretranslate,
|
|
464
|
+
final: true,
|
|
465
|
+
fromSources: that.getDependencies(),
|
|
466
|
+
};
|
|
467
|
+
}
|
|
463
468
|
// begin with the compiler flags of the model we are extending
|
|
464
469
|
if (extendingModel && !this.importedAnnotations) {
|
|
465
470
|
const tagParse = tags_1.Tag.annotationToTag(extendingModel.annotation, {
|
|
@@ -487,8 +492,6 @@ class TranslateStep {
|
|
|
487
492
|
}
|
|
488
493
|
else {
|
|
489
494
|
that.modelDef = docCompile.modelDef;
|
|
490
|
-
that.queryList = docCompile.queryList;
|
|
491
|
-
that.sqlBlocks = docCompile.sqlBlocks;
|
|
492
495
|
break;
|
|
493
496
|
}
|
|
494
497
|
}
|
|
@@ -505,10 +508,9 @@ class TranslateStep {
|
|
|
505
508
|
}
|
|
506
509
|
else {
|
|
507
510
|
this.response = {
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
sqlBlocks: that.sqlBlocks,
|
|
511
|
+
modelDef: {
|
|
512
|
+
...that.modelDef,
|
|
513
|
+
dependencies: that.getDependencyTree(),
|
|
512
514
|
},
|
|
513
515
|
fromSources: that.getDependencies(),
|
|
514
516
|
...that.problemResponse(),
|
|
@@ -523,10 +525,10 @@ class MalloyTranslation {
|
|
|
523
525
|
this.sourceURL = sourceURL;
|
|
524
526
|
this.importBaseURL = importBaseURL;
|
|
525
527
|
this.grammarRule = grammarRule;
|
|
526
|
-
this.
|
|
527
|
-
this.sqlBlocks = [];
|
|
528
|
+
this.sqlSources = [];
|
|
528
529
|
this.imports = [];
|
|
529
530
|
this.compilerFlags = new tags_1.Tag();
|
|
531
|
+
this._urlIsFullPath = undefined;
|
|
530
532
|
/*
|
|
531
533
|
Experimental dialect support, not confident this is how this should work.
|
|
532
534
|
|
|
@@ -544,6 +546,8 @@ class MalloyTranslation {
|
|
|
544
546
|
name: sourceURL,
|
|
545
547
|
exports: [],
|
|
546
548
|
contents: {},
|
|
549
|
+
queryList: [],
|
|
550
|
+
dependencies: {},
|
|
547
551
|
};
|
|
548
552
|
/**
|
|
549
553
|
* This is sort of the makefile for the translation, all the steps
|
|
@@ -563,18 +567,59 @@ class MalloyTranslation {
|
|
|
563
567
|
this.translateStep = new TranslateStep(this.astStep);
|
|
564
568
|
this.references = new reference_list_1.ReferenceList(sourceURL);
|
|
565
569
|
}
|
|
570
|
+
get urlIsFullPath() {
|
|
571
|
+
if (this._urlIsFullPath === undefined) {
|
|
572
|
+
try {
|
|
573
|
+
const _checkFull = new URL(this.sourceURL);
|
|
574
|
+
this._urlIsFullPath = true;
|
|
575
|
+
}
|
|
576
|
+
catch (e) {
|
|
577
|
+
const msg = e instanceof Error ? e.message : '';
|
|
578
|
+
this._urlIsFullPath = false;
|
|
579
|
+
this.root.logError('failed-to-compute-absolute-import-url', `Could not compute full path URL: ${msg}`);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return this._urlIsFullPath;
|
|
583
|
+
}
|
|
566
584
|
addChild(url) {
|
|
567
585
|
if (!this.childTranslators.get(url)) {
|
|
568
586
|
this.childTranslators.set(url, new MalloyChildTranslator(url, this.root));
|
|
569
587
|
}
|
|
570
588
|
}
|
|
571
589
|
getDependencies() {
|
|
572
|
-
const dependencies =
|
|
590
|
+
const dependencies = this.getDependencyTree();
|
|
591
|
+
return [this.sourceURL, ...flattenDependencyTree(dependencies)];
|
|
592
|
+
}
|
|
593
|
+
getDependencyTree() {
|
|
594
|
+
const pretranslated = this.root.pretranslatedModels.get(this.sourceURL);
|
|
595
|
+
if (pretranslated !== undefined) {
|
|
596
|
+
return pretranslated.dependencies;
|
|
597
|
+
}
|
|
598
|
+
const dependencies = {};
|
|
573
599
|
for (const [_childURL, child] of this.childTranslators) {
|
|
574
|
-
dependencies
|
|
600
|
+
dependencies[_childURL] = child.getDependencyTree();
|
|
575
601
|
}
|
|
576
602
|
return dependencies;
|
|
577
603
|
}
|
|
604
|
+
newlyTranslatedDependencies() {
|
|
605
|
+
const pretranslated = this.root.pretranslatedModels.get(this.sourceURL);
|
|
606
|
+
if (pretranslated !== undefined) {
|
|
607
|
+
return [];
|
|
608
|
+
}
|
|
609
|
+
const newModels = [];
|
|
610
|
+
for (const [url, child] of this.childTranslators) {
|
|
611
|
+
const pretranslated = this.root.pretranslatedModels.get(url);
|
|
612
|
+
if (pretranslated !== undefined) {
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
const result = child.translate();
|
|
616
|
+
if (result.modelDef) {
|
|
617
|
+
newModels.push({ url, modelDef: result.modelDef });
|
|
618
|
+
newModels.push(...child.newlyTranslatedDependencies());
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
return newModels;
|
|
622
|
+
}
|
|
578
623
|
addReference(reference) {
|
|
579
624
|
this.references.add(reference);
|
|
580
625
|
}
|
|
@@ -677,7 +722,7 @@ class MalloyTranslation {
|
|
|
677
722
|
const child = this.childTranslators.get(childURL);
|
|
678
723
|
if (child) {
|
|
679
724
|
const did = child.translate();
|
|
680
|
-
if (did.
|
|
725
|
+
if (did.modelDef) {
|
|
681
726
|
for (const fromChild of child.modelDef.exports) {
|
|
682
727
|
const modelEntry = child.modelDef.contents[fromChild];
|
|
683
728
|
if ((0, malloy_types_1.isSourceDef)(modelEntry) || modelEntry.type === 'query') {
|
|
@@ -699,6 +744,9 @@ class MalloyTranslation {
|
|
|
699
744
|
}
|
|
700
745
|
return attempt;
|
|
701
746
|
}
|
|
747
|
+
translatorForDependency(url) {
|
|
748
|
+
return this.childTranslators.get(url);
|
|
749
|
+
}
|
|
702
750
|
importAt(position) {
|
|
703
751
|
// Here we assume that imports DO NOT overlap. And then we do a linear
|
|
704
752
|
// search to find the one we're looking for.
|
|
@@ -812,6 +860,7 @@ class MalloyTranslator extends MalloyTranslation {
|
|
|
812
860
|
this.eventStream = eventStream;
|
|
813
861
|
this.schemaZone = new zone_1.Zone();
|
|
814
862
|
this.importZone = new zone_1.Zone();
|
|
863
|
+
this.pretranslatedModels = new Map();
|
|
815
864
|
this.sqlQueryZone = new zone_1.Zone();
|
|
816
865
|
this.root = this;
|
|
817
866
|
this.logger = new parse_log_1.BaseMessageLogger(eventStream);
|
|
@@ -824,6 +873,9 @@ class MalloyTranslator extends MalloyTranslation {
|
|
|
824
873
|
this.schemaZone.updateFrom(dd.tables, (_a = dd.errors) === null || _a === void 0 ? void 0 : _a.tables);
|
|
825
874
|
this.importZone.updateFrom(dd.urls, (_b = dd.errors) === null || _b === void 0 ? void 0 : _b.urls);
|
|
826
875
|
this.sqlQueryZone.updateFrom(dd.compileSQL, (_c = dd.errors) === null || _c === void 0 ? void 0 : _c.compileSQL);
|
|
876
|
+
for (const url in dd.translations) {
|
|
877
|
+
this.pretranslatedModels.set(url, dd.translations[url]);
|
|
878
|
+
}
|
|
827
879
|
}
|
|
828
880
|
logError(code, parameters, options) {
|
|
829
881
|
this.logger.log((0, parse_log_1.makeLogMessage)(code, parameters, { severity: 'error', ...options }));
|
|
@@ -851,4 +903,14 @@ class MalloyParserErrorHandler {
|
|
|
851
903
|
}
|
|
852
904
|
}
|
|
853
905
|
exports.MalloyParserErrorHandler = MalloyParserErrorHandler;
|
|
906
|
+
function flattenDependencyTree(dependencies) {
|
|
907
|
+
return [
|
|
908
|
+
...Object.keys(dependencies),
|
|
909
|
+
...Object.keys(dependencies)
|
|
910
|
+
.map(dependency => {
|
|
911
|
+
return flattenDependencyTree(dependencies[dependency]);
|
|
912
|
+
})
|
|
913
|
+
.flat(),
|
|
914
|
+
];
|
|
915
|
+
}
|
|
854
916
|
//# sourceMappingURL=parse-malloy.js.map
|
|
@@ -228,9 +228,9 @@ describe('document annotation', () => {
|
|
|
228
228
|
## model2
|
|
229
229
|
`);
|
|
230
230
|
expect(m).toTranslate();
|
|
231
|
-
const model = (_a = m.translate()) === null || _a === void 0 ? void 0 : _a.
|
|
231
|
+
const model = (_a = m.translate()) === null || _a === void 0 ? void 0 : _a.modelDef;
|
|
232
232
|
expect(model).toBeDefined();
|
|
233
|
-
const notes = model === null || model === void 0 ? void 0 : model.
|
|
233
|
+
const notes = model === null || model === void 0 ? void 0 : model.annotation;
|
|
234
234
|
expect(notes).matchesAnnotation({ notes: ['## model1\n', '## model2\n'] });
|
|
235
235
|
});
|
|
236
236
|
test('ignores objectless object annotations', () => {
|
|
@@ -253,14 +253,14 @@ describe('document annotation', () => {
|
|
|
253
253
|
expect(m.translator.compilerFlags.has('flagThis')).toBeTruthy();
|
|
254
254
|
});
|
|
255
255
|
test('extended models inherit model flags', () => {
|
|
256
|
-
var _a, _b
|
|
256
|
+
var _a, _b;
|
|
257
257
|
const first = (0, test_translator_1.model) `## from=1\n`;
|
|
258
258
|
expect(first).toTranslate();
|
|
259
|
-
const firstModel = (
|
|
259
|
+
const firstModel = (_a = first.translator.translate()) === null || _a === void 0 ? void 0 : _a.modelDef;
|
|
260
260
|
expect(firstModel).toBeDefined();
|
|
261
261
|
const second = (0, test_translator_1.model) `## from=2\n`;
|
|
262
262
|
second.translator.internalModel = firstModel;
|
|
263
|
-
const secondModel = (
|
|
263
|
+
const secondModel = (_b = second.translator.translate()) === null || _b === void 0 ? void 0 : _b.modelDef;
|
|
264
264
|
expect(secondModel === null || secondModel === void 0 ? void 0 : secondModel.annotation).matchesAnnotation({
|
|
265
265
|
inherits: { notes: ['## from=1\n'] },
|
|
266
266
|
notes: ['## from=2\n'],
|
|
@@ -222,8 +222,8 @@ describe('expressions', () => {
|
|
|
222
222
|
test('x is expr y is not null', () => {
|
|
223
223
|
const isNullSrc = (0, test_translator_1.model) `source: xa is a extend { dimension: x is 1 y is not null }`;
|
|
224
224
|
expect(isNullSrc).toTranslate();
|
|
225
|
-
const xaModel = isNullSrc.translator.translate().
|
|
226
|
-
const xa = (0, test_translator_1.getExplore)(xaModel
|
|
225
|
+
const xaModel = isNullSrc.translator.translate().modelDef;
|
|
226
|
+
const xa = (0, test_translator_1.getExplore)(xaModel, 'xa');
|
|
227
227
|
const x = (0, test_translator_1.getFieldDef)(xa, 'x');
|
|
228
228
|
expect(x).toMatchObject({ e: { node: 'numberLiteral' } });
|
|
229
229
|
const y = (0, test_translator_1.getFieldDef)(xa, 'y');
|
|
@@ -31,6 +31,7 @@ const test_translator_1 = require("./test-translator");
|
|
|
31
31
|
const escapeRegExp_1 = __importDefault(require("lodash/escapeRegExp"));
|
|
32
32
|
describe('import:', () => {
|
|
33
33
|
test('simple source', () => {
|
|
34
|
+
var _a;
|
|
34
35
|
const docParse = new test_translator_1.TestTranslator('import "child"');
|
|
35
36
|
const xr = docParse.unresolved();
|
|
36
37
|
expect(docParse).toParse();
|
|
@@ -41,8 +42,12 @@ describe('import:', () => {
|
|
|
41
42
|
expect(docParse).toTranslate();
|
|
42
43
|
const aa = docParse.getSourceDef('aa');
|
|
43
44
|
expect(aa).toBeDefined();
|
|
45
|
+
expect((_a = docParse.translate().modelDef) === null || _a === void 0 ? void 0 : _a.dependencies).toMatchObject({
|
|
46
|
+
'internal://test/langtests/child': {},
|
|
47
|
+
});
|
|
44
48
|
});
|
|
45
49
|
test('simple source with importBaseURL', () => {
|
|
50
|
+
var _a;
|
|
46
51
|
const docParse = new test_translator_1.TestTranslator('import "child"', 'http://example.com/');
|
|
47
52
|
const xr = docParse.unresolved();
|
|
48
53
|
expect(docParse).toParse();
|
|
@@ -53,8 +58,12 @@ describe('import:', () => {
|
|
|
53
58
|
expect(docParse).toTranslate();
|
|
54
59
|
const aa = docParse.getSourceDef('aa');
|
|
55
60
|
expect(aa).toBeDefined();
|
|
61
|
+
expect((_a = docParse.translate().modelDef) === null || _a === void 0 ? void 0 : _a.dependencies).toMatchObject({
|
|
62
|
+
'http://example.com/child': {},
|
|
63
|
+
});
|
|
56
64
|
});
|
|
57
65
|
test('simple query', () => {
|
|
66
|
+
var _a;
|
|
58
67
|
const docParse = new test_translator_1.TestTranslator('import "child"');
|
|
59
68
|
const xr = docParse.unresolved();
|
|
60
69
|
expect(docParse).toParse();
|
|
@@ -67,6 +76,9 @@ describe('import:', () => {
|
|
|
67
76
|
expect(docParse).toTranslate();
|
|
68
77
|
const aq = docParse.getQuery('aq');
|
|
69
78
|
expect(aq).toBeDefined();
|
|
79
|
+
expect((_a = docParse.translate().modelDef) === null || _a === void 0 ? void 0 : _a.dependencies).toMatchObject({
|
|
80
|
+
'internal://test/langtests/child': {},
|
|
81
|
+
});
|
|
70
82
|
});
|
|
71
83
|
test('query based source with named structref', () => {
|
|
72
84
|
const docParse = new test_translator_1.TestTranslator(`
|
|
@@ -115,6 +127,7 @@ source: botProjQSrc is botProjQ
|
|
|
115
127
|
expect(docParse).toLog((0, test_translator_1.errorMessage)(new RegExp((0, escapeRegExp_1.default)(reportedError))));
|
|
116
128
|
});
|
|
117
129
|
test('chained imports', () => {
|
|
130
|
+
var _a, _b;
|
|
118
131
|
const docParse = new test_translator_1.TestTranslator('import "child"');
|
|
119
132
|
docParse.update({
|
|
120
133
|
urls: { 'internal://test/langtests/child': 'import "grandChild"' },
|
|
@@ -126,12 +139,27 @@ source: botProjQSrc is botProjQ
|
|
|
126
139
|
urls: { 'internal://test/langtests/grandChild': '// empty file' },
|
|
127
140
|
});
|
|
128
141
|
expect(docParse).toTranslate();
|
|
129
|
-
const
|
|
142
|
+
const translated = docParse.translate();
|
|
143
|
+
const sources = translated.fromSources;
|
|
130
144
|
expect(sources).toEqual([
|
|
131
145
|
'internal://test/langtests/root.malloy',
|
|
132
146
|
'internal://test/langtests/child',
|
|
133
147
|
'internal://test/langtests/grandChild',
|
|
134
148
|
]);
|
|
149
|
+
expect((_a = translated.modelDef) === null || _a === void 0 ? void 0 : _a.dependencies).toMatchObject({
|
|
150
|
+
'internal://test/langtests/child': {
|
|
151
|
+
'internal://test/langtests/grandChild': {},
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
const newDependencies = docParse.newlyTranslatedDependencies();
|
|
155
|
+
expect(newDependencies).toMatchObject([
|
|
156
|
+
{ url: 'internal://test/langtests/child', modelDef: {} },
|
|
157
|
+
{ url: 'internal://test/langtests/grandChild', modelDef: {} },
|
|
158
|
+
]);
|
|
159
|
+
const child = docParse.translatorForDependency('internal://test/langtests/child');
|
|
160
|
+
expect((_b = child.translate().modelDef) === null || _b === void 0 ? void 0 : _b.dependencies).toMatchObject({
|
|
161
|
+
'internal://test/langtests/grandChild': {},
|
|
162
|
+
});
|
|
135
163
|
});
|
|
136
164
|
test('relative imports', () => {
|
|
137
165
|
const docParse = new test_translator_1.TestTranslator('import "../parent.malloy"');
|
|
@@ -343,7 +343,7 @@ function checkForProblems(context, expectCompiles, s, ...msgs) {
|
|
|
343
343
|
emsg += `\nSource:\n${src}`;
|
|
344
344
|
m.compile();
|
|
345
345
|
const t = m.translate();
|
|
346
|
-
if (t.
|
|
346
|
+
if (t.modelDef && !expectCompiles) {
|
|
347
347
|
return { pass: false, message: () => emsg };
|
|
348
348
|
}
|
|
349
349
|
else if (t.problems === undefined) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './parse-expects';
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
require("./parse-expects");
|
|
10
|
+
const test_translator_1 = require("./test-translator");
|
|
11
|
+
describe('pretranslated models', () => {
|
|
12
|
+
test('import of pretranslated', () => {
|
|
13
|
+
var _a, _b;
|
|
14
|
+
const docParse = new test_translator_1.TestTranslator('import "child"');
|
|
15
|
+
const xr = docParse.unresolved();
|
|
16
|
+
expect(docParse).toParse();
|
|
17
|
+
expect(xr).toEqual({ urls: ['internal://test/langtests/child'] });
|
|
18
|
+
docParse.update({
|
|
19
|
+
translations: {
|
|
20
|
+
'internal://test/langtests/child': {
|
|
21
|
+
name: 'child',
|
|
22
|
+
exports: ['foo'],
|
|
23
|
+
queryList: [],
|
|
24
|
+
contents: {
|
|
25
|
+
foo: {
|
|
26
|
+
type: 'table',
|
|
27
|
+
tablePath: 'foo',
|
|
28
|
+
connection: 'duckdb',
|
|
29
|
+
dialect: 'duckdb',
|
|
30
|
+
name: 'foo',
|
|
31
|
+
fields: [],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
dependencies: {
|
|
35
|
+
'internal://test/langtests/grandchild': {
|
|
36
|
+
'internal://test/langtests/grandgrandchild1': {},
|
|
37
|
+
'internal://test/langtests/grandgrandchild2': {},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
expect(docParse).toTranslate();
|
|
44
|
+
const foo = docParse.getSourceDef('foo');
|
|
45
|
+
expect(foo).toBeDefined();
|
|
46
|
+
const translated = docParse.translate();
|
|
47
|
+
expect((_a = translated.modelDef) === null || _a === void 0 ? void 0 : _a.dependencies).toMatchObject({
|
|
48
|
+
'internal://test/langtests/child': {
|
|
49
|
+
'internal://test/langtests/grandchild': {
|
|
50
|
+
'internal://test/langtests/grandgrandchild1': {},
|
|
51
|
+
'internal://test/langtests/grandgrandchild2': {},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
const newDependencies = docParse.newlyTranslatedDependencies();
|
|
56
|
+
expect(newDependencies).toMatchObject([]);
|
|
57
|
+
expect(translated.fromSources).toEqual([
|
|
58
|
+
'internal://test/langtests/root.malloy',
|
|
59
|
+
'internal://test/langtests/child',
|
|
60
|
+
'internal://test/langtests/grandchild',
|
|
61
|
+
'internal://test/langtests/grandgrandchild1',
|
|
62
|
+
'internal://test/langtests/grandgrandchild2',
|
|
63
|
+
]);
|
|
64
|
+
const child = docParse.translatorForDependency('internal://test/langtests/child');
|
|
65
|
+
const childTranslated = child.translate();
|
|
66
|
+
expect((_b = childTranslated.modelDef) === null || _b === void 0 ? void 0 : _b.dependencies).toMatchObject({
|
|
67
|
+
'internal://test/langtests/grandchild': {
|
|
68
|
+
'internal://test/langtests/grandgrandchild1': {},
|
|
69
|
+
'internal://test/langtests/grandgrandchild2': {},
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
expect(childTranslated.fromSources).toEqual([
|
|
73
|
+
'internal://test/langtests/child',
|
|
74
|
+
'internal://test/langtests/grandchild',
|
|
75
|
+
'internal://test/langtests/grandgrandchild1',
|
|
76
|
+
'internal://test/langtests/grandgrandchild2',
|
|
77
|
+
]);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=pretranslate.spec.js.map
|
|
@@ -985,8 +985,8 @@ describe('query:', () => {
|
|
|
985
985
|
`);
|
|
986
986
|
expect(m).toTranslate();
|
|
987
987
|
const t = m.translate();
|
|
988
|
-
if (t.
|
|
989
|
-
const q = t.
|
|
988
|
+
if (t.modelDef) {
|
|
989
|
+
const q = t.modelDef.queryList[0].pipeline[0];
|
|
990
990
|
expect(q).toBeDefined();
|
|
991
991
|
if (q.type === 'reduce' && q.extendSource) {
|
|
992
992
|
expect(q.extendSource.length).toBe(1);
|
|
@@ -1010,8 +1010,8 @@ describe('query:', () => {
|
|
|
1010
1010
|
`);
|
|
1011
1011
|
expect(m).toTranslate();
|
|
1012
1012
|
const t = m.translate();
|
|
1013
|
-
if (t.
|
|
1014
|
-
const q = t.
|
|
1013
|
+
if (t.modelDef) {
|
|
1014
|
+
const q = t.modelDef.queryList[0].pipeline[0];
|
|
1015
1015
|
if (q.type === 'reduce' && q.extendSource) {
|
|
1016
1016
|
expect(q.extendSource.length).toBe(1);
|
|
1017
1017
|
const f = q.extendSource[0];
|
|
@@ -1034,8 +1034,8 @@ describe('query:', () => {
|
|
|
1034
1034
|
`);
|
|
1035
1035
|
expect(m).toTranslate();
|
|
1036
1036
|
const t = m.translate();
|
|
1037
|
-
if (t.
|
|
1038
|
-
const q = t.
|
|
1037
|
+
if (t.modelDef) {
|
|
1038
|
+
const q = t.modelDef.queryList[0].pipeline[0];
|
|
1039
1039
|
if (q.type === 'reduce' && q.extendSource) {
|
|
1040
1040
|
expect(q.extendSource.length).toBe(1);
|
|
1041
1041
|
expect((0, model_1.isJoined)(q.extendSource[0])).toBeTruthy();
|
|
@@ -127,7 +127,7 @@ describe('connection sql()', () => {
|
|
|
127
127
|
expect(m).toParse();
|
|
128
128
|
});
|
|
129
129
|
test('source from extended sql-based-source', () => {
|
|
130
|
-
var _a
|
|
130
|
+
var _a;
|
|
131
131
|
const model = new test_translator_1.TestTranslator(`
|
|
132
132
|
source: sql_block is aConnection.sql("""${selStmt}""")
|
|
133
133
|
source: malloy_source is sql_block extend { primary_key: ai }
|
|
@@ -135,14 +135,14 @@ describe('connection sql()', () => {
|
|
|
135
135
|
const sql = (0, sql_block_1.makeSQLSentence)([{ sql: selStmt }], 'aConnection');
|
|
136
136
|
model.update({ compileSQL: { [sql.name]: makeSchemaResponse(sql) } });
|
|
137
137
|
expect(model).toTranslate();
|
|
138
|
-
const modelDef = (
|
|
138
|
+
const modelDef = (_a = model === null || model === void 0 ? void 0 : model.translate()) === null || _a === void 0 ? void 0 : _a.modelDef;
|
|
139
139
|
// this tests the underlying api that .extendModel calls
|
|
140
140
|
const extModel = new parse_malloy_1.MalloyTranslator('sqlblocktest://main');
|
|
141
141
|
extModel.importZone.define('sqlblocktest://main', 'run: malloy_source -> { select: * }');
|
|
142
142
|
const tr = extModel.translate(modelDef);
|
|
143
143
|
// because extModel is not a TestTranslator we can't use the hotness
|
|
144
144
|
expect(tr.problems).toEqual([]);
|
|
145
|
-
expect(tr.
|
|
145
|
+
expect(tr.modelDef).toBeDefined();
|
|
146
146
|
});
|
|
147
147
|
});
|
|
148
148
|
//# sourceMappingURL=sql-block.spec.js.map
|
|
@@ -241,6 +241,8 @@ class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
|
241
241
|
this.internalModel = {
|
|
242
242
|
name: testURI,
|
|
243
243
|
exports: [],
|
|
244
|
+
queryList: [],
|
|
245
|
+
dependencies: {},
|
|
244
246
|
contents: {
|
|
245
247
|
_db_: { type: 'connection', name: '_db_' },
|
|
246
248
|
a: { ...exports.aTableDef, primaryKey: 'astr', as: 'a' },
|
|
@@ -341,7 +343,7 @@ class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
|
341
343
|
get nameSpace() {
|
|
342
344
|
var _a;
|
|
343
345
|
const gotModel = this.translate();
|
|
344
|
-
return ((_a = gotModel === null || gotModel === void 0 ? void 0 : gotModel.
|
|
346
|
+
return ((_a = gotModel === null || gotModel === void 0 ? void 0 : gotModel.modelDef) === null || _a === void 0 ? void 0 : _a.contents) || {};
|
|
345
347
|
}
|
|
346
348
|
exploreFor(exploreName) {
|
|
347
349
|
const explore = this.nameSpace[exploreName];
|
|
@@ -352,9 +354,8 @@ class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
|
352
354
|
}
|
|
353
355
|
compile() {
|
|
354
356
|
const compileTo = this.translate();
|
|
355
|
-
if (compileTo.
|
|
356
|
-
console.log('MODEL: ', pretty(compileTo.
|
|
357
|
-
console.log('QUERIES: ', pretty(compileTo.translated.queryList));
|
|
357
|
+
if (compileTo.modelDef && TestTranslator.inspectCompile) {
|
|
358
|
+
console.log('MODEL: ', pretty(compileTo.modelDef));
|
|
358
359
|
}
|
|
359
360
|
// All the stuff to ask the ast for a translation is already in TestTranslator
|
|
360
361
|
}
|
|
@@ -362,19 +363,18 @@ class TestTranslator extends parse_malloy_1.MalloyTranslator {
|
|
|
362
363
|
return this.importsAndTablesStep.step(this);
|
|
363
364
|
}
|
|
364
365
|
getSourceDef(srcName) {
|
|
365
|
-
|
|
366
|
-
const
|
|
367
|
-
const s = (_a = t === null || t === void 0 ? void 0 : t.modelDef) === null || _a === void 0 ? void 0 : _a.contents[srcName];
|
|
366
|
+
const t = this.translate().modelDef;
|
|
367
|
+
const s = t === null || t === void 0 ? void 0 : t.contents[srcName];
|
|
368
368
|
if (s && (0, malloy_types_1.isSourceDef)(s)) {
|
|
369
369
|
return s;
|
|
370
370
|
}
|
|
371
371
|
return undefined;
|
|
372
372
|
}
|
|
373
373
|
getQuery(queryName) {
|
|
374
|
-
const t = this.translate().
|
|
374
|
+
const t = this.translate().modelDef;
|
|
375
375
|
if (t) {
|
|
376
376
|
const s = typeof queryName === 'string'
|
|
377
|
-
? t.
|
|
377
|
+
? t.contents[queryName]
|
|
378
378
|
: t.queryList[queryName];
|
|
379
379
|
if ((s === null || s === void 0 ? void 0 : s.type) === 'query') {
|
|
380
380
|
return s;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Annotation, ModelDef,
|
|
1
|
+
import { Annotation, ModelDef, SQLSentence } from '../model/malloy_types';
|
|
2
2
|
import { MalloyElement } from './ast';
|
|
3
3
|
import { LogMessage } from './parse-log';
|
|
4
4
|
import { DocumentSymbol } from './parse-tree-walkers/document-symbol-walker';
|
|
@@ -55,11 +55,7 @@ interface HelpContext extends NeededData, ProblemResponse, FinalResponse {
|
|
|
55
55
|
}
|
|
56
56
|
export type HelpContextResponse = Partial<HelpContext>;
|
|
57
57
|
interface TranslatedResponseData extends NeededData, ProblemResponse, FinalResponse {
|
|
58
|
-
|
|
59
|
-
modelDef: ModelDef;
|
|
60
|
-
queryList: Query[];
|
|
61
|
-
sqlBlocks: SQLSourceDef[];
|
|
62
|
-
};
|
|
58
|
+
modelDef: ModelDef;
|
|
63
59
|
fromSources: string[];
|
|
64
60
|
}
|
|
65
61
|
interface TablePath extends NeededData, ProblemResponse, FinalResponse {
|
package/dist/malloy.d.ts
CHANGED
|
@@ -165,12 +165,11 @@ export declare class MalloyError extends Error {
|
|
|
165
165
|
*/
|
|
166
166
|
export declare class Model implements Taggable {
|
|
167
167
|
private modelDef;
|
|
168
|
-
private queryList;
|
|
169
168
|
readonly problems: LogMessage[];
|
|
170
169
|
readonly fromSources: string[];
|
|
171
170
|
_referenceAt: (location: ModelDocumentPosition) => DocumentReference | undefined;
|
|
172
171
|
_importAt: (location: ModelDocumentPosition) => ImportLocation | undefined;
|
|
173
|
-
constructor(modelDef: ModelDef,
|
|
172
|
+
constructor(modelDef: ModelDef, problems: LogMessage[], fromSources: string[], referenceAt?: (location: ModelDocumentPosition) => DocumentReference | undefined, importAt?: (location: ModelDocumentPosition) => ImportLocation | undefined);
|
|
174
173
|
tagParse(spec?: TagParseSpec): TagParse;
|
|
175
174
|
getTaglines(prefix?: RegExp): string[];
|
|
176
175
|
/**
|
package/dist/malloy.js
CHANGED
|
@@ -87,17 +87,19 @@ class Malloy {
|
|
|
87
87
|
for (;;) {
|
|
88
88
|
const result = translator.translate(model === null || model === void 0 ? void 0 : model._modelDef);
|
|
89
89
|
if (result.final) {
|
|
90
|
-
if (result.
|
|
91
|
-
return new Model(result.
|
|
90
|
+
if (result.modelDef) {
|
|
91
|
+
return new Model(result.modelDef, result.problems || [], [...((_a = model === null || model === void 0 ? void 0 : model.fromSources) !== null && _a !== void 0 ? _a : []), ...((_b = result.fromSources) !== null && _b !== void 0 ? _b : [])], (position) => translator.referenceAt(position), (position) => translator.importAt(position));
|
|
92
92
|
}
|
|
93
93
|
else if (noThrowOnError) {
|
|
94
94
|
const emptyModel = {
|
|
95
95
|
name: 'modelDidNotCompile',
|
|
96
96
|
exports: [],
|
|
97
97
|
contents: {},
|
|
98
|
+
dependencies: {},
|
|
99
|
+
queryList: [],
|
|
98
100
|
};
|
|
99
101
|
const modelFromCompile = (model === null || model === void 0 ? void 0 : model._modelDef) || emptyModel;
|
|
100
|
-
return new Model(modelFromCompile,
|
|
102
|
+
return new Model(modelFromCompile, result.problems || [], [...((_c = model === null || model === void 0 ? void 0 : model.fromSources) !== null && _c !== void 0 ? _c : []), ...((_d = result.fromSources) !== null && _d !== void 0 ? _d : [])], (position) => translator.referenceAt(position), (position) => translator.importAt(position));
|
|
101
103
|
}
|
|
102
104
|
else {
|
|
103
105
|
const errors = result.problems || [];
|
|
@@ -273,6 +275,8 @@ class Malloy {
|
|
|
273
275
|
name: 'empty_model',
|
|
274
276
|
exports: [],
|
|
275
277
|
contents: {},
|
|
278
|
+
queryList: [],
|
|
279
|
+
dependencies: {},
|
|
276
280
|
});
|
|
277
281
|
}
|
|
278
282
|
else if (preparedResult) {
|
|
@@ -358,9 +362,8 @@ exports.MalloyError = MalloyError;
|
|
|
358
362
|
* A compiled Malloy document.
|
|
359
363
|
*/
|
|
360
364
|
class Model {
|
|
361
|
-
constructor(modelDef,
|
|
365
|
+
constructor(modelDef, problems, fromSources, referenceAt = () => undefined, importAt = () => undefined) {
|
|
362
366
|
this.modelDef = modelDef;
|
|
363
|
-
this.queryList = queryList;
|
|
364
367
|
this.problems = problems;
|
|
365
368
|
this.fromSources = fromSources;
|
|
366
369
|
this._referenceAt = referenceAt;
|
|
@@ -415,10 +418,10 @@ class Model {
|
|
|
415
418
|
if (index < 0) {
|
|
416
419
|
throw new Error(`Invalid index ${index}.`);
|
|
417
420
|
}
|
|
418
|
-
else if (index >= this.queryList.length) {
|
|
421
|
+
else if (index >= this.modelDef.queryList.length) {
|
|
419
422
|
throw new Error(`Query index ${index} is out of bounds.`);
|
|
420
423
|
}
|
|
421
|
-
return new PreparedQuery(this.queryList[index], this.modelDef, this.problems);
|
|
424
|
+
return new PreparedQuery(this.modelDef.queryList[index], this.modelDef, this.problems);
|
|
422
425
|
}
|
|
423
426
|
/**
|
|
424
427
|
* Retrieve a prepared query for the final unnamed query at the top level of a model.
|
|
@@ -434,10 +437,10 @@ class Model {
|
|
|
434
437
|
* @return A prepared query.
|
|
435
438
|
*/
|
|
436
439
|
getPreparedQuery() {
|
|
437
|
-
if (this.queryList.length === 0) {
|
|
440
|
+
if (this.modelDef.queryList.length === 0) {
|
|
438
441
|
throw new Error('Model has no queries.');
|
|
439
442
|
}
|
|
440
|
-
return new PreparedQuery(this.queryList[this.queryList.length - 1], this.modelDef, this.problems);
|
|
443
|
+
return new PreparedQuery(this.modelDef.queryList[this.modelDef.queryList.length - 1], this.modelDef, this.problems);
|
|
441
444
|
}
|
|
442
445
|
/**
|
|
443
446
|
* Retrieve an `Explore` from the model by name.
|
|
@@ -1032,10 +1035,12 @@ class Explore extends Entity {
|
|
|
1032
1035
|
name: 'generated_model',
|
|
1033
1036
|
exports: [],
|
|
1034
1037
|
contents: { [this.structDef.name]: this.structDef },
|
|
1038
|
+
queryList: [],
|
|
1039
|
+
dependencies: {},
|
|
1035
1040
|
};
|
|
1036
1041
|
}
|
|
1037
1042
|
getSingleExploreModel() {
|
|
1038
|
-
return new Model(this.modelDef, [], []
|
|
1043
|
+
return new Model(this.modelDef, [], []);
|
|
1039
1044
|
}
|
|
1040
1045
|
get fieldMap() {
|
|
1041
1046
|
var _a;
|
|
@@ -1652,7 +1657,7 @@ class Runtime {
|
|
|
1652
1657
|
// be used in tests.
|
|
1653
1658
|
_loadModelFromModelDef(modelDef, options) {
|
|
1654
1659
|
return new ModelMaterializer(this, async () => {
|
|
1655
|
-
return new Model(modelDef, [], []
|
|
1660
|
+
return new Model(modelDef, [], []);
|
|
1656
1661
|
}, options);
|
|
1657
1662
|
}
|
|
1658
1663
|
/**
|
|
@@ -748,12 +748,17 @@ export type TypedDef = AtomicTypeDef | JoinFieldDef | TurtleDef | RefToField | S
|
|
|
748
748
|
/** Get the output name for a NamedObject */
|
|
749
749
|
export declare function getIdentifier(n: AliasedName): string;
|
|
750
750
|
export type NamedModelObject = SourceDef | NamedQuery | FunctionDef | ConnectionDef;
|
|
751
|
+
export interface DependencyTree {
|
|
752
|
+
[url: string]: DependencyTree;
|
|
753
|
+
}
|
|
751
754
|
/** Result of parsing a model file */
|
|
752
755
|
export interface ModelDef {
|
|
753
756
|
name: string;
|
|
754
757
|
exports: string[];
|
|
755
758
|
contents: Record<string, NamedModelObject>;
|
|
756
759
|
annotation?: ModelAnnotation;
|
|
760
|
+
queryList: Query[];
|
|
761
|
+
dependencies: DependencyTree;
|
|
757
762
|
}
|
|
758
763
|
/** Very common record type */
|
|
759
764
|
export type NamedSourceDefs = Record<string, SourceDef>;
|