zenstack 1.0.0-alpha.23 → 1.0.0-alpha.25
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/README.md +79 -9
- package/cli/cli-error.js +3 -5
- package/cli/cli-error.js.map +1 -1
- package/cli/cli-util.js +123 -105
- package/cli/cli-util.js.map +1 -1
- package/cli/index.js +105 -63
- package/cli/index.js.map +1 -1
- package/cli/plugin-runner.js +130 -127
- package/cli/plugin-runner.js.map +1 -1
- package/language-server/constants.js +5 -13
- package/language-server/constants.js.map +1 -1
- package/language-server/main.js +8 -15
- package/language-server/main.js.map +1 -1
- package/language-server/types.js +3 -1
- package/language-server/types.js.map +1 -1
- package/language-server/utils.js +13 -16
- package/language-server/utils.js.map +1 -1
- package/language-server/validator/attribute-validator.js +3 -7
- package/language-server/validator/attribute-validator.js.map +1 -1
- package/language-server/validator/datamodel-validator.js +293 -347
- package/language-server/validator/datamodel-validator.js.map +1 -1
- package/language-server/validator/datasource-validator.js +61 -71
- package/language-server/validator/datasource-validator.js.map +1 -1
- package/language-server/validator/enum-validator.js +6 -10
- package/language-server/validator/enum-validator.js.map +1 -1
- package/language-server/validator/expression-validator.js +25 -31
- package/language-server/validator/expression-validator.js.map +1 -1
- package/language-server/validator/schema-validator.js +18 -25
- package/language-server/validator/schema-validator.js.map +1 -1
- package/language-server/validator/utils.js +86 -85
- package/language-server/validator/utils.js.map +1 -1
- package/language-server/validator/zmodel-validator.js +55 -58
- package/language-server/validator/zmodel-validator.js.map +1 -1
- package/language-server/zmodel-formatter.js +40 -21
- package/language-server/zmodel-formatter.js.map +1 -1
- package/language-server/zmodel-linker.js +328 -331
- package/language-server/zmodel-linker.js.map +1 -1
- package/language-server/zmodel-module.js +50 -59
- package/language-server/zmodel-module.js.map +1 -1
- package/language-server/zmodel-scope.js +35 -25
- package/language-server/zmodel-scope.js.map +1 -1
- package/language-server/zmodel-workspace-manager.js +30 -18
- package/language-server/zmodel-workspace-manager.js.map +1 -1
- package/package.json +8 -12
- package/plugins/access-policy/expression-writer.js +301 -292
- package/plugins/access-policy/expression-writer.js.map +1 -1
- package/plugins/access-policy/index.js +20 -11
- package/plugins/access-policy/index.js.map +1 -1
- package/plugins/access-policy/policy-guard-generator.js +327 -321
- package/plugins/access-policy/policy-guard-generator.js.map +1 -1
- package/plugins/access-policy/typescript-expression-transformer.js +94 -95
- package/plugins/access-policy/typescript-expression-transformer.js.map +1 -1
- package/plugins/access-policy/utils.js +7 -9
- package/plugins/access-policy/utils.js.map +1 -1
- package/plugins/access-policy/zod-schema-generator.js +143 -159
- package/plugins/access-policy/zod-schema-generator.js.map +1 -1
- package/plugins/model-meta/index.js +97 -102
- package/plugins/model-meta/index.js.map +1 -1
- package/plugins/plugin-utils.js +34 -40
- package/plugins/plugin-utils.js.map +1 -1
- package/plugins/prisma/indent-string.js +4 -8
- package/plugins/prisma/indent-string.js.map +1 -1
- package/plugins/prisma/index.js +20 -11
- package/plugins/prisma/index.js.map +1 -1
- package/plugins/prisma/prisma-builder.js +235 -213
- package/plugins/prisma/prisma-builder.js.map +1 -1
- package/plugins/prisma/schema-generator.js +205 -192
- package/plugins/prisma/schema-generator.js.map +1 -1
- package/plugins/prisma/zmodel-code-generator.js +109 -114
- package/plugins/prisma/zmodel-code-generator.js.map +1 -1
- package/telemetry.js +107 -90
- package/telemetry.js.map +1 -1
- package/types.js +3 -1
- package/types.js.map +1 -1
- package/utils/ast-utils.js +67 -67
- package/utils/ast-utils.js.map +1 -1
- package/utils/exec-utils.js +6 -15
- package/utils/exec-utils.js.map +1 -1
- package/utils/pkg-utils.js +38 -35
- package/utils/pkg-utils.js.map +1 -1
- package/utils/version-utils.js +9 -10
- package/utils/version-utils.js.map +1 -1
- package/global.d.js +0 -1
- package/global.d.js.map +0 -1
|
@@ -1,364 +1,361 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
});
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
12
|
exports.ZModelLinker = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
const ast_1 = require("@zenstackhq/language/ast");
|
|
14
|
+
const langium_1 = require("langium");
|
|
15
|
+
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
|
|
16
|
+
const utils_1 = require("./utils");
|
|
17
|
+
const utils_2 = require("./validator/utils");
|
|
12
18
|
/**
|
|
13
19
|
* Langium linker implementation which links references and resolves expression types
|
|
14
20
|
*/
|
|
15
|
-
class ZModelLinker extends
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
//#region Reference linking
|
|
22
|
-
|
|
23
|
-
async link(document, cancelToken = _vscodeJsonrpc.CancellationToken.None) {
|
|
24
|
-
var _document$parseResult, _document$parseResult2;
|
|
25
|
-
if (((_document$parseResult = document.parseResult.lexerErrors) === null || _document$parseResult === void 0 ? void 0 : _document$parseResult.length) > 0 || ((_document$parseResult2 = document.parseResult.parserErrors) === null || _document$parseResult2 === void 0 ? void 0 : _document$parseResult2.length) > 0) {
|
|
26
|
-
return;
|
|
21
|
+
class ZModelLinker extends langium_1.DefaultLinker {
|
|
22
|
+
constructor(services) {
|
|
23
|
+
super(services);
|
|
24
|
+
this.descriptions = services.workspace.AstNodeDescriptionProvider;
|
|
27
25
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
//#region Reference linking
|
|
27
|
+
link(document, cancelToken = vscode_jsonrpc_1.CancellationToken.None) {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
if (((_a = document.parseResult.lexerErrors) === null || _a === void 0 ? void 0 : _a.length) > 0 || ((_b = document.parseResult.parserErrors) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
for (const node of (0, langium_1.streamContents)(document.parseResult.value)) {
|
|
34
|
+
yield (0, langium_1.interruptAndCheck)(cancelToken);
|
|
35
|
+
this.resolve(node, document);
|
|
36
|
+
}
|
|
37
|
+
document.state = langium_1.DocumentState.Linked;
|
|
38
|
+
});
|
|
31
39
|
}
|
|
32
|
-
document
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.doLink({
|
|
39
|
-
reference,
|
|
40
|
-
container,
|
|
41
|
-
property
|
|
42
|
-
}, document);
|
|
40
|
+
linkReference(container, property, document, extraScopes) {
|
|
41
|
+
if (!this.resolveFromScopeProviders(container, property, document, extraScopes)) {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
+
const reference = container[property];
|
|
44
|
+
this.doLink({ reference, container, property }, document);
|
|
45
|
+
}
|
|
43
46
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return target;
|
|
59
|
-
}
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region Expression type resolving
|
|
49
|
+
resolveFromScopeProviders(node, property, document, providers) {
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
51
|
+
const reference = node[property];
|
|
52
|
+
for (const provider of providers) {
|
|
53
|
+
const target = provider(reference.$refText);
|
|
54
|
+
if (target) {
|
|
55
|
+
reference._ref = target;
|
|
56
|
+
reference._nodeDescription = this.descriptions.createDescription(target, target.name, document);
|
|
57
|
+
return target;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
break;
|
|
62
|
+
resolve(node, document, extraScopes = []) {
|
|
63
|
+
switch (node.$type) {
|
|
64
|
+
case ast_1.LiteralExpr:
|
|
65
|
+
this.resolveLiteral(node);
|
|
66
|
+
break;
|
|
67
|
+
case ast_1.InvocationExpr:
|
|
68
|
+
this.resolveInvocation(node, document, extraScopes);
|
|
69
|
+
break;
|
|
70
|
+
case ast_1.ArrayExpr:
|
|
71
|
+
this.resolveArray(node, document, extraScopes);
|
|
72
|
+
break;
|
|
73
|
+
case ast_1.ReferenceExpr:
|
|
74
|
+
this.resolveReference(node, document, extraScopes);
|
|
75
|
+
break;
|
|
76
|
+
case ast_1.MemberAccessExpr:
|
|
77
|
+
this.resolveMemberAccess(node, document, extraScopes);
|
|
78
|
+
break;
|
|
79
|
+
case ast_1.UnaryExpr:
|
|
80
|
+
this.resolveUnary(node, document, extraScopes);
|
|
81
|
+
break;
|
|
82
|
+
case ast_1.BinaryExpr:
|
|
83
|
+
this.resolveBinary(node, document, extraScopes);
|
|
84
|
+
break;
|
|
85
|
+
case ast_1.ThisExpr:
|
|
86
|
+
this.resolveThis(node, document, extraScopes);
|
|
87
|
+
break;
|
|
88
|
+
case ast_1.NullExpr:
|
|
89
|
+
this.resolveNull(node, document, extraScopes);
|
|
90
|
+
break;
|
|
91
|
+
case ast_1.AttributeArg:
|
|
92
|
+
this.resolveAttributeArg(node, document, extraScopes);
|
|
93
|
+
break;
|
|
94
|
+
default:
|
|
95
|
+
this.resolveDefault(node, document, extraScopes);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
98
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
throw Error(`Unsupported binary operator: ${node.operator}`);
|
|
99
|
+
resolveBinary(node, document, extraScopes) {
|
|
100
|
+
switch (node.operator) {
|
|
101
|
+
// TODO: support arithmetics?
|
|
102
|
+
// case '+':
|
|
103
|
+
// case '-':
|
|
104
|
+
// case '*':
|
|
105
|
+
// case '/':
|
|
106
|
+
// this.resolve(node.left, document, extraScopes);
|
|
107
|
+
// this.resolve(node.right, document, extraScopes);
|
|
108
|
+
// this.resolveToBuiltinTypeOrDecl(node, 'Int');
|
|
109
|
+
// break;
|
|
110
|
+
case '>':
|
|
111
|
+
case '>=':
|
|
112
|
+
case '<':
|
|
113
|
+
case '<=':
|
|
114
|
+
case '==':
|
|
115
|
+
case '!=':
|
|
116
|
+
case '&&':
|
|
117
|
+
case '||':
|
|
118
|
+
this.resolve(node.left, document, extraScopes);
|
|
119
|
+
this.resolve(node.right, document, extraScopes);
|
|
120
|
+
this.resolveToBuiltinTypeOrDecl(node, 'Boolean');
|
|
121
|
+
break;
|
|
122
|
+
case '?':
|
|
123
|
+
case '!':
|
|
124
|
+
case '^':
|
|
125
|
+
this.resolveCollectionPredicate(node, document, extraScopes);
|
|
126
|
+
break;
|
|
127
|
+
default:
|
|
128
|
+
throw Error(`Unsupported binary operator: ${node.operator}`);
|
|
129
|
+
}
|
|
131
130
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
node.$resolvedType = node.operand.$resolvedType;
|
|
136
|
-
}
|
|
137
|
-
resolveReference(node, document, extraScopes) {
|
|
138
|
-
this.linkReference(node, 'target', document, extraScopes);
|
|
139
|
-
node.args.forEach(arg => this.resolve(arg, document, extraScopes));
|
|
140
|
-
if (node.target.ref) {
|
|
141
|
-
// resolve type
|
|
142
|
-
if (node.target.ref.$type === _ast.EnumField) {
|
|
143
|
-
this.resolveToBuiltinTypeOrDecl(node, node.target.ref.$container);
|
|
144
|
-
} else {
|
|
145
|
-
this.resolveToDeclaredType(node, node.target.ref.type);
|
|
146
|
-
}
|
|
131
|
+
resolveUnary(node, document, extraScopes) {
|
|
132
|
+
this.resolve(node.operand, document, extraScopes);
|
|
133
|
+
node.$resolvedType = node.operand.$resolvedType;
|
|
147
134
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
135
|
+
resolveReference(node, document, extraScopes) {
|
|
136
|
+
this.linkReference(node, 'target', document, extraScopes);
|
|
137
|
+
node.args.forEach((arg) => this.resolve(arg, document, extraScopes));
|
|
138
|
+
if (node.target.ref) {
|
|
139
|
+
// resolve type
|
|
140
|
+
if (node.target.ref.$type === ast_1.EnumField) {
|
|
141
|
+
this.resolveToBuiltinTypeOrDecl(node, node.target.ref.$container);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
this.resolveToDeclaredType(node, node.target.ref.type);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
154
147
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
161
|
-
const funcDecl = node.function.ref;
|
|
162
|
-
if (funcDecl.name === 'auth' && (0, _utils.isFromStdlib)(funcDecl)) {
|
|
163
|
-
// auth() function is resolved to User model in the current document
|
|
164
|
-
const model = (0, _utils.getContainingModel)(node);
|
|
165
|
-
const userModel = model === null || model === void 0 ? void 0 : model.declarations.find(d => (0, _ast.isDataModel)(d) && d.name === 'User');
|
|
166
|
-
if (userModel) {
|
|
167
|
-
node.$resolvedType = {
|
|
168
|
-
decl: userModel
|
|
169
|
-
};
|
|
148
|
+
resolveArray(node, document, extraScopes) {
|
|
149
|
+
node.items.forEach((item) => this.resolve(item, document, extraScopes));
|
|
150
|
+
const itemType = node.items[0].$resolvedType;
|
|
151
|
+
if (itemType === null || itemType === void 0 ? void 0 : itemType.decl) {
|
|
152
|
+
this.resolveToBuiltinTypeOrDecl(node, itemType.decl, true);
|
|
170
153
|
}
|
|
171
|
-
} else if (funcDecl.name === 'future' && (0, _utils.isFromStdlib)(funcDecl)) {
|
|
172
|
-
// future() function is resolved to current model
|
|
173
|
-
node.$resolvedType = {
|
|
174
|
-
decl: this.getContainingDataModel(node)
|
|
175
|
-
};
|
|
176
|
-
} else {
|
|
177
|
-
this.resolveToDeclaredType(node, funcDecl.returnType);
|
|
178
|
-
}
|
|
179
154
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
155
|
+
resolveInvocation(node, document, extraScopes) {
|
|
156
|
+
this.linkReference(node, 'function', document, extraScopes);
|
|
157
|
+
node.args.forEach((arg) => this.resolve(arg, document, extraScopes));
|
|
158
|
+
if (node.function.ref) {
|
|
159
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
160
|
+
const funcDecl = node.function.ref;
|
|
161
|
+
if (funcDecl.name === 'auth' && (0, utils_1.isFromStdlib)(funcDecl)) {
|
|
162
|
+
// auth() function is resolved to User model in the current document
|
|
163
|
+
const model = (0, utils_1.getContainingModel)(node);
|
|
164
|
+
const userModel = model === null || model === void 0 ? void 0 : model.declarations.find((d) => (0, ast_1.isDataModel)(d) && d.name === 'User');
|
|
165
|
+
if (userModel) {
|
|
166
|
+
node.$resolvedType = { decl: userModel };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else if (funcDecl.name === 'future' && (0, utils_1.isFromStdlib)(funcDecl)) {
|
|
170
|
+
// future() function is resolved to current model
|
|
171
|
+
node.$resolvedType = { decl: this.getContainingDataModel(node) };
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
this.resolveToDeclaredType(node, funcDecl.returnType);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
188
177
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
178
|
+
getContainingDataModel(node) {
|
|
179
|
+
let curr = node.$container;
|
|
180
|
+
while (curr) {
|
|
181
|
+
if ((0, ast_1.isDataModel)(curr)) {
|
|
182
|
+
return curr;
|
|
183
|
+
}
|
|
184
|
+
curr = curr.$container;
|
|
185
|
+
}
|
|
186
|
+
return undefined;
|
|
195
187
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
188
|
+
resolveLiteral(node) {
|
|
189
|
+
const type = typeof node.value === 'string'
|
|
190
|
+
? 'String'
|
|
191
|
+
: typeof node.value === 'boolean'
|
|
192
|
+
? 'Boolean'
|
|
193
|
+
: typeof node.value === 'number'
|
|
194
|
+
? 'Int'
|
|
195
|
+
: undefined;
|
|
196
|
+
if (type) {
|
|
197
|
+
this.resolveToBuiltinTypeOrDecl(node, type);
|
|
198
|
+
}
|
|
204
199
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
200
|
+
resolveMemberAccess(node, document, extraScopes) {
|
|
201
|
+
this.resolve(node.operand, document, extraScopes);
|
|
202
|
+
const operandResolved = node.operand.$resolvedType;
|
|
203
|
+
if (operandResolved && !operandResolved.array && (0, ast_1.isDataModel)(operandResolved.decl)) {
|
|
204
|
+
const modelDecl = operandResolved.decl;
|
|
205
|
+
const provider = (name) => modelDecl.fields.find((f) => f.name === name);
|
|
206
|
+
extraScopes = [provider, ...extraScopes];
|
|
207
|
+
}
|
|
208
|
+
this.linkReference(node, 'member', document, extraScopes);
|
|
209
|
+
if (node.member.ref) {
|
|
210
|
+
this.resolveToDeclaredType(node, node.member.ref.type);
|
|
211
|
+
}
|
|
208
212
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
213
|
+
resolveCollectionPredicate(node, document, extraScopes) {
|
|
214
|
+
this.resolve(node.left, document, extraScopes);
|
|
215
|
+
const resolvedType = node.left.$resolvedType;
|
|
216
|
+
if (resolvedType && (0, ast_1.isDataModel)(resolvedType.decl) && resolvedType.array) {
|
|
217
|
+
const dataModelDecl = resolvedType.decl;
|
|
218
|
+
const provider = (name) => dataModelDecl.fields.find((f) => f.name === name);
|
|
219
|
+
extraScopes = [provider, ...extraScopes];
|
|
220
|
+
this.resolve(node.right, document, extraScopes);
|
|
221
|
+
this.resolveToBuiltinTypeOrDecl(node, 'Boolean');
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
// error is reported in validation pass
|
|
225
|
+
}
|
|
221
226
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
227
|
+
resolveThis(node,
|
|
228
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
229
|
+
document,
|
|
230
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
231
|
+
extraScopes) {
|
|
232
|
+
let decl = node.$container;
|
|
233
|
+
while (decl && !(0, ast_1.isDataModel)(decl)) {
|
|
234
|
+
decl = decl.$container;
|
|
235
|
+
}
|
|
236
|
+
if (decl) {
|
|
237
|
+
this.resolveToBuiltinTypeOrDecl(node, decl);
|
|
238
|
+
}
|
|
231
239
|
}
|
|
232
|
-
|
|
233
|
-
|
|
240
|
+
resolveNull(node,
|
|
241
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
242
|
+
document,
|
|
243
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
244
|
+
extraScopes) {
|
|
245
|
+
// TODO: how to really resolve null?
|
|
246
|
+
this.resolveToBuiltinTypeOrDecl(node, 'Null');
|
|
234
247
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
248
|
+
resolveAttributeArg(node, document, extraScopes) {
|
|
249
|
+
var _a, _b, _c;
|
|
250
|
+
const attrParam = this.findAttrParamForArg(node);
|
|
251
|
+
const attrAppliedOn = node.$container.$container;
|
|
252
|
+
if ((attrParam === null || attrParam === void 0 ? void 0 : attrParam.type.type) === 'TransitiveFieldReference' && (0, ast_1.isDataModelField)(attrAppliedOn)) {
|
|
253
|
+
// "TransitiveFieldReference" is resolved in the context of the containing model of the field
|
|
254
|
+
// where the attribute is applied
|
|
255
|
+
//
|
|
256
|
+
// E.g.:
|
|
257
|
+
//
|
|
258
|
+
// model A {
|
|
259
|
+
// myId @id String
|
|
260
|
+
// }
|
|
261
|
+
//
|
|
262
|
+
// model B {
|
|
263
|
+
// id @id String
|
|
264
|
+
// a A @relation(fields: [id], references: [myId])
|
|
265
|
+
// }
|
|
266
|
+
//
|
|
267
|
+
// In model B, the attribute argument "myId" is resolved to the field "myId" in model A
|
|
268
|
+
const transtiveDataModel = (_a = attrAppliedOn.type.reference) === null || _a === void 0 ? void 0 : _a.ref;
|
|
269
|
+
if (transtiveDataModel) {
|
|
270
|
+
// resolve references in the context of the transitive data model
|
|
271
|
+
const scopeProvider = (name) => transtiveDataModel.fields.find((f) => f.name === name);
|
|
272
|
+
if ((0, ast_1.isArrayExpr)(node.value)) {
|
|
273
|
+
node.value.items.forEach((item) => {
|
|
274
|
+
if ((0, ast_1.isReferenceExpr)(item)) {
|
|
275
|
+
const resolved = this.resolveFromScopeProviders(item, 'target', document, [scopeProvider]);
|
|
276
|
+
if (resolved) {
|
|
277
|
+
this.resolveToDeclaredType(item, resolved.type);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// need to clear linked reference, because it's resolved in default scope by default
|
|
281
|
+
const ref = item.target;
|
|
282
|
+
ref._ref = this.createLinkingError({
|
|
283
|
+
reference: ref,
|
|
284
|
+
container: item,
|
|
285
|
+
property: 'target',
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
if ((_c = (_b = node.value.items[0]) === null || _b === void 0 ? void 0 : _b.$resolvedType) === null || _c === void 0 ? void 0 : _c.decl) {
|
|
291
|
+
this.resolveToBuiltinTypeOrDecl(node.value, node.value.items[0].$resolvedType.decl, true);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
else if ((0, ast_1.isReferenceExpr)(node.value)) {
|
|
295
|
+
const resolved = this.resolveFromScopeProviders(node.value, 'target', document, [scopeProvider]);
|
|
296
|
+
if (resolved) {
|
|
297
|
+
this.resolveToDeclaredType(node.value, resolved.type);
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
// need to clear linked reference, because it's resolved in default scope by default
|
|
301
|
+
const ref = node.value.target;
|
|
302
|
+
ref._ref = this.createLinkingError({
|
|
303
|
+
reference: ref,
|
|
304
|
+
container: node.value,
|
|
305
|
+
property: 'target',
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
285
309
|
}
|
|
286
|
-
});
|
|
287
|
-
if ((_node$value$items$ = node.value.items[0]) !== null && _node$value$items$ !== void 0 && (_node$value$items$$$r = _node$value$items$.$resolvedType) !== null && _node$value$items$$$r !== void 0 && _node$value$items$$$r.decl) {
|
|
288
|
-
this.resolveToBuiltinTypeOrDecl(node.value, node.value.items[0].$resolvedType.decl, true);
|
|
289
|
-
}
|
|
290
|
-
} else if ((0, _ast.isReferenceExpr)(node.value)) {
|
|
291
|
-
const resolved = this.resolveFromScopeProviders(node.value, 'target', document, [scopeProvider]);
|
|
292
|
-
if (resolved) {
|
|
293
|
-
this.resolveToDeclaredType(node.value, resolved.type);
|
|
294
|
-
} else {
|
|
295
|
-
// need to clear linked reference, because it's resolved in default scope by default
|
|
296
|
-
const ref = node.value.target;
|
|
297
|
-
ref._ref = this.createLinkingError({
|
|
298
|
-
reference: ref,
|
|
299
|
-
container: node.value,
|
|
300
|
-
property: 'target'
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
310
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
node.$resolvedType = node.value.$resolvedType;
|
|
309
|
-
}
|
|
310
|
-
findAttrParamForArg(arg) {
|
|
311
|
-
const attr = arg.$container.decl.ref;
|
|
312
|
-
if (!attr) {
|
|
313
|
-
return undefined;
|
|
311
|
+
else {
|
|
312
|
+
this.resolve(node.value, document, extraScopes);
|
|
313
|
+
}
|
|
314
|
+
node.$resolvedType = node.value.$resolvedType;
|
|
314
315
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
316
|
+
findAttrParamForArg(arg) {
|
|
317
|
+
var _a;
|
|
318
|
+
const attr = arg.$container.decl.ref;
|
|
319
|
+
if (!attr) {
|
|
320
|
+
return undefined;
|
|
321
|
+
}
|
|
322
|
+
if (arg.name) {
|
|
323
|
+
return (_a = attr.params) === null || _a === void 0 ? void 0 : _a.find((p) => p.name === arg.name);
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
const index = arg.$container.args.findIndex((a) => a === arg);
|
|
327
|
+
return attr.params[index];
|
|
328
|
+
}
|
|
321
329
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
330
|
+
resolveDefault(node, document, extraScopes) {
|
|
331
|
+
for (const [property, value] of Object.entries(node)) {
|
|
332
|
+
if (!property.startsWith('$')) {
|
|
333
|
+
if ((0, langium_1.isReference)(value)) {
|
|
334
|
+
this.linkReference(node, property, document, extraScopes);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
for (const child of (0, langium_1.streamContents)(node)) {
|
|
339
|
+
this.resolve(child, document, extraScopes);
|
|
328
340
|
}
|
|
329
|
-
}
|
|
330
341
|
}
|
|
331
|
-
|
|
332
|
-
|
|
342
|
+
//#endregion
|
|
343
|
+
//#region Utils
|
|
344
|
+
resolveToDeclaredType(node, type) {
|
|
345
|
+
if (type.type) {
|
|
346
|
+
const mappedType = (0, utils_2.mapBuiltinTypeToExpressionType)(type.type);
|
|
347
|
+
node.$resolvedType = { decl: mappedType, array: type.array };
|
|
348
|
+
}
|
|
349
|
+
else if (type.reference) {
|
|
350
|
+
node.$resolvedType = {
|
|
351
|
+
decl: type.reference.ref,
|
|
352
|
+
array: type.array,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
333
355
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
//#endregion
|
|
337
|
-
|
|
338
|
-
//#region Utils
|
|
339
|
-
|
|
340
|
-
resolveToDeclaredType(node, type) {
|
|
341
|
-
if (type.type) {
|
|
342
|
-
const mappedType = (0, _utils2.mapBuiltinTypeToExpressionType)(type.type);
|
|
343
|
-
node.$resolvedType = {
|
|
344
|
-
decl: mappedType,
|
|
345
|
-
array: type.array
|
|
346
|
-
};
|
|
347
|
-
} else if (type.reference) {
|
|
348
|
-
node.$resolvedType = {
|
|
349
|
-
decl: type.reference.ref,
|
|
350
|
-
array: type.array
|
|
351
|
-
};
|
|
356
|
+
resolveToBuiltinTypeOrDecl(node, type, array = false) {
|
|
357
|
+
node.$resolvedType = { decl: type, array };
|
|
352
358
|
}
|
|
353
|
-
}
|
|
354
|
-
resolveToBuiltinTypeOrDecl(node, type, array = false) {
|
|
355
|
-
node.$resolvedType = {
|
|
356
|
-
decl: type,
|
|
357
|
-
array
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
//#endregion
|
|
362
359
|
}
|
|
363
360
|
exports.ZModelLinker = ZModelLinker;
|
|
364
361
|
//# sourceMappingURL=zmodel-linker.js.map
|