@player-tools/typescript-expression-plugin 0.4.2-next.1 → 0.5.0-next.0
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/cjs/index.cjs +389 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/{index.esm.js → index.legacy-esm.js} +103 -115
- package/dist/index.mjs +358 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +25 -28
- package/src/__tests__/service.test.ts +185 -0
- package/src/index.ts +5 -5
- package/src/logger.ts +2 -2
- package/src/service.ts +18 -18
- package/src/transforms.ts +7 -7
- package/src/utils.ts +9 -9
- package/src/virtual-service-host.ts +4 -4
- package/{dist → types}/index.d.ts +3 -4
- package/types/logger.d.ts +8 -0
- package/types/service.d.ts +31 -0
- package/types/transforms.d.ts +2 -0
- package/types/utils.d.ts +14 -0
- package/types/virtual-service-host.d.ts +20 -0
- package/dist/index.cjs.js +0 -392
package/dist/index.cjs.js
DELETED
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var typescriptTemplateLanguageServiceDecorator = require('typescript-template-language-service-decorator');
|
|
4
|
-
var ts = require('typescript/lib/tsserverlibrary');
|
|
5
|
-
var xlrUtils = require('@player-tools/xlr-utils');
|
|
6
|
-
var xlrSdk = require('@player-tools/xlr-sdk');
|
|
7
|
-
var player = require('@player-ui/player');
|
|
8
|
-
var jsoncParser = require('jsonc-parser');
|
|
9
|
-
|
|
10
|
-
function _interopNamespace(e) {
|
|
11
|
-
if (e && e.__esModule) return e;
|
|
12
|
-
var n = Object.create(null);
|
|
13
|
-
if (e) {
|
|
14
|
-
Object.keys(e).forEach(function (k) {
|
|
15
|
-
if (k !== 'default') {
|
|
16
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
17
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
18
|
-
enumerable: true,
|
|
19
|
-
get: function () { return e[k]; }
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
n["default"] = e;
|
|
25
|
-
return Object.freeze(n);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
29
|
-
|
|
30
|
-
function isInRange(position, location) {
|
|
31
|
-
return position.character >= location.start.character && position.character <= location.end.character;
|
|
32
|
-
}
|
|
33
|
-
function getTokenAtPosition(node, position) {
|
|
34
|
-
var _a;
|
|
35
|
-
if (node.type === "CallExpression") {
|
|
36
|
-
const anyArgs = node.args.find((arg) => {
|
|
37
|
-
return getTokenAtPosition(arg, position);
|
|
38
|
-
});
|
|
39
|
-
if (anyArgs) {
|
|
40
|
-
return anyArgs;
|
|
41
|
-
}
|
|
42
|
-
const asTarget = getTokenAtPosition(node.callTarget, position);
|
|
43
|
-
if (asTarget) {
|
|
44
|
-
return asTarget;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
if (node.type === "Assignment") {
|
|
48
|
-
const asTarget = (_a = getTokenAtPosition(node.left, position)) != null ? _a : getTokenAtPosition(node.right, position);
|
|
49
|
-
if (asTarget) {
|
|
50
|
-
return asTarget;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
if (node.location && isInRange(position, node.location)) {
|
|
54
|
-
return node;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
function toTSLocation(node) {
|
|
58
|
-
var _a, _b;
|
|
59
|
-
const start = (_a = node.location) == null ? void 0 : _a.start.character;
|
|
60
|
-
const end = (_b = node.location) == null ? void 0 : _b.end.character;
|
|
61
|
-
if (start === void 0 || end === void 0) {
|
|
62
|
-
return {
|
|
63
|
-
start: 0,
|
|
64
|
-
length: 0
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
start,
|
|
69
|
-
length: end - start
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
function convertExprToValue(exprNode) {
|
|
73
|
-
let val;
|
|
74
|
-
if (exprNode.type === "Literal") {
|
|
75
|
-
val = exprNode.value;
|
|
76
|
-
} else if (exprNode.type === "Object") {
|
|
77
|
-
val = {};
|
|
78
|
-
exprNode.attributes.forEach((prop) => {
|
|
79
|
-
val[convertExprToValue(prop.key)] = convertExprToValue(prop.value);
|
|
80
|
-
});
|
|
81
|
-
} else if (exprNode.type === "ArrayExpression") {
|
|
82
|
-
val = exprNode.elements.map(convertExprToValue);
|
|
83
|
-
}
|
|
84
|
-
return val;
|
|
85
|
-
}
|
|
86
|
-
function convertExprToJSONNode(exprNode) {
|
|
87
|
-
const val = convertExprToValue(exprNode);
|
|
88
|
-
if (val === void 0) {
|
|
89
|
-
return void 0;
|
|
90
|
-
}
|
|
91
|
-
return jsoncParser.parseTree(JSON.stringify(val));
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
var __defProp$1 = Object.defineProperty;
|
|
95
|
-
var __defProps$1 = Object.defineProperties;
|
|
96
|
-
var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
|
|
97
|
-
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
98
|
-
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
99
|
-
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
100
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
101
|
-
var __spreadValues$1 = (a, b) => {
|
|
102
|
-
for (var prop in b || (b = {}))
|
|
103
|
-
if (__hasOwnProp$1.call(b, prop))
|
|
104
|
-
__defNormalProp$1(a, prop, b[prop]);
|
|
105
|
-
if (__getOwnPropSymbols$1)
|
|
106
|
-
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
107
|
-
if (__propIsEnum$1.call(b, prop))
|
|
108
|
-
__defNormalProp$1(a, prop, b[prop]);
|
|
109
|
-
}
|
|
110
|
-
return a;
|
|
111
|
-
};
|
|
112
|
-
var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
|
|
113
|
-
const toFunction = xlrSdk.simpleTransformGenerator("ref", "Expressions", (exp) => {
|
|
114
|
-
if (!exp.genericArguments || exp.ref !== "ExpressionHandler") {
|
|
115
|
-
return exp;
|
|
116
|
-
}
|
|
117
|
-
const [args, returnType] = exp.genericArguments;
|
|
118
|
-
const parameters = (args.type === "tuple" ? args.elementTypes : []).map((elementType, index) => {
|
|
119
|
-
var _a, _b, _c, _d, _e, _f;
|
|
120
|
-
return {
|
|
121
|
-
name: (_c = (_b = (_a = elementType.name) != null ? _a : elementType.type.name) != null ? _b : elementType.type.title) != null ? _c : `arg_${index}`,
|
|
122
|
-
type: __spreadValues$1({
|
|
123
|
-
name: (_f = (_e = (_d = elementType.name) != null ? _d : elementType.type.name) != null ? _e : elementType.type.title) != null ? _f : `arg_${index}`
|
|
124
|
-
}, elementType.type),
|
|
125
|
-
optional: elementType.optional === true ? elementType.optional : void 0
|
|
126
|
-
};
|
|
127
|
-
});
|
|
128
|
-
return __spreadProps$1(__spreadValues$1({}, exp), {
|
|
129
|
-
type: "function",
|
|
130
|
-
parameters,
|
|
131
|
-
returnType
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
var __defProp = Object.defineProperty;
|
|
136
|
-
var __defProps = Object.defineProperties;
|
|
137
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
138
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
139
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
140
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
141
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
142
|
-
var __spreadValues = (a, b) => {
|
|
143
|
-
for (var prop in b || (b = {}))
|
|
144
|
-
if (__hasOwnProp.call(b, prop))
|
|
145
|
-
__defNormalProp(a, prop, b[prop]);
|
|
146
|
-
if (__getOwnPropSymbols)
|
|
147
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
148
|
-
if (__propIsEnum.call(b, prop))
|
|
149
|
-
__defNormalProp(a, prop, b[prop]);
|
|
150
|
-
}
|
|
151
|
-
return a;
|
|
152
|
-
};
|
|
153
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
154
|
-
class ExpressionLanguageService {
|
|
155
|
-
constructor(options) {
|
|
156
|
-
this._plugins = [];
|
|
157
|
-
var _a;
|
|
158
|
-
this.logger = options == null ? void 0 : options.logger;
|
|
159
|
-
this._plugins = (_a = options == null ? void 0 : options.plugins) != null ? _a : [];
|
|
160
|
-
this.xlr = new xlrSdk.XLRSDK();
|
|
161
|
-
this._plugins.forEach((p) => {
|
|
162
|
-
this.xlr.loadDefinitionsFromModule(p, void 0, [toFunction]);
|
|
163
|
-
});
|
|
164
|
-
this._expressions = this.reduceExpression();
|
|
165
|
-
}
|
|
166
|
-
setConfig(config) {
|
|
167
|
-
this._plugins = config.plugins;
|
|
168
|
-
this.xlr = new xlrSdk.XLRSDK();
|
|
169
|
-
this._plugins.forEach((p) => {
|
|
170
|
-
this.xlr.loadDefinitionsFromModule(p, void 0, [toFunction]);
|
|
171
|
-
});
|
|
172
|
-
this._expressions = this.reduceExpression();
|
|
173
|
-
}
|
|
174
|
-
reduceExpression() {
|
|
175
|
-
const expressions = new Map();
|
|
176
|
-
this.xlr.listTypes().forEach((type) => {
|
|
177
|
-
const typeInfo = this.xlr.getTypeInfo(type.name);
|
|
178
|
-
const source = this._plugins.find((value) => value.pluginName === (typeInfo == null ? void 0 : typeInfo.plugin));
|
|
179
|
-
if (type.type === "function" && (typeInfo == null ? void 0 : typeInfo.capability) === "Expressions" && source) {
|
|
180
|
-
expressions.set(type.name, {
|
|
181
|
-
name: type.name,
|
|
182
|
-
description: type.description,
|
|
183
|
-
type,
|
|
184
|
-
source
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
return expressions;
|
|
189
|
-
}
|
|
190
|
-
getCompletionsAtPosition(context, position) {
|
|
191
|
-
var _a, _b;
|
|
192
|
-
const completionInfo = {
|
|
193
|
-
isGlobalCompletion: false,
|
|
194
|
-
isMemberCompletion: false,
|
|
195
|
-
isNewIdentifierLocation: true,
|
|
196
|
-
entries: []
|
|
197
|
-
};
|
|
198
|
-
if (context.text.length === 0) {
|
|
199
|
-
this._expressions.forEach((exp) => {
|
|
200
|
-
completionInfo.entries.push({
|
|
201
|
-
name: exp.name,
|
|
202
|
-
kind: ts__namespace.ScriptElementKind.functionElement,
|
|
203
|
-
sortText: exp.name,
|
|
204
|
-
isRecommended: true,
|
|
205
|
-
insertText: `${exp.name}()`
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
return completionInfo;
|
|
209
|
-
}
|
|
210
|
-
const line = context.text.split(/\n/g)[position.line];
|
|
211
|
-
const parsed = player.parseExpression(line, { strict: false });
|
|
212
|
-
const token = getTokenAtPosition(parsed, position);
|
|
213
|
-
if ((token == null ? void 0 : token.type) === "Compound" && token.error) {
|
|
214
|
-
this._expressions.forEach((exp) => {
|
|
215
|
-
completionInfo.entries.push({
|
|
216
|
-
name: exp.name,
|
|
217
|
-
kind: ts__namespace.ScriptElementKind.functionElement,
|
|
218
|
-
sortText: exp.name,
|
|
219
|
-
isRecommended: true,
|
|
220
|
-
insertText: `${exp.name}()`
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
return completionInfo;
|
|
224
|
-
}
|
|
225
|
-
if ((token == null ? void 0 : token.type) === "Identifier") {
|
|
226
|
-
const start = (_b = (_a = token.location) == null ? void 0 : _a.start) != null ? _b : { character: 0 };
|
|
227
|
-
const wordFromStart = line.slice(start.character, position.character);
|
|
228
|
-
const allCompletions = Array.from(this._expressions.keys()).filter((key) => key.startsWith(wordFromStart));
|
|
229
|
-
allCompletions.forEach((c) => {
|
|
230
|
-
completionInfo.entries.push({
|
|
231
|
-
name: c,
|
|
232
|
-
kind: ts__namespace.ScriptElementKind.functionElement,
|
|
233
|
-
sortText: c,
|
|
234
|
-
isRecommended: true,
|
|
235
|
-
insertText: `${c}()`
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
return completionInfo;
|
|
240
|
-
}
|
|
241
|
-
getCompletionEntryDetails(context, position, name) {
|
|
242
|
-
var _a;
|
|
243
|
-
const expression = this._expressions.get(name);
|
|
244
|
-
const completionDetails = {
|
|
245
|
-
name,
|
|
246
|
-
kind: ts__namespace.ScriptElementKind.functionElement,
|
|
247
|
-
kindModifiers: ts__namespace.ScriptElementKindModifier.none,
|
|
248
|
-
documentation: [
|
|
249
|
-
{
|
|
250
|
-
kind: "text",
|
|
251
|
-
text: (_a = expression == null ? void 0 : expression.type.description) != null ? _a : ""
|
|
252
|
-
}
|
|
253
|
-
],
|
|
254
|
-
displayParts: expression ? xlrUtils.createTSDocString(expression.type) : []
|
|
255
|
-
};
|
|
256
|
-
return completionDetails;
|
|
257
|
-
}
|
|
258
|
-
getQuickInfoAtPosition(context, position) {
|
|
259
|
-
const parsed = player.parseExpression(context.text, { strict: false });
|
|
260
|
-
const token = getTokenAtPosition(parsed, position);
|
|
261
|
-
if ((token == null ? void 0 : token.type) === "Identifier") {
|
|
262
|
-
const expression = this._expressions.get(token.name);
|
|
263
|
-
if (expression) {
|
|
264
|
-
const completionDetails = this.getCompletionEntryDetails(context, position, expression.name);
|
|
265
|
-
return __spreadProps(__spreadValues({}, completionDetails), {
|
|
266
|
-
textSpan: toTSLocation(token)
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
return void 0;
|
|
271
|
-
}
|
|
272
|
-
checkNode(context, node, xlrType) {
|
|
273
|
-
const diagnostics = [];
|
|
274
|
-
const asJsonNodeValue = convertExprToJSONNode(node);
|
|
275
|
-
if (asJsonNodeValue) {
|
|
276
|
-
const xlrDiags = this.xlr.validateByType(xlrType, asJsonNodeValue);
|
|
277
|
-
xlrDiags.forEach((d) => {
|
|
278
|
-
diagnostics.push(__spreadProps(__spreadValues({
|
|
279
|
-
file: context.node.getSourceFile()
|
|
280
|
-
}, toTSLocation(node)), {
|
|
281
|
-
messageText: d.message,
|
|
282
|
-
category: ts__namespace.DiagnosticCategory.Error,
|
|
283
|
-
code: 1
|
|
284
|
-
}));
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
return diagnostics;
|
|
288
|
-
}
|
|
289
|
-
getDiagnosticsForNode(context, node) {
|
|
290
|
-
const diags = [];
|
|
291
|
-
if (node.type === "Compound") {
|
|
292
|
-
node.body.forEach((n) => {
|
|
293
|
-
diags.push(...this.getDiagnosticsForNode(context, n));
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
if (node.type === "CallExpression") {
|
|
297
|
-
const exprName = node.callTarget.name;
|
|
298
|
-
const expression = this._expressions.get(exprName);
|
|
299
|
-
node.args.forEach((n) => {
|
|
300
|
-
diags.push(...this.getDiagnosticsForNode(context, n));
|
|
301
|
-
});
|
|
302
|
-
if (expression) {
|
|
303
|
-
const expectedArgs = expression.type.parameters;
|
|
304
|
-
const actualArgs = node.args;
|
|
305
|
-
actualArgs.forEach((actualArg, index) => {
|
|
306
|
-
const expectedArg = expectedArgs[index];
|
|
307
|
-
if (expectedArg) {
|
|
308
|
-
diags.push(...this.checkNode(context, actualArg, expectedArg.type));
|
|
309
|
-
}
|
|
310
|
-
});
|
|
311
|
-
if (expectedArgs.length > actualArgs.length) {
|
|
312
|
-
const requiredArgs = expectedArgs.filter((a) => !a.optional);
|
|
313
|
-
if (actualArgs.length < requiredArgs.length) {
|
|
314
|
-
diags.push(__spreadProps(__spreadValues({
|
|
315
|
-
category: ts__namespace.DiagnosticCategory.Error,
|
|
316
|
-
code: 1,
|
|
317
|
-
file: context.node.getSourceFile()
|
|
318
|
-
}, toTSLocation(node.callTarget)), {
|
|
319
|
-
messageText: `Expected ${requiredArgs.length} argument(s), got ${actualArgs.length}`
|
|
320
|
-
}));
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
} else {
|
|
324
|
-
diags.push(__spreadProps(__spreadValues({
|
|
325
|
-
category: ts__namespace.DiagnosticCategory.Error,
|
|
326
|
-
code: 1,
|
|
327
|
-
file: context.node.getSourceFile()
|
|
328
|
-
}, toTSLocation(node.callTarget)), {
|
|
329
|
-
messageText: `Unknown expression ${exprName}`
|
|
330
|
-
}));
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
return diags;
|
|
334
|
-
}
|
|
335
|
-
getSemanticDiagnostics(context) {
|
|
336
|
-
if (this._plugins.length === 0) {
|
|
337
|
-
return [];
|
|
338
|
-
}
|
|
339
|
-
const parsed = player.parseExpression(context.text.trim(), { strict: false });
|
|
340
|
-
return this.getDiagnosticsForNode(context, parsed);
|
|
341
|
-
}
|
|
342
|
-
getSyntacticDiagnostics(context) {
|
|
343
|
-
const parsed = player.parseExpression(context.text.trim(), { strict: false });
|
|
344
|
-
if (parsed.error) {
|
|
345
|
-
return [
|
|
346
|
-
__spreadProps(__spreadValues({
|
|
347
|
-
category: ts__namespace.DiagnosticCategory.Error,
|
|
348
|
-
code: 1,
|
|
349
|
-
file: context.node.getSourceFile()
|
|
350
|
-
}, toTSLocation(parsed)), {
|
|
351
|
-
messageText: parsed.error.message
|
|
352
|
-
})
|
|
353
|
-
];
|
|
354
|
-
}
|
|
355
|
-
return [];
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
class LSPLogger {
|
|
360
|
-
constructor(info) {
|
|
361
|
-
this.info = info;
|
|
362
|
-
}
|
|
363
|
-
log(msg) {
|
|
364
|
-
this.info.project.projectService.logger.info(`[player-expr-lsp] ${msg}`);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
class Plugin {
|
|
369
|
-
constructor(initOptions) {
|
|
370
|
-
this.initOptions = initOptions;
|
|
371
|
-
}
|
|
372
|
-
create(info) {
|
|
373
|
-
const logger = new LSPLogger(info);
|
|
374
|
-
this.logger = logger;
|
|
375
|
-
const templateService = new ExpressionLanguageService({ logger });
|
|
376
|
-
this.templateService = templateService;
|
|
377
|
-
return typescriptTemplateLanguageServiceDecorator.decorateWithTemplateLanguageService(this.initOptions.typescript, info.languageService, info.project, templateService, {
|
|
378
|
-
tags: ["e", "expr", "expression"],
|
|
379
|
-
enableForStringWithSubstitutions: true
|
|
380
|
-
}, { logger });
|
|
381
|
-
}
|
|
382
|
-
onConfigurationChanged(config) {
|
|
383
|
-
var _a;
|
|
384
|
-
(_a = this.templateService) == null ? void 0 : _a.setConfig(config);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
function init(mod) {
|
|
388
|
-
return new Plugin(mod);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
module.exports = init;
|
|
392
|
-
//# sourceMappingURL=index.cjs.js.map
|