@zenstackhq/language 3.0.0-beta.1 → 3.0.0-beta.10
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/index.cjs +430 -264
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -20
- package/dist/index.d.ts +19 -20
- package/dist/index.js +382 -218
- package/dist/index.js.map +1 -1
- package/dist/utils.cjs +104 -26
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +5 -5
- package/dist/utils.d.ts +5 -5
- package/dist/utils.js +98 -21
- package/dist/utils.js.map +1 -1
- package/package.json +8 -6
- package/res/stdlib.zmodel +26 -56
package/dist/index.js
CHANGED
|
@@ -7,12 +7,11 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
7
7
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
// src/
|
|
11
|
-
import { isAstNode, URI as
|
|
12
|
-
import { NodeFileSystem } from "langium/node";
|
|
10
|
+
// src/document.ts
|
|
11
|
+
import { isAstNode, URI as URI4 } from "langium";
|
|
13
12
|
import fs3 from "fs";
|
|
14
|
-
import
|
|
15
|
-
import { fileURLToPath as
|
|
13
|
+
import path4 from "path";
|
|
14
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
16
15
|
|
|
17
16
|
// src/generated/ast.ts
|
|
18
17
|
import * as langium from "langium";
|
|
@@ -1042,8 +1041,11 @@ var ExpressionContext = /* @__PURE__ */ function(ExpressionContext2) {
|
|
|
1042
1041
|
}({});
|
|
1043
1042
|
|
|
1044
1043
|
// src/module.ts
|
|
1045
|
-
import { inject } from "langium";
|
|
1044
|
+
import { DocumentState as DocumentState2, inject, URI as URI3 } from "langium";
|
|
1046
1045
|
import { createDefaultModule, createDefaultSharedModule } from "langium/lsp";
|
|
1046
|
+
import { NodeFileSystem } from "langium/node";
|
|
1047
|
+
import path3 from "path";
|
|
1048
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
1047
1049
|
|
|
1048
1050
|
// src/generated/grammar.ts
|
|
1049
1051
|
import { loadGrammarFromJson } from "langium";
|
|
@@ -5104,15 +5106,12 @@ var ZModelGeneratedModule = {
|
|
|
5104
5106
|
parser: {}
|
|
5105
5107
|
};
|
|
5106
5108
|
|
|
5107
|
-
// src/validators/attribute-application-validator.ts
|
|
5108
|
-
import { AstUtils as AstUtils2 } from "langium";
|
|
5109
|
-
import pluralize from "pluralize";
|
|
5110
|
-
|
|
5111
5109
|
// src/utils.ts
|
|
5112
|
-
import { invariant } from "@zenstackhq/common-helpers";
|
|
5113
5110
|
import { AstUtils, URI } from "langium";
|
|
5114
5111
|
import fs from "fs";
|
|
5112
|
+
import { createRequire } from "module";
|
|
5115
5113
|
import path from "path";
|
|
5114
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
5116
5115
|
function hasAttribute(decl, name) {
|
|
5117
5116
|
return !!getAttribute(decl, name);
|
|
5118
5117
|
}
|
|
@@ -5192,10 +5191,6 @@ function isRelationshipField(field) {
|
|
|
5192
5191
|
return isDataModel(field.type.reference?.ref);
|
|
5193
5192
|
}
|
|
5194
5193
|
__name(isRelationshipField, "isRelationshipField");
|
|
5195
|
-
function isFutureExpr(node) {
|
|
5196
|
-
return isInvocationExpr(node) && node.function.ref?.name === "future" && isFromStdlib(node.function.ref);
|
|
5197
|
-
}
|
|
5198
|
-
__name(isFutureExpr, "isFutureExpr");
|
|
5199
5194
|
function isDelegateModel(node) {
|
|
5200
5195
|
return isDataModel(node) && hasAttribute(node, "@@delegate");
|
|
5201
5196
|
}
|
|
@@ -5213,8 +5208,14 @@ function getRecursiveBases(decl, includeDelegate = true, seen = /* @__PURE__ */
|
|
|
5213
5208
|
return result;
|
|
5214
5209
|
}
|
|
5215
5210
|
seen.add(decl);
|
|
5216
|
-
|
|
5217
|
-
|
|
5211
|
+
const bases = [
|
|
5212
|
+
...decl.mixins,
|
|
5213
|
+
...isDataModel(decl) && decl.baseModel ? [
|
|
5214
|
+
decl.baseModel
|
|
5215
|
+
] : []
|
|
5216
|
+
];
|
|
5217
|
+
bases.forEach((base) => {
|
|
5218
|
+
const baseDecl = decl.$container.declarations.find((d) => isTypeDef(d) || isDataModel(d) && d.name === base.$refText);
|
|
5218
5219
|
if (baseDecl) {
|
|
5219
5220
|
if (!includeDelegate && isDelegateModel(baseDecl)) {
|
|
5220
5221
|
return;
|
|
@@ -5354,7 +5355,7 @@ function getFunctionExpressionContext(funcDecl) {
|
|
|
5354
5355
|
}
|
|
5355
5356
|
__name(getFunctionExpressionContext, "getFunctionExpressionContext");
|
|
5356
5357
|
function isCheckInvocation(node) {
|
|
5357
|
-
return isInvocationExpr(node) && node.function.ref?.name === "check"
|
|
5358
|
+
return isInvocationExpr(node) && node.function.ref?.name === "check";
|
|
5358
5359
|
}
|
|
5359
5360
|
__name(isCheckInvocation, "isCheckInvocation");
|
|
5360
5361
|
function resolveTransitiveImports(documents, model) {
|
|
@@ -5431,10 +5432,10 @@ function getAuthDecl(decls) {
|
|
|
5431
5432
|
return authModel;
|
|
5432
5433
|
}
|
|
5433
5434
|
__name(getAuthDecl, "getAuthDecl");
|
|
5434
|
-
function
|
|
5435
|
-
return isInvocationExpr(node) && node.function.ref?.name === "
|
|
5435
|
+
function isBeforeInvocation(node) {
|
|
5436
|
+
return isInvocationExpr(node) && node.function.ref?.name === "before";
|
|
5436
5437
|
}
|
|
5437
|
-
__name(
|
|
5438
|
+
__name(isBeforeInvocation, "isBeforeInvocation");
|
|
5438
5439
|
function isCollectionPredicate(node) {
|
|
5439
5440
|
return isBinaryExpr(node) && [
|
|
5440
5441
|
"?",
|
|
@@ -5489,12 +5490,14 @@ function getAllFields(decl, includeIgnored = false, seen = /* @__PURE__ */ new S
|
|
|
5489
5490
|
seen.add(decl);
|
|
5490
5491
|
const fields = [];
|
|
5491
5492
|
for (const mixin of decl.mixins) {
|
|
5492
|
-
|
|
5493
|
-
|
|
5493
|
+
if (mixin.ref) {
|
|
5494
|
+
fields.push(...getAllFields(mixin.ref, includeIgnored, seen));
|
|
5495
|
+
}
|
|
5494
5496
|
}
|
|
5495
5497
|
if (isDataModel(decl) && decl.baseModel) {
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
+
if (decl.baseModel.ref) {
|
|
5499
|
+
fields.push(...getAllFields(decl.baseModel.ref, includeIgnored, seen));
|
|
5500
|
+
}
|
|
5498
5501
|
}
|
|
5499
5502
|
fields.push(...decl.fields.filter((f) => includeIgnored || !hasAttribute(f, "@ignore")));
|
|
5500
5503
|
return fields;
|
|
@@ -5507,12 +5510,14 @@ function getAllAttributes(decl, seen = /* @__PURE__ */ new Set()) {
|
|
|
5507
5510
|
seen.add(decl);
|
|
5508
5511
|
const attributes = [];
|
|
5509
5512
|
for (const mixin of decl.mixins) {
|
|
5510
|
-
|
|
5511
|
-
|
|
5513
|
+
if (mixin.ref) {
|
|
5514
|
+
attributes.push(...getAllAttributes(mixin.ref, seen));
|
|
5515
|
+
}
|
|
5512
5516
|
}
|
|
5513
5517
|
if (isDataModel(decl) && decl.baseModel) {
|
|
5514
|
-
|
|
5515
|
-
|
|
5518
|
+
if (decl.baseModel.ref) {
|
|
5519
|
+
attributes.push(...getAllAttributes(decl.baseModel.ref, seen));
|
|
5520
|
+
}
|
|
5516
5521
|
}
|
|
5517
5522
|
attributes.push(...decl.attributes);
|
|
5518
5523
|
return attributes;
|
|
@@ -5527,6 +5532,71 @@ function getDocument(node) {
|
|
|
5527
5532
|
return result;
|
|
5528
5533
|
}
|
|
5529
5534
|
__name(getDocument, "getDocument");
|
|
5535
|
+
function getPluginDocuments(model, schemaPath) {
|
|
5536
|
+
const result = [];
|
|
5537
|
+
for (const decl of model.declarations.filter(isPlugin)) {
|
|
5538
|
+
const providerField = decl.fields.find((f) => f.name === "provider");
|
|
5539
|
+
if (!providerField) {
|
|
5540
|
+
continue;
|
|
5541
|
+
}
|
|
5542
|
+
const provider = getLiteral(providerField.value);
|
|
5543
|
+
if (!provider) {
|
|
5544
|
+
continue;
|
|
5545
|
+
}
|
|
5546
|
+
let pluginModelFile;
|
|
5547
|
+
let providerPath = path.resolve(path.dirname(schemaPath), provider);
|
|
5548
|
+
if (fs.existsSync(providerPath)) {
|
|
5549
|
+
if (fs.statSync(providerPath).isDirectory()) {
|
|
5550
|
+
providerPath = path.join(providerPath, "index.js");
|
|
5551
|
+
}
|
|
5552
|
+
pluginModelFile = path.resolve(path.dirname(providerPath), PLUGIN_MODULE_NAME);
|
|
5553
|
+
if (!fs.existsSync(pluginModelFile)) {
|
|
5554
|
+
pluginModelFile = findUp([
|
|
5555
|
+
PLUGIN_MODULE_NAME
|
|
5556
|
+
], path.dirname(providerPath));
|
|
5557
|
+
}
|
|
5558
|
+
}
|
|
5559
|
+
if (!pluginModelFile) {
|
|
5560
|
+
if (typeof import.meta.resolve === "function") {
|
|
5561
|
+
try {
|
|
5562
|
+
const resolvedUrl = import.meta.resolve(`${provider}/${PLUGIN_MODULE_NAME}`);
|
|
5563
|
+
pluginModelFile = fileURLToPath(resolvedUrl);
|
|
5564
|
+
} catch {
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5567
|
+
}
|
|
5568
|
+
if (!pluginModelFile) {
|
|
5569
|
+
try {
|
|
5570
|
+
const require2 = createRequire(pathToFileURL(schemaPath));
|
|
5571
|
+
pluginModelFile = require2.resolve(`${provider}/${PLUGIN_MODULE_NAME}`);
|
|
5572
|
+
} catch {
|
|
5573
|
+
}
|
|
5574
|
+
}
|
|
5575
|
+
if (pluginModelFile && fs.existsSync(pluginModelFile)) {
|
|
5576
|
+
result.push(pluginModelFile);
|
|
5577
|
+
}
|
|
5578
|
+
}
|
|
5579
|
+
return result;
|
|
5580
|
+
}
|
|
5581
|
+
__name(getPluginDocuments, "getPluginDocuments");
|
|
5582
|
+
function findUp(names, cwd = process.cwd(), multiple = false, result = []) {
|
|
5583
|
+
if (!names.some((name) => !!name)) {
|
|
5584
|
+
return void 0;
|
|
5585
|
+
}
|
|
5586
|
+
const target = names.find((name) => fs.existsSync(path.join(cwd, name)));
|
|
5587
|
+
if (multiple === false && target) {
|
|
5588
|
+
return path.join(cwd, target);
|
|
5589
|
+
}
|
|
5590
|
+
if (target) {
|
|
5591
|
+
result.push(path.join(cwd, target));
|
|
5592
|
+
}
|
|
5593
|
+
const up = path.resolve(cwd, "..");
|
|
5594
|
+
if (up === cwd) {
|
|
5595
|
+
return multiple && result.length > 0 ? result : void 0;
|
|
5596
|
+
}
|
|
5597
|
+
return findUp(names, up, multiple, result);
|
|
5598
|
+
}
|
|
5599
|
+
__name(findUp, "findUp");
|
|
5530
5600
|
function findRootNode(node) {
|
|
5531
5601
|
while (node.$container) {
|
|
5532
5602
|
node = node.$container;
|
|
@@ -5536,6 +5606,8 @@ function findRootNode(node) {
|
|
|
5536
5606
|
__name(findRootNode, "findRootNode");
|
|
5537
5607
|
|
|
5538
5608
|
// src/validators/attribute-application-validator.ts
|
|
5609
|
+
import { AstUtils as AstUtils2 } from "langium";
|
|
5610
|
+
import pluralize from "pluralize";
|
|
5539
5611
|
function _ts_decorate(decorators, target, key, desc) {
|
|
5540
5612
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5541
5613
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -5649,6 +5721,7 @@ var AttributeApplicationValidator = class {
|
|
|
5649
5721
|
});
|
|
5650
5722
|
}
|
|
5651
5723
|
}
|
|
5724
|
+
// TODO: design a way to let plugin register validation
|
|
5652
5725
|
_checkModelLevelPolicy(attr, accept) {
|
|
5653
5726
|
const kind = getStringLiteral(attr.args[0]?.value);
|
|
5654
5727
|
if (!kind) {
|
|
@@ -5661,11 +5734,61 @@ var AttributeApplicationValidator = class {
|
|
|
5661
5734
|
"create",
|
|
5662
5735
|
"read",
|
|
5663
5736
|
"update",
|
|
5737
|
+
"post-update",
|
|
5664
5738
|
"delete",
|
|
5665
5739
|
"all"
|
|
5666
5740
|
], attr, accept);
|
|
5667
|
-
|
|
5741
|
+
if ((kind === "create" || kind === "all") && attr.args[1]?.value) {
|
|
5742
|
+
this.rejectNonOwnedRelationInExpression(attr.args[1].value, accept);
|
|
5743
|
+
}
|
|
5744
|
+
if (kind !== "post-update" && attr.args[1]?.value) {
|
|
5745
|
+
const beforeCall = AstUtils2.streamAst(attr.args[1]?.value).find(isBeforeInvocation);
|
|
5746
|
+
if (beforeCall) {
|
|
5747
|
+
accept("error", `"before()" is only allowed in "post-update" policy rules`, {
|
|
5748
|
+
node: beforeCall
|
|
5749
|
+
});
|
|
5750
|
+
}
|
|
5751
|
+
}
|
|
5668
5752
|
}
|
|
5753
|
+
rejectNonOwnedRelationInExpression(expr, accept) {
|
|
5754
|
+
const contextModel = AstUtils2.getContainerOfType(expr, isDataModel);
|
|
5755
|
+
if (!contextModel) {
|
|
5756
|
+
return;
|
|
5757
|
+
}
|
|
5758
|
+
if (AstUtils2.streamAst(expr).some((node) => {
|
|
5759
|
+
if (!isDataFieldReference(node)) {
|
|
5760
|
+
return false;
|
|
5761
|
+
}
|
|
5762
|
+
if (node.target.ref?.$container !== contextModel) {
|
|
5763
|
+
return false;
|
|
5764
|
+
}
|
|
5765
|
+
const field = node.target.ref;
|
|
5766
|
+
if (!isRelationshipField(field)) {
|
|
5767
|
+
return false;
|
|
5768
|
+
}
|
|
5769
|
+
if (isAuthOrAuthMemberAccess(node)) {
|
|
5770
|
+
return false;
|
|
5771
|
+
}
|
|
5772
|
+
const startNode = isCollectionPredicate(node.$container) && node.$container.left === node ? node.$container : node;
|
|
5773
|
+
const collectionPredicate = AstUtils2.getContainerOfType(startNode.$container, isCollectionPredicate);
|
|
5774
|
+
if (collectionPredicate && isAuthOrAuthMemberAccess(collectionPredicate.left)) {
|
|
5775
|
+
return false;
|
|
5776
|
+
}
|
|
5777
|
+
const relationAttr = field.attributes.find((attr) => attr.decl.ref?.name === "@relation");
|
|
5778
|
+
if (!relationAttr) {
|
|
5779
|
+
return true;
|
|
5780
|
+
}
|
|
5781
|
+
if (!relationAttr.args.some((arg) => arg.name === "fields")) {
|
|
5782
|
+
return true;
|
|
5783
|
+
}
|
|
5784
|
+
return false;
|
|
5785
|
+
})) {
|
|
5786
|
+
accept("error", `non-owned relation fields are not allowed in "create" rules`, {
|
|
5787
|
+
node: expr
|
|
5788
|
+
});
|
|
5789
|
+
}
|
|
5790
|
+
}
|
|
5791
|
+
// TODO: design a way to let plugin register validation
|
|
5669
5792
|
_checkFieldLevelPolicy(attr, accept) {
|
|
5670
5793
|
const kind = getStringLiteral(attr.args[0]?.value);
|
|
5671
5794
|
if (!kind) {
|
|
@@ -5680,8 +5803,8 @@ var AttributeApplicationValidator = class {
|
|
|
5680
5803
|
"all"
|
|
5681
5804
|
], attr, accept);
|
|
5682
5805
|
const expr = attr.args[1]?.value;
|
|
5683
|
-
if (expr && AstUtils2.streamAst(expr).some((node) =>
|
|
5684
|
-
accept("error", `"
|
|
5806
|
+
if (expr && AstUtils2.streamAst(expr).some((node) => isBeforeInvocation(node))) {
|
|
5807
|
+
accept("error", `"before()" is not allowed in field-level policy rules`, {
|
|
5685
5808
|
node: expr
|
|
5686
5809
|
});
|
|
5687
5810
|
}
|
|
@@ -5693,7 +5816,6 @@ var AttributeApplicationValidator = class {
|
|
|
5693
5816
|
});
|
|
5694
5817
|
}
|
|
5695
5818
|
}
|
|
5696
|
-
this.rejectEncryptedFields(attr, accept);
|
|
5697
5819
|
}
|
|
5698
5820
|
_checkValidate(attr, accept) {
|
|
5699
5821
|
const condition = attr.args[0]?.value;
|
|
@@ -5743,15 +5865,6 @@ var AttributeApplicationValidator = class {
|
|
|
5743
5865
|
});
|
|
5744
5866
|
}
|
|
5745
5867
|
}
|
|
5746
|
-
rejectEncryptedFields(attr, accept) {
|
|
5747
|
-
AstUtils2.streamAllContents(attr).forEach((node) => {
|
|
5748
|
-
if (isDataFieldReference(node) && hasAttribute(node.target.ref, "@encrypted")) {
|
|
5749
|
-
accept("error", `Encrypted fields cannot be used in policy rules`, {
|
|
5750
|
-
node
|
|
5751
|
-
});
|
|
5752
|
-
}
|
|
5753
|
-
});
|
|
5754
|
-
}
|
|
5755
5868
|
validatePolicyKinds(kind, candidates, attr, accept) {
|
|
5756
5869
|
const items = kind.split(",").map((x) => x.trim());
|
|
5757
5870
|
items.forEach((item) => {
|
|
@@ -5812,6 +5925,10 @@ function assignableToAttributeParam(arg, param, attr) {
|
|
|
5812
5925
|
let dstIsArray = param.type.array;
|
|
5813
5926
|
if (dstType === "ContextType") {
|
|
5814
5927
|
if (isDataField(attr.$container)) {
|
|
5928
|
+
const dstIsTypedJson = hasAttribute(attr.$container, "@json");
|
|
5929
|
+
if (dstIsTypedJson && attr.decl.ref?.name === "@default") {
|
|
5930
|
+
return argResolvedType.decl === "String";
|
|
5931
|
+
}
|
|
5815
5932
|
dstIsArray = attr.$container.type.array;
|
|
5816
5933
|
}
|
|
5817
5934
|
}
|
|
@@ -5903,6 +6020,9 @@ function isValidAttributeTarget(attrDecl, targetDecl) {
|
|
|
5903
6020
|
case "TypeDefField":
|
|
5904
6021
|
allowed = allowed || isTypeDef(targetDecl.type.reference?.ref);
|
|
5905
6022
|
break;
|
|
6023
|
+
case "ListField":
|
|
6024
|
+
allowed = allowed || !isDataModel(targetDecl.type.reference?.ref) && targetDecl.type.array;
|
|
6025
|
+
break;
|
|
5906
6026
|
default:
|
|
5907
6027
|
break;
|
|
5908
6028
|
}
|
|
@@ -5929,7 +6049,7 @@ var AttributeValidator = class {
|
|
|
5929
6049
|
};
|
|
5930
6050
|
|
|
5931
6051
|
// src/validators/datamodel-validator.ts
|
|
5932
|
-
import { invariant
|
|
6052
|
+
import { invariant } from "@zenstackhq/common-helpers";
|
|
5933
6053
|
import { AstUtils as AstUtils3 } from "langium";
|
|
5934
6054
|
|
|
5935
6055
|
// src/validators/common.ts
|
|
@@ -6300,7 +6420,7 @@ var DataModelValidator = class {
|
|
|
6300
6420
|
if (!model.baseModel) {
|
|
6301
6421
|
return;
|
|
6302
6422
|
}
|
|
6303
|
-
|
|
6423
|
+
invariant(model.baseModel.ref, "baseModel must be resolved");
|
|
6304
6424
|
if (!isDelegateModel(model.baseModel.ref)) {
|
|
6305
6425
|
accept("error", `Model ${model.baseModel.$refText} cannot be extended because it's not a delegate model`, {
|
|
6306
6426
|
node: model,
|
|
@@ -6322,7 +6442,7 @@ var DataModelValidator = class {
|
|
|
6322
6442
|
}
|
|
6323
6443
|
seen.push(current);
|
|
6324
6444
|
if (current.baseModel) {
|
|
6325
|
-
|
|
6445
|
+
invariant(current.baseModel.ref, "baseModel must be resolved");
|
|
6326
6446
|
todo.push(current.baseModel.ref);
|
|
6327
6447
|
}
|
|
6328
6448
|
}
|
|
@@ -6452,11 +6572,21 @@ var ExpressionValidator = class {
|
|
|
6452
6572
|
}
|
|
6453
6573
|
}
|
|
6454
6574
|
switch (expr.$type) {
|
|
6575
|
+
case "MemberAccessExpr":
|
|
6576
|
+
this.validateMemberAccessExpr(expr, accept);
|
|
6577
|
+
break;
|
|
6455
6578
|
case "BinaryExpr":
|
|
6456
6579
|
this.validateBinaryExpr(expr, accept);
|
|
6457
6580
|
break;
|
|
6458
6581
|
}
|
|
6459
6582
|
}
|
|
6583
|
+
validateMemberAccessExpr(expr, accept) {
|
|
6584
|
+
if (isBeforeInvocation(expr.operand) && isDataModel(expr.$resolvedType?.decl)) {
|
|
6585
|
+
accept("error", "relation fields cannot be accessed from `before()`", {
|
|
6586
|
+
node: expr
|
|
6587
|
+
});
|
|
6588
|
+
}
|
|
6589
|
+
}
|
|
6460
6590
|
validateBinaryExpr(expr, accept) {
|
|
6461
6591
|
switch (expr.operator) {
|
|
6462
6592
|
case "in": {
|
|
@@ -6509,23 +6639,25 @@ var ExpressionValidator = class {
|
|
|
6509
6639
|
"Any"
|
|
6510
6640
|
];
|
|
6511
6641
|
}
|
|
6512
|
-
|
|
6642
|
+
const leftResolvedDecl = expr.left.$resolvedType?.decl;
|
|
6643
|
+
const rightResolvedDecl = expr.right.$resolvedType?.decl;
|
|
6644
|
+
if (leftResolvedDecl && (typeof leftResolvedDecl !== "string" || !supportedShapes.includes(leftResolvedDecl))) {
|
|
6513
6645
|
accept("error", `invalid operand type for "${expr.operator}" operator`, {
|
|
6514
6646
|
node: expr.left
|
|
6515
6647
|
});
|
|
6516
6648
|
return;
|
|
6517
6649
|
}
|
|
6518
|
-
if (typeof
|
|
6650
|
+
if (rightResolvedDecl && (typeof rightResolvedDecl !== "string" || !supportedShapes.includes(rightResolvedDecl))) {
|
|
6519
6651
|
accept("error", `invalid operand type for "${expr.operator}" operator`, {
|
|
6520
6652
|
node: expr.right
|
|
6521
6653
|
});
|
|
6522
6654
|
return;
|
|
6523
6655
|
}
|
|
6524
|
-
if (
|
|
6656
|
+
if (leftResolvedDecl === "DateTime" && rightResolvedDecl && rightResolvedDecl !== "DateTime") {
|
|
6525
6657
|
accept("error", "incompatible operand types", {
|
|
6526
6658
|
node: expr
|
|
6527
6659
|
});
|
|
6528
|
-
} else if (
|
|
6660
|
+
} else if (rightResolvedDecl === "DateTime" && leftResolvedDecl && leftResolvedDecl !== "DateTime") {
|
|
6529
6661
|
accept("error", "incompatible operand types", {
|
|
6530
6662
|
node: expr
|
|
6531
6663
|
});
|
|
@@ -6565,11 +6697,11 @@ var ExpressionValidator = class {
|
|
|
6565
6697
|
});
|
|
6566
6698
|
}
|
|
6567
6699
|
if (isDataFieldReference(expr.left) && (isThisExpr(expr.right) || isDataFieldReference(expr.right))) {
|
|
6568
|
-
accept("error", "comparison between
|
|
6700
|
+
accept("error", "comparison between models is not supported", {
|
|
6569
6701
|
node: expr
|
|
6570
6702
|
});
|
|
6571
6703
|
} else if (isDataFieldReference(expr.right) && (isThisExpr(expr.left) || isDataFieldReference(expr.left))) {
|
|
6572
|
-
accept("error", "comparison between
|
|
6704
|
+
accept("error", "comparison between models is not supported", {
|
|
6573
6705
|
node: expr
|
|
6574
6706
|
});
|
|
6575
6707
|
}
|
|
@@ -6659,41 +6791,39 @@ var FunctionInvocationValidator = class {
|
|
|
6659
6791
|
if (!this.validateArgs(funcDecl, expr.args, accept)) {
|
|
6660
6792
|
return;
|
|
6661
6793
|
}
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
break;
|
|
6669
|
-
}
|
|
6670
|
-
curr = curr.$container;
|
|
6794
|
+
let curr = expr.$container;
|
|
6795
|
+
let containerAttribute;
|
|
6796
|
+
while (curr) {
|
|
6797
|
+
if (isDataModelAttribute(curr) || isDataFieldAttribute(curr)) {
|
|
6798
|
+
containerAttribute = curr;
|
|
6799
|
+
break;
|
|
6671
6800
|
}
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6801
|
+
curr = curr.$container;
|
|
6802
|
+
}
|
|
6803
|
+
const exprContext = this.getExpressionContext(containerAttribute);
|
|
6804
|
+
const funcAllowedContext = getFunctionExpressionContext(funcDecl);
|
|
6805
|
+
if (exprContext && !funcAllowedContext.includes(exprContext)) {
|
|
6806
|
+
accept("error", `function "${funcDecl.name}" is not allowed in the current context: ${exprContext}`, {
|
|
6807
|
+
node: expr
|
|
6808
|
+
});
|
|
6809
|
+
return;
|
|
6810
|
+
}
|
|
6811
|
+
const allCasing = [
|
|
6812
|
+
"original",
|
|
6813
|
+
"upper",
|
|
6814
|
+
"lower",
|
|
6815
|
+
"capitalize",
|
|
6816
|
+
"uncapitalize"
|
|
6817
|
+
];
|
|
6818
|
+
if ([
|
|
6819
|
+
"currentModel",
|
|
6820
|
+
"currentOperation"
|
|
6821
|
+
].includes(funcDecl.name)) {
|
|
6822
|
+
const arg = getLiteral(expr.args[0]?.value);
|
|
6823
|
+
if (arg && !allCasing.includes(arg)) {
|
|
6824
|
+
accept("error", `argument must be one of: ${allCasing.map((c) => '"' + c + '"').join(", ")}`, {
|
|
6825
|
+
node: expr.args[0]
|
|
6677
6826
|
});
|
|
6678
|
-
return;
|
|
6679
|
-
}
|
|
6680
|
-
const allCasing = [
|
|
6681
|
-
"original",
|
|
6682
|
-
"upper",
|
|
6683
|
-
"lower",
|
|
6684
|
-
"capitalize",
|
|
6685
|
-
"uncapitalize"
|
|
6686
|
-
];
|
|
6687
|
-
if ([
|
|
6688
|
-
"currentModel",
|
|
6689
|
-
"currentOperation"
|
|
6690
|
-
].includes(funcDecl.name)) {
|
|
6691
|
-
const arg = getLiteral(expr.args[0]?.value);
|
|
6692
|
-
if (arg && !allCasing.includes(arg)) {
|
|
6693
|
-
accept("error", `argument must be one of: ${allCasing.map((c) => '"' + c + '"').join(", ")}`, {
|
|
6694
|
-
node: expr.args[0]
|
|
6695
|
-
});
|
|
6696
|
-
}
|
|
6697
6827
|
}
|
|
6698
6828
|
}
|
|
6699
6829
|
const checker = invocationCheckers.get(expr.function.$refText);
|
|
@@ -6701,6 +6831,18 @@ var FunctionInvocationValidator = class {
|
|
|
6701
6831
|
checker.value.call(this, expr, accept);
|
|
6702
6832
|
}
|
|
6703
6833
|
}
|
|
6834
|
+
getExpressionContext(containerAttribute) {
|
|
6835
|
+
if (!containerAttribute) {
|
|
6836
|
+
return void 0;
|
|
6837
|
+
}
|
|
6838
|
+
if (this.isValidationAttribute(containerAttribute)) {
|
|
6839
|
+
return ExpressionContext.ValidationRule;
|
|
6840
|
+
}
|
|
6841
|
+
return match(containerAttribute?.decl.$refText).with("@default", () => ExpressionContext.DefaultValue).with(P.union("@@allow", "@@deny", "@allow", "@deny"), () => ExpressionContext.AccessPolicy).with("@@index", () => ExpressionContext.Index).otherwise(() => void 0);
|
|
6842
|
+
}
|
|
6843
|
+
isValidationAttribute(attr) {
|
|
6844
|
+
return !!attr.decl.ref?.attributes.some((attr2) => attr2.decl.$refText === "@@@validation");
|
|
6845
|
+
}
|
|
6704
6846
|
validateArgs(funcDecl, args, accept) {
|
|
6705
6847
|
let success = true;
|
|
6706
6848
|
for (let i = 0; i < funcDecl.params.length; i++) {
|
|
@@ -6761,6 +6903,44 @@ var FunctionInvocationValidator = class {
|
|
|
6761
6903
|
}
|
|
6762
6904
|
return true;
|
|
6763
6905
|
}
|
|
6906
|
+
_checkLength(expr, accept) {
|
|
6907
|
+
const msg = "argument must be a string or list field";
|
|
6908
|
+
const fieldArg = expr.args[0].value;
|
|
6909
|
+
if (!isDataFieldReference(fieldArg)) {
|
|
6910
|
+
accept("error", msg, {
|
|
6911
|
+
node: expr.args[0]
|
|
6912
|
+
});
|
|
6913
|
+
return;
|
|
6914
|
+
}
|
|
6915
|
+
if (isDataModel(fieldArg.$resolvedType?.decl)) {
|
|
6916
|
+
accept("error", msg, {
|
|
6917
|
+
node: expr.args[0]
|
|
6918
|
+
});
|
|
6919
|
+
return;
|
|
6920
|
+
}
|
|
6921
|
+
if (!fieldArg.$resolvedType?.array && fieldArg.$resolvedType?.decl !== "String") {
|
|
6922
|
+
accept("error", msg, {
|
|
6923
|
+
node: expr.args[0]
|
|
6924
|
+
});
|
|
6925
|
+
}
|
|
6926
|
+
}
|
|
6927
|
+
_checkRegex(expr, accept) {
|
|
6928
|
+
const regex = expr.args[1]?.value;
|
|
6929
|
+
if (!isStringLiteral(regex)) {
|
|
6930
|
+
accept("error", "second argument must be a string literal", {
|
|
6931
|
+
node: expr.args[1]
|
|
6932
|
+
});
|
|
6933
|
+
return;
|
|
6934
|
+
}
|
|
6935
|
+
try {
|
|
6936
|
+
new RegExp(regex.value);
|
|
6937
|
+
} catch (e) {
|
|
6938
|
+
accept("error", "invalid regular expression: " + e.message, {
|
|
6939
|
+
node: expr.args[1]
|
|
6940
|
+
});
|
|
6941
|
+
}
|
|
6942
|
+
}
|
|
6943
|
+
// TODO: move this to policy plugin
|
|
6764
6944
|
_checkCheck(expr, accept) {
|
|
6765
6945
|
let valid = true;
|
|
6766
6946
|
const fieldArg = expr.args[0].value;
|
|
@@ -6832,6 +7012,24 @@ var FunctionInvocationValidator = class {
|
|
|
6832
7012
|
}
|
|
6833
7013
|
}
|
|
6834
7014
|
};
|
|
7015
|
+
_ts_decorate2([
|
|
7016
|
+
func("length"),
|
|
7017
|
+
_ts_metadata2("design:type", Function),
|
|
7018
|
+
_ts_metadata2("design:paramtypes", [
|
|
7019
|
+
typeof InvocationExpr === "undefined" ? Object : InvocationExpr,
|
|
7020
|
+
typeof ValidationAcceptor === "undefined" ? Object : ValidationAcceptor
|
|
7021
|
+
]),
|
|
7022
|
+
_ts_metadata2("design:returntype", void 0)
|
|
7023
|
+
], FunctionInvocationValidator.prototype, "_checkLength", null);
|
|
7024
|
+
_ts_decorate2([
|
|
7025
|
+
func("regex"),
|
|
7026
|
+
_ts_metadata2("design:type", Function),
|
|
7027
|
+
_ts_metadata2("design:paramtypes", [
|
|
7028
|
+
typeof InvocationExpr === "undefined" ? Object : InvocationExpr,
|
|
7029
|
+
typeof ValidationAcceptor === "undefined" ? Object : ValidationAcceptor
|
|
7030
|
+
]),
|
|
7031
|
+
_ts_metadata2("design:returntype", void 0)
|
|
7032
|
+
], FunctionInvocationValidator.prototype, "_checkRegex", null);
|
|
6835
7033
|
_ts_decorate2([
|
|
6836
7034
|
func("check"),
|
|
6837
7035
|
_ts_metadata2("design:type", Function),
|
|
@@ -6941,49 +7139,66 @@ var ZModelValidator = class {
|
|
|
6941
7139
|
constructor(services) {
|
|
6942
7140
|
this.services = services;
|
|
6943
7141
|
}
|
|
6944
|
-
shouldCheck(node) {
|
|
6945
|
-
let doc;
|
|
6946
|
-
let currNode = node;
|
|
6947
|
-
while (currNode) {
|
|
6948
|
-
if (currNode.$document) {
|
|
6949
|
-
doc = currNode.$document;
|
|
6950
|
-
break;
|
|
6951
|
-
}
|
|
6952
|
-
currNode = currNode.$container;
|
|
6953
|
-
}
|
|
6954
|
-
return doc?.parseResult.lexerErrors.length === 0 && doc?.parseResult.parserErrors.length === 0;
|
|
6955
|
-
}
|
|
6956
7142
|
checkModel(node, accept) {
|
|
6957
|
-
|
|
7143
|
+
new SchemaValidator(this.services.shared.workspace.LangiumDocuments).validate(node, accept);
|
|
6958
7144
|
}
|
|
6959
7145
|
checkDataSource(node, accept) {
|
|
6960
|
-
|
|
7146
|
+
new DataSourceValidator().validate(node, accept);
|
|
6961
7147
|
}
|
|
6962
7148
|
checkDataModel(node, accept) {
|
|
6963
|
-
|
|
7149
|
+
new DataModelValidator().validate(node, accept);
|
|
6964
7150
|
}
|
|
6965
7151
|
checkTypeDef(node, accept) {
|
|
6966
|
-
|
|
7152
|
+
new TypeDefValidator().validate(node, accept);
|
|
6967
7153
|
}
|
|
6968
7154
|
checkEnum(node, accept) {
|
|
6969
|
-
|
|
7155
|
+
new EnumValidator().validate(node, accept);
|
|
6970
7156
|
}
|
|
6971
7157
|
checkAttribute(node, accept) {
|
|
6972
|
-
|
|
7158
|
+
new AttributeValidator().validate(node, accept);
|
|
6973
7159
|
}
|
|
6974
7160
|
checkExpression(node, accept) {
|
|
6975
|
-
|
|
7161
|
+
new ExpressionValidator().validate(node, accept);
|
|
6976
7162
|
}
|
|
6977
7163
|
checkFunctionInvocation(node, accept) {
|
|
6978
|
-
|
|
7164
|
+
new FunctionInvocationValidator().validate(node, accept);
|
|
6979
7165
|
}
|
|
6980
7166
|
checkFunctionDecl(node, accept) {
|
|
6981
|
-
|
|
7167
|
+
new FunctionDeclValidator().validate(node, accept);
|
|
7168
|
+
}
|
|
7169
|
+
};
|
|
7170
|
+
|
|
7171
|
+
// src/zmodel-document-builder.ts
|
|
7172
|
+
import { DefaultDocumentBuilder } from "langium";
|
|
7173
|
+
var ZModelDocumentBuilder = class extends DefaultDocumentBuilder {
|
|
7174
|
+
static {
|
|
7175
|
+
__name(this, "ZModelDocumentBuilder");
|
|
7176
|
+
}
|
|
7177
|
+
constructor(services) {
|
|
7178
|
+
super(services);
|
|
7179
|
+
let validationOptions = this.updateBuildOptions.validation;
|
|
7180
|
+
const stopFlags = {
|
|
7181
|
+
stopAfterLinkingErrors: true,
|
|
7182
|
+
stopAfterLexingErrors: true,
|
|
7183
|
+
stopAfterParsingErrors: true
|
|
7184
|
+
};
|
|
7185
|
+
if (validationOptions === true) {
|
|
7186
|
+
validationOptions = stopFlags;
|
|
7187
|
+
} else if (typeof validationOptions === "object") {
|
|
7188
|
+
validationOptions = {
|
|
7189
|
+
...validationOptions,
|
|
7190
|
+
...stopFlags
|
|
7191
|
+
};
|
|
7192
|
+
}
|
|
7193
|
+
this.updateBuildOptions = {
|
|
7194
|
+
...this.updateBuildOptions,
|
|
7195
|
+
validation: validationOptions
|
|
7196
|
+
};
|
|
6982
7197
|
}
|
|
6983
7198
|
};
|
|
6984
7199
|
|
|
6985
7200
|
// src/zmodel-linker.ts
|
|
6986
|
-
import { AstUtils as AstUtils6, Cancellation, DefaultLinker, DocumentState, interruptAndCheck
|
|
7201
|
+
import { AstUtils as AstUtils6, Cancellation, DefaultLinker, DocumentState, interruptAndCheck } from "langium";
|
|
6987
7202
|
import { match as match2 } from "ts-pattern";
|
|
6988
7203
|
var ZModelLinker = class extends DefaultLinker {
|
|
6989
7204
|
static {
|
|
@@ -7005,21 +7220,19 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7005
7220
|
}
|
|
7006
7221
|
document.state = DocumentState.Linked;
|
|
7007
7222
|
}
|
|
7008
|
-
linkReference(
|
|
7009
|
-
|
|
7223
|
+
linkReference(refInfo, document, extraScopes) {
|
|
7224
|
+
const defaultRef = refInfo.reference;
|
|
7225
|
+
if (defaultRef._ref) {
|
|
7226
|
+
return;
|
|
7227
|
+
}
|
|
7228
|
+
if (this.resolveFromScopeProviders(refInfo.reference, document, extraScopes)) {
|
|
7010
7229
|
return;
|
|
7011
7230
|
}
|
|
7012
|
-
|
|
7013
|
-
this.doLink({
|
|
7014
|
-
reference,
|
|
7015
|
-
container,
|
|
7016
|
-
property
|
|
7017
|
-
}, document);
|
|
7231
|
+
this.doLink(refInfo, document);
|
|
7018
7232
|
}
|
|
7019
7233
|
//#endregion
|
|
7020
7234
|
//#region Expression type resolving
|
|
7021
|
-
resolveFromScopeProviders(
|
|
7022
|
-
const reference = node[property];
|
|
7235
|
+
resolveFromScopeProviders(reference, document, providers) {
|
|
7023
7236
|
for (const provider of providers) {
|
|
7024
7237
|
const target = provider(reference.$refText);
|
|
7025
7238
|
if (target) {
|
|
@@ -7148,7 +7361,11 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7148
7361
|
}
|
|
7149
7362
|
}
|
|
7150
7363
|
resolveInvocation(node, document, extraScopes) {
|
|
7151
|
-
this.linkReference(
|
|
7364
|
+
this.linkReference({
|
|
7365
|
+
reference: node.function,
|
|
7366
|
+
container: node,
|
|
7367
|
+
property: "function"
|
|
7368
|
+
}, document, extraScopes);
|
|
7152
7369
|
node.args.forEach((arg) => this.resolve(arg, document, extraScopes));
|
|
7153
7370
|
if (node.function.ref) {
|
|
7154
7371
|
const funcDecl = node.function.ref;
|
|
@@ -7161,7 +7378,7 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7161
7378
|
nullable: true
|
|
7162
7379
|
};
|
|
7163
7380
|
}
|
|
7164
|
-
} else if (
|
|
7381
|
+
} else if (isBeforeInvocation(node)) {
|
|
7165
7382
|
node.$resolvedType = {
|
|
7166
7383
|
decl: getContainingDataModel(node)
|
|
7167
7384
|
};
|
|
@@ -7225,7 +7442,7 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7225
7442
|
if (isArrayExpr(node.value)) {
|
|
7226
7443
|
node.value.items.forEach((item) => {
|
|
7227
7444
|
if (isReferenceExpr(item)) {
|
|
7228
|
-
const resolved2 = this.resolveFromScopeProviders(item
|
|
7445
|
+
const resolved2 = this.resolveFromScopeProviders(item.target, document, [
|
|
7229
7446
|
scopeProvider
|
|
7230
7447
|
]);
|
|
7231
7448
|
if (resolved2) {
|
|
@@ -7239,7 +7456,7 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7239
7456
|
this.resolveToBuiltinTypeOrDecl(node.value, node.value.items[0].$resolvedType.decl, true);
|
|
7240
7457
|
}
|
|
7241
7458
|
} else if (isReferenceExpr(node.value)) {
|
|
7242
|
-
const resolved2 = this.resolveFromScopeProviders(node.value
|
|
7459
|
+
const resolved2 = this.resolveFromScopeProviders(node.value.target, document, [
|
|
7243
7460
|
scopeProvider
|
|
7244
7461
|
]);
|
|
7245
7462
|
if (resolved2) {
|
|
@@ -7291,13 +7508,9 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7291
7508
|
this.resolveDefault(node, document, scopes);
|
|
7292
7509
|
}
|
|
7293
7510
|
resolveDefault(node, document, extraScopes) {
|
|
7294
|
-
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
this.linkReference(node, property, document, extraScopes);
|
|
7298
|
-
}
|
|
7299
|
-
}
|
|
7300
|
-
}
|
|
7511
|
+
AstUtils6.streamReferences(node).forEach((ref) => {
|
|
7512
|
+
this.linkReference(ref, document, extraScopes);
|
|
7513
|
+
});
|
|
7301
7514
|
for (const child of AstUtils6.streamContents(node)) {
|
|
7302
7515
|
this.resolve(child, document, extraScopes);
|
|
7303
7516
|
}
|
|
@@ -7367,7 +7580,7 @@ var ZModelScopeComputation = class extends DefaultScopeComputation {
|
|
|
7367
7580
|
}
|
|
7368
7581
|
processNode(node, document, scopes) {
|
|
7369
7582
|
super.processNode(node, document, scopes);
|
|
7370
|
-
if (isDataModel(node)) {
|
|
7583
|
+
if (isDataModel(node) || isTypeDef(node)) {
|
|
7371
7584
|
const bases = getRecursiveBases(node);
|
|
7372
7585
|
for (const base of bases) {
|
|
7373
7586
|
for (const field of base.fields) {
|
|
@@ -7438,7 +7651,7 @@ var ZModelScopeProvider = class extends DefaultScopeProvider {
|
|
|
7438
7651
|
if (isAuthInvocation(operand)) {
|
|
7439
7652
|
return this.createScopeForAuth(node, globalScope);
|
|
7440
7653
|
}
|
|
7441
|
-
if (
|
|
7654
|
+
if (isBeforeInvocation(operand)) {
|
|
7442
7655
|
return this.createScopeForContainingModel(node, globalScope);
|
|
7443
7656
|
}
|
|
7444
7657
|
return EMPTY_SCOPE;
|
|
@@ -7512,10 +7725,10 @@ function getCollectionPredicateContext(node) {
|
|
|
7512
7725
|
__name(getCollectionPredicateContext, "getCollectionPredicateContext");
|
|
7513
7726
|
|
|
7514
7727
|
// src/zmodel-workspace-manager.ts
|
|
7515
|
-
import { DefaultWorkspaceManager, URI as URI2
|
|
7728
|
+
import { DefaultWorkspaceManager, URI as URI2 } from "langium";
|
|
7516
7729
|
import fs2 from "fs";
|
|
7517
7730
|
import path2 from "path";
|
|
7518
|
-
import { fileURLToPath } from "url";
|
|
7731
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7519
7732
|
var ZModelWorkspaceManager = class extends DefaultWorkspaceManager {
|
|
7520
7733
|
static {
|
|
7521
7734
|
__name(this, "ZModelWorkspaceManager");
|
|
@@ -7551,73 +7764,12 @@ var ZModelWorkspaceManager = class extends DefaultWorkspaceManager {
|
|
|
7551
7764
|
if (installedStdlibPath) {
|
|
7552
7765
|
stdLibPath = installedStdlibPath;
|
|
7553
7766
|
} else {
|
|
7554
|
-
const _dirname = typeof __dirname !== "undefined" ? __dirname : path2.dirname(
|
|
7767
|
+
const _dirname = typeof __dirname !== "undefined" ? __dirname : path2.dirname(fileURLToPath2(import.meta.url));
|
|
7555
7768
|
stdLibPath = path2.join(_dirname, "../res", STD_LIB_MODULE_NAME);
|
|
7556
7769
|
console.log(`Using bundled stdlib in extension:`, stdLibPath);
|
|
7557
7770
|
}
|
|
7558
7771
|
const stdlib = await this.documentFactory.fromUri(URI2.file(stdLibPath));
|
|
7559
7772
|
collector(stdlib);
|
|
7560
|
-
const documents = this.langiumDocuments.all;
|
|
7561
|
-
const pluginModels = /* @__PURE__ */ new Set();
|
|
7562
|
-
documents.forEach((doc) => {
|
|
7563
|
-
const parsed = doc.parseResult.value;
|
|
7564
|
-
parsed.declarations.forEach((decl) => {
|
|
7565
|
-
if (isPlugin(decl)) {
|
|
7566
|
-
const providerField = decl.fields.find((f) => f.name === "provider");
|
|
7567
|
-
if (providerField) {
|
|
7568
|
-
const provider = getLiteral(providerField.value);
|
|
7569
|
-
if (provider) {
|
|
7570
|
-
pluginModels.add(provider);
|
|
7571
|
-
}
|
|
7572
|
-
}
|
|
7573
|
-
}
|
|
7574
|
-
});
|
|
7575
|
-
});
|
|
7576
|
-
if (pluginModels.size > 0) {
|
|
7577
|
-
console.log(`Used plugin modules: ${Array.from(pluginModels)}`);
|
|
7578
|
-
const pendingPluginModules = new Set(pluginModels);
|
|
7579
|
-
await Promise.all(folders.map((wf) => [
|
|
7580
|
-
wf,
|
|
7581
|
-
this.getRootFolder(wf)
|
|
7582
|
-
]).map(async (entry) => this.loadPluginModels(...entry, pendingPluginModules, collector)));
|
|
7583
|
-
}
|
|
7584
|
-
}
|
|
7585
|
-
async loadPluginModels(workspaceFolder, folderPath, pendingPluginModels, collector) {
|
|
7586
|
-
const content = (await this.fileSystemProvider.readDirectory(folderPath)).sort((a, b) => {
|
|
7587
|
-
if (a.isDirectory && b.isDirectory) {
|
|
7588
|
-
const aName = UriUtils2.basename(a.uri);
|
|
7589
|
-
if (aName === "node_modules") {
|
|
7590
|
-
return -1;
|
|
7591
|
-
} else {
|
|
7592
|
-
return 1;
|
|
7593
|
-
}
|
|
7594
|
-
} else {
|
|
7595
|
-
return 0;
|
|
7596
|
-
}
|
|
7597
|
-
});
|
|
7598
|
-
for (const entry of content) {
|
|
7599
|
-
if (entry.isDirectory) {
|
|
7600
|
-
const name = UriUtils2.basename(entry.uri);
|
|
7601
|
-
if (name === "node_modules") {
|
|
7602
|
-
for (const plugin of Array.from(pendingPluginModels)) {
|
|
7603
|
-
const path4 = UriUtils2.joinPath(entry.uri, plugin, PLUGIN_MODULE_NAME);
|
|
7604
|
-
try {
|
|
7605
|
-
await this.fileSystemProvider.readFile(path4);
|
|
7606
|
-
const document = await this.langiumDocuments.getOrCreateDocument(path4);
|
|
7607
|
-
collector(document);
|
|
7608
|
-
console.log(`Adding plugin document from ${path4.path}`);
|
|
7609
|
-
pendingPluginModels.delete(plugin);
|
|
7610
|
-
if (pendingPluginModels.size === 0) {
|
|
7611
|
-
return;
|
|
7612
|
-
}
|
|
7613
|
-
} catch {
|
|
7614
|
-
}
|
|
7615
|
-
}
|
|
7616
|
-
} else {
|
|
7617
|
-
await this.loadPluginModels(workspaceFolder, entry.uri, pendingPluginModels, collector);
|
|
7618
|
-
}
|
|
7619
|
-
}
|
|
7620
|
-
}
|
|
7621
7773
|
}
|
|
7622
7774
|
};
|
|
7623
7775
|
|
|
@@ -7634,10 +7786,11 @@ var ZModelLanguageModule = {
|
|
|
7634
7786
|
};
|
|
7635
7787
|
var ZModelSharedModule = {
|
|
7636
7788
|
workspace: {
|
|
7789
|
+
DocumentBuilder: /* @__PURE__ */ __name((services) => new ZModelDocumentBuilder(services), "DocumentBuilder"),
|
|
7637
7790
|
WorkspaceManager: /* @__PURE__ */ __name((services) => new ZModelWorkspaceManager(services), "WorkspaceManager")
|
|
7638
7791
|
}
|
|
7639
7792
|
};
|
|
7640
|
-
function createZModelLanguageServices(context) {
|
|
7793
|
+
function createZModelLanguageServices(context, logToConsole = false) {
|
|
7641
7794
|
const shared = inject(createDefaultSharedModule(context), ZModelGeneratedSharedModule, ZModelSharedModule);
|
|
7642
7795
|
const ZModelLanguage = inject(createDefaultModule({
|
|
7643
7796
|
shared
|
|
@@ -7647,30 +7800,38 @@ function createZModelLanguageServices(context) {
|
|
|
7647
7800
|
if (!context.connection) {
|
|
7648
7801
|
shared.workspace.ConfigurationProvider.initialized({});
|
|
7649
7802
|
}
|
|
7803
|
+
shared.workspace.DocumentBuilder.onBuildPhase(DocumentState2.Parsed, async (documents) => {
|
|
7804
|
+
for (const doc of documents) {
|
|
7805
|
+
if (doc.parseResult.lexerErrors.length > 0 || doc.parseResult.parserErrors.length > 0) {
|
|
7806
|
+
continue;
|
|
7807
|
+
}
|
|
7808
|
+
const schemaPath = fileURLToPath3(doc.uri.toString());
|
|
7809
|
+
const pluginSchemas = getPluginDocuments(doc.parseResult.value, schemaPath);
|
|
7810
|
+
for (const plugin of pluginSchemas) {
|
|
7811
|
+
const pluginDoc = await shared.workspace.LangiumDocuments.getOrCreateDocument(URI3.file(path3.resolve(plugin)));
|
|
7812
|
+
shared.workspace.IndexManager.updateContent(pluginDoc);
|
|
7813
|
+
if (logToConsole) {
|
|
7814
|
+
console.log(`Loaded plugin model: ${plugin}`);
|
|
7815
|
+
}
|
|
7816
|
+
}
|
|
7817
|
+
}
|
|
7818
|
+
});
|
|
7650
7819
|
return {
|
|
7651
7820
|
shared,
|
|
7652
7821
|
ZModelLanguage
|
|
7653
7822
|
};
|
|
7654
7823
|
}
|
|
7655
7824
|
__name(createZModelLanguageServices, "createZModelLanguageServices");
|
|
7656
|
-
|
|
7657
|
-
|
|
7658
|
-
function createZModelServices() {
|
|
7659
|
-
return createZModelLanguageServices(NodeFileSystem);
|
|
7825
|
+
function createZModelServices(logToConsole = false) {
|
|
7826
|
+
return createZModelLanguageServices(NodeFileSystem, logToConsole);
|
|
7660
7827
|
}
|
|
7661
7828
|
__name(createZModelServices, "createZModelServices");
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
}
|
|
7666
|
-
constructor(message) {
|
|
7667
|
-
super(message);
|
|
7668
|
-
}
|
|
7669
|
-
};
|
|
7670
|
-
async function loadDocument(fileName, pluginModelFiles = []) {
|
|
7671
|
-
const { ZModelLanguage: services } = createZModelServices();
|
|
7829
|
+
|
|
7830
|
+
// src/document.ts
|
|
7831
|
+
async function loadDocument(fileName, additionalModelFiles = []) {
|
|
7832
|
+
const { ZModelLanguage: services } = createZModelServices(false);
|
|
7672
7833
|
const extensions = services.LanguageMetaData.fileExtensions;
|
|
7673
|
-
if (!extensions.includes(
|
|
7834
|
+
if (!extensions.includes(path4.extname(fileName))) {
|
|
7674
7835
|
return {
|
|
7675
7836
|
success: false,
|
|
7676
7837
|
errors: [
|
|
@@ -7688,23 +7849,27 @@ async function loadDocument(fileName, pluginModelFiles = []) {
|
|
|
7688
7849
|
warnings: []
|
|
7689
7850
|
};
|
|
7690
7851
|
}
|
|
7691
|
-
const _dirname = typeof __dirname !== "undefined" ? __dirname :
|
|
7692
|
-
const stdLib = await services.shared.workspace.LangiumDocuments.getOrCreateDocument(
|
|
7693
|
-
const pluginDocs = await Promise.all(pluginModelFiles.map((file) => services.shared.workspace.LangiumDocuments.getOrCreateDocument(URI3.file(path3.resolve(file)))));
|
|
7852
|
+
const _dirname = typeof __dirname !== "undefined" ? __dirname : path4.dirname(fileURLToPath4(import.meta.url));
|
|
7853
|
+
const stdLib = await services.shared.workspace.LangiumDocuments.getOrCreateDocument(URI4.file(path4.resolve(path4.join(_dirname, "../res", STD_LIB_MODULE_NAME))));
|
|
7694
7854
|
const langiumDocuments = services.shared.workspace.LangiumDocuments;
|
|
7695
|
-
const document = await langiumDocuments.getOrCreateDocument(
|
|
7855
|
+
const document = await langiumDocuments.getOrCreateDocument(URI4.file(path4.resolve(fileName)));
|
|
7696
7856
|
const importedURIs = await loadImports(document, langiumDocuments);
|
|
7697
7857
|
const importedDocuments = [];
|
|
7698
7858
|
for (const uri of importedURIs) {
|
|
7699
7859
|
importedDocuments.push(await langiumDocuments.getOrCreateDocument(uri));
|
|
7700
7860
|
}
|
|
7861
|
+
const additionalDocs = await Promise.all(additionalModelFiles.map((file) => services.shared.workspace.LangiumDocuments.getOrCreateDocument(URI4.file(path4.resolve(file)))));
|
|
7701
7862
|
await services.shared.workspace.DocumentBuilder.build([
|
|
7702
7863
|
stdLib,
|
|
7703
|
-
...
|
|
7864
|
+
...additionalDocs,
|
|
7704
7865
|
document,
|
|
7705
7866
|
...importedDocuments
|
|
7706
7867
|
], {
|
|
7707
|
-
validation:
|
|
7868
|
+
validation: {
|
|
7869
|
+
stopAfterLexingErrors: true,
|
|
7870
|
+
stopAfterParsingErrors: true,
|
|
7871
|
+
stopAfterLinkingErrors: true
|
|
7872
|
+
}
|
|
7708
7873
|
});
|
|
7709
7874
|
const diagnostics = langiumDocuments.all.flatMap((doc) => (doc.diagnostics ?? []).map((diag) => ({
|
|
7710
7875
|
doc,
|
|
@@ -7714,7 +7879,7 @@ async function loadDocument(fileName, pluginModelFiles = []) {
|
|
|
7714
7879
|
const warnings = [];
|
|
7715
7880
|
if (diagnostics.length > 0) {
|
|
7716
7881
|
for (const { doc, diag } of diagnostics) {
|
|
7717
|
-
const message = `${
|
|
7882
|
+
const message = `${path4.relative(process.cwd(), doc.uri.fsPath)}:${diag.range.start.line + 1}:${diag.range.start.character + 1} - ${diag.message}`;
|
|
7718
7883
|
if (diag.severity === 1) {
|
|
7719
7884
|
errors.push(message);
|
|
7720
7885
|
} else {
|
|
@@ -7763,7 +7928,7 @@ async function loadImports(document, documents, uris = /* @__PURE__ */ new Set()
|
|
|
7763
7928
|
}
|
|
7764
7929
|
}
|
|
7765
7930
|
}
|
|
7766
|
-
return Array.from(uris).filter((x) => uriString != x).map((e) =>
|
|
7931
|
+
return Array.from(uris).filter((x) => uriString != x).map((e) => URI4.parse(e));
|
|
7767
7932
|
}
|
|
7768
7933
|
__name(loadImports, "loadImports");
|
|
7769
7934
|
function mergeImportsDeclarations(documents, model) {
|
|
@@ -7813,7 +7978,6 @@ function validationAfterImportMerge(model) {
|
|
|
7813
7978
|
}
|
|
7814
7979
|
__name(validationAfterImportMerge, "validationAfterImportMerge");
|
|
7815
7980
|
export {
|
|
7816
|
-
DocumentLoadError,
|
|
7817
7981
|
ZModelLanguageMetaData,
|
|
7818
7982
|
ZModelLanguageModule,
|
|
7819
7983
|
ZModelSharedModule,
|