@ui5/webcomponents-tools 2.15.0 → 2.16.0-rc.1
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/CHANGELOG.md +19 -0
- package/components-package/nps.js +0 -1
- package/lib/cem/cem.js +1 -1
- package/lib/cem/patch/@custom-elements-manifest/analyzer/cli.js +128 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/package.json +59 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/browser-entrypoint.js +23 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/create.js +117 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/arrow-function.js +26 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/class-jsdoc.js +157 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/classes.js +20 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createArrowFunction.js +17 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createAttribute.js +24 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createClass.js +301 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createClassField.js +26 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createFunctionLike.js +73 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createMixin.js +33 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createVariable.js +22 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/handlers.js +338 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/custom-elements-define-calls.js +90 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/exports.js +156 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/function-like.js +24 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/mixins.js +29 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/reexported-wrapped-mixin-exports.js +84 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/variables.js +34 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/collect-phase/collect-imports.js +101 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst/catalyst.js +11 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst/controller.js +34 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst-major-2/catalyst.js +11 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst-major-2/controller.js +34 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/decorators/attr.js +53 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/decorators/custom-element-decorator.js +36 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/fast/fast.js +7 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/lit.js +13 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/member-denylist.js +21 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/method-denylist.js +20 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/property-decorator.js +94 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/static-properties.js +121 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/utils.js +66 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/stencil/stencil.js +129 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/index.js +80 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/cleanup-classes.js +25 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/field-denylist.js +22 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/method-denylist.js +25 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/apply-inheritance.js +78 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/is-custom-element.js +34 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/link-class-to-tagname.js +27 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/remove-unexported-declarations.js +23 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/resolve-initializers.js +52 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/ast-helpers.js +186 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/cli-helpers.js +164 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/exports.js +44 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/find-external-manifests.js +67 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/imports.js +25 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/index.js +71 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/jsdoc.js +19 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/manifest-helpers.js +194 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/mixins.js +112 -0
- package/package.json +3 -3
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { parse } from 'comment-parser';
|
|
3
|
+
|
|
4
|
+
import { has, resolveModuleOrPackageSpecifier, safe } from '../../../utils/index.js';
|
|
5
|
+
import { handleJsDocType, normalizeDescription } from '../../../utils/jsdoc.js';
|
|
6
|
+
import { isWellKnownType } from '../../../utils/ast-helpers.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @example static foo;
|
|
10
|
+
* @example public foo;
|
|
11
|
+
* @example private foo;
|
|
12
|
+
* @example protected foo;
|
|
13
|
+
*/
|
|
14
|
+
export function handleModifiers(doc, node) {
|
|
15
|
+
node?.modifiers?.forEach(modifier => {
|
|
16
|
+
if(modifier?.kind === ts.SyntaxKind.StaticKeyword) {
|
|
17
|
+
doc.static = true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (modifier?.kind === ts.SyntaxKind.ReadonlyKeyword) {
|
|
21
|
+
doc.readonly = true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
switch (modifier.kind) {
|
|
25
|
+
case ts.SyntaxKind.PublicKeyword:
|
|
26
|
+
doc.privacy = 'public';
|
|
27
|
+
break;
|
|
28
|
+
case ts.SyntaxKind.PrivateKeyword:
|
|
29
|
+
doc.privacy = 'private';
|
|
30
|
+
break;
|
|
31
|
+
case ts.SyntaxKind.ProtectedKeyword:
|
|
32
|
+
doc.privacy = 'protected';
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (node.name?.text?.startsWith('#')) {
|
|
38
|
+
doc.privacy = 'private';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return doc;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Handles JsDoc
|
|
46
|
+
*/
|
|
47
|
+
export function handleJsDoc(doc, node) {
|
|
48
|
+
node?.jsDoc?.forEach(jsDocComment => {
|
|
49
|
+
if(jsDocComment?.comment) {
|
|
50
|
+
if(has(jsDocComment?.comment)) {
|
|
51
|
+
doc.description = jsDocComment.comment.map(com => `${safe(() => com?.name?.getText()) ?? ''}${com.text}`).join('');
|
|
52
|
+
} else {
|
|
53
|
+
doc.description = normalizeDescription(jsDocComment.comment);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
jsDocComment?.tags?.forEach(tag => {
|
|
58
|
+
/** @readonly */
|
|
59
|
+
if(tag.kind === ts.SyntaxKind.JSDocReadonlyTag) {
|
|
60
|
+
doc.readonly = true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @param */
|
|
64
|
+
if(tag.kind === ts.SyntaxKind.JSDocParameterTag) {
|
|
65
|
+
const parameter = doc?.parameters?.find(parameter => parameter.name === tag.name.text);
|
|
66
|
+
const parameterAlreadyExists = !!parameter;
|
|
67
|
+
const parameterTemplate = parameter || {};
|
|
68
|
+
|
|
69
|
+
if(tag?.comment) {
|
|
70
|
+
parameterTemplate.description = normalizeDescription(tag.comment);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if(tag?.name) {
|
|
74
|
+
parameterTemplate.name = tag.name.getText();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* If its bracketed, that means its optional
|
|
79
|
+
* @example [foo]
|
|
80
|
+
*/
|
|
81
|
+
if(tag?.isBracketed) {
|
|
82
|
+
parameterTemplate.optional = true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if(tag?.typeExpression) {
|
|
86
|
+
parameterTemplate.type = {
|
|
87
|
+
text: handleJsDocType(tag.typeExpression.type.getText())
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if(!parameterAlreadyExists) {
|
|
92
|
+
doc.parameters = [...(doc?.parameters || []), parameterTemplate];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** @returns */
|
|
97
|
+
if(tag.kind === ts.SyntaxKind.JSDocReturnTag) {
|
|
98
|
+
doc.return = {
|
|
99
|
+
type: {
|
|
100
|
+
text: handleJsDocType(tag?.typeExpression?.type?.getText())
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** @type */
|
|
106
|
+
if(tag.kind === ts.SyntaxKind.JSDocTypeTag) {
|
|
107
|
+
if(tag?.comment) {
|
|
108
|
+
doc.description = normalizeDescription(tag.comment);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
doc.type = {
|
|
112
|
+
text: handleJsDocType(tag.typeExpression.type.getText())
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** @reflect */
|
|
117
|
+
if(safe(() => tag?.tagName?.getText()) === 'reflect' && doc?.kind === 'field') {
|
|
118
|
+
doc.reflects = true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** @summary */
|
|
122
|
+
if(safe(() => tag?.tagName?.getText()) === 'summary') {
|
|
123
|
+
doc.summary = tag.comment;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** @deprecated */
|
|
127
|
+
if(safe(() => tag?.tagName?.getText()) === 'deprecated') {
|
|
128
|
+
doc.deprecated = tag.comment || "true";
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** @default */
|
|
132
|
+
if (safe(() => tag?.tagName?.getText()) === 'default' && doc?.kind === 'field') {
|
|
133
|
+
doc.default ??= tag.comment;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Overwrite privacy
|
|
138
|
+
* @public
|
|
139
|
+
* @private
|
|
140
|
+
* @protected
|
|
141
|
+
*/
|
|
142
|
+
switch(tag.kind) {
|
|
143
|
+
case ts.SyntaxKind.JSDocPublicTag:
|
|
144
|
+
doc.privacy = 'public';
|
|
145
|
+
break;
|
|
146
|
+
case ts.SyntaxKind.JSDocPrivateTag:
|
|
147
|
+
doc.privacy = 'private';
|
|
148
|
+
break;
|
|
149
|
+
case ts.SyntaxKind.JSDocProtectedTag:
|
|
150
|
+
doc.privacy = 'protected';
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
return doc;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Creates a mixin for inside a classDoc
|
|
163
|
+
*/
|
|
164
|
+
export function createClassDeclarationMixin(name, moduleDoc, context) {
|
|
165
|
+
const mixin = {
|
|
166
|
+
name,
|
|
167
|
+
...resolveModuleOrPackageSpecifier(moduleDoc, context, name)
|
|
168
|
+
};
|
|
169
|
+
return mixin;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Handles mixins and superclass
|
|
174
|
+
*/
|
|
175
|
+
export function handleHeritage(classTemplate, moduleDoc, context, node) {
|
|
176
|
+
node?.heritageClauses?.forEach((clause) => {
|
|
177
|
+
/* Ignoring `ImplementsKeyword` for now, future revisions may retrieve docs per-field for the implemented methods. */
|
|
178
|
+
if (clause.token !== ts.SyntaxKind.ExtendsKeyword) return;
|
|
179
|
+
|
|
180
|
+
clause?.types?.forEach((type) => {
|
|
181
|
+
const mixins = [];
|
|
182
|
+
let node = type.expression;
|
|
183
|
+
let superClass;
|
|
184
|
+
|
|
185
|
+
/* gather mixin calls */
|
|
186
|
+
if (ts.isCallExpression(node)) {
|
|
187
|
+
const mixinName = node.expression.getText();
|
|
188
|
+
mixins.push(createClassDeclarationMixin(mixinName, moduleDoc, context))
|
|
189
|
+
while (ts.isCallExpression(node.arguments[0])) {
|
|
190
|
+
node = node.arguments[0];
|
|
191
|
+
const mixinName = node.expression.getText();
|
|
192
|
+
mixins.push(createClassDeclarationMixin(mixinName, moduleDoc, context));
|
|
193
|
+
}
|
|
194
|
+
superClass = node.arguments[0].text;
|
|
195
|
+
} else {
|
|
196
|
+
superClass = node.text;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (has(mixins)) {
|
|
200
|
+
classTemplate.mixins = mixins;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
classTemplate.superclass = {
|
|
204
|
+
name: superClass,
|
|
205
|
+
...resolveModuleOrPackageSpecifier(moduleDoc, context, superClass)
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
if(superClass === 'HTMLElement') {
|
|
209
|
+
delete classTemplate.superclass.module;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
return classTemplate;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Handles fields that have an @attr jsdoc annotation and gets the attribute name (if specified) and the description
|
|
219
|
+
* @example @attr my-attr this is the attr description
|
|
220
|
+
*/
|
|
221
|
+
export function handleAttrJsDoc(node, doc) {
|
|
222
|
+
node?.jsDoc?.forEach(jsDoc => {
|
|
223
|
+
const docs = parse(jsDoc?.getFullText())?.find(doc => doc?.tags?.some(({tag}) => ["attribute", "attr"].includes(tag)));
|
|
224
|
+
const attrTag = docs?.tags?.find(({tag}) => ["attribute", "attr"].includes(tag));
|
|
225
|
+
|
|
226
|
+
if(attrTag?.name) {
|
|
227
|
+
doc.name = attrTag.name;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if(attrTag?.description) {
|
|
231
|
+
doc.description = normalizeDescription(attrTag.description);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
return doc;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function handleTypeInference(doc, node) {
|
|
239
|
+
const n = node?.initializer || node;
|
|
240
|
+
switch(n?.kind) {
|
|
241
|
+
case ts.SyntaxKind.TrueKeyword:
|
|
242
|
+
case ts.SyntaxKind.FalseKeyword:
|
|
243
|
+
doc.type = { text: "boolean" }
|
|
244
|
+
break;
|
|
245
|
+
case ts.SyntaxKind.StringLiteral:
|
|
246
|
+
doc.type = { text: "string" }
|
|
247
|
+
break;
|
|
248
|
+
case ts.SyntaxKind.PrefixUnaryExpression:
|
|
249
|
+
doc.type = n?.operator === ts.SyntaxKind.ExclamationToken ? { text: "boolean" } : { text: "number" };
|
|
250
|
+
break;
|
|
251
|
+
case ts.SyntaxKind.NumericLiteral:
|
|
252
|
+
doc.type = { text: "number" }
|
|
253
|
+
break;
|
|
254
|
+
case ts.SyntaxKind.NullKeyword:
|
|
255
|
+
doc.type = { text: "null" }
|
|
256
|
+
break;
|
|
257
|
+
case ts.SyntaxKind.ArrayLiteralExpression:
|
|
258
|
+
doc.type = { text: "array" }
|
|
259
|
+
break;
|
|
260
|
+
case ts.SyntaxKind.ObjectLiteralExpression:
|
|
261
|
+
doc.type = { text: "object" }
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
return doc;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* For `as const` and namespace/enum types
|
|
269
|
+
* @example class A { b = 'b' as const }
|
|
270
|
+
* @example class A { b = B.b }
|
|
271
|
+
*/
|
|
272
|
+
export function handleWellKnownTypes(doc, node) {
|
|
273
|
+
if (!!node.initializer?.expression) {
|
|
274
|
+
const text = node?.initializer?.expression?.getText();
|
|
275
|
+
if (isWellKnownType(node)) {
|
|
276
|
+
doc.type = { text };
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return doc;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function handleDefaultValue(doc, node, expression) {
|
|
283
|
+
/**
|
|
284
|
+
* In case of a class field node?.initializer
|
|
285
|
+
* In case of a property assignment in constructor node?.expression?.right
|
|
286
|
+
*/
|
|
287
|
+
const initializer = node?.initializer || expression?.right;
|
|
288
|
+
|
|
289
|
+
/** Ignore the following */
|
|
290
|
+
if(initializer?.kind === ts.SyntaxKind.BinaryExpression) return doc;
|
|
291
|
+
if(initializer?.kind === ts.SyntaxKind.ConditionalExpression) return doc;
|
|
292
|
+
if(initializer?.kind === ts.SyntaxKind.PropertyAccessExpression) return doc;
|
|
293
|
+
if(initializer?.kind === ts.SyntaxKind.CallExpression) return doc;
|
|
294
|
+
if(initializer?.kind === ts.SyntaxKind.ArrowFunction) return doc;
|
|
295
|
+
|
|
296
|
+
let defaultValue;
|
|
297
|
+
/**
|
|
298
|
+
* Check if value has `as const`
|
|
299
|
+
* @example const foo = 'foo' as const;
|
|
300
|
+
*/
|
|
301
|
+
if(initializer?.kind === ts.SyntaxKind.AsExpression) {
|
|
302
|
+
defaultValue = initializer?.expression?.getText()
|
|
303
|
+
} else {
|
|
304
|
+
defaultValue = initializer?.getText()
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if(defaultValue) {
|
|
308
|
+
doc.default = defaultValue.replace(/\s+/g, ' ').trim();
|
|
309
|
+
}
|
|
310
|
+
return doc;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Add TS type
|
|
315
|
+
* @example class Foo { bar: string = ''; }
|
|
316
|
+
*/
|
|
317
|
+
export function handleExplicitType(doc, node) {
|
|
318
|
+
if(node.type) {
|
|
319
|
+
doc.type = { text: node.type.getText() }
|
|
320
|
+
|
|
321
|
+
if(node?.questionToken) {
|
|
322
|
+
doc.type.text += ' | undefined';
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return doc;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* if is private field
|
|
331
|
+
* @example class Foo { #bar = ''; }
|
|
332
|
+
*/
|
|
333
|
+
export function handlePrivateMember(doc, node) {
|
|
334
|
+
if (ts.isPrivateIdentifier(node.name)) {
|
|
335
|
+
doc.privacy = 'private';
|
|
336
|
+
}
|
|
337
|
+
return doc;
|
|
338
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { getDeclarationInFile, hasIgnoreJSDoc, isCustomElementsDefineCall } from '../../utils/ast-helpers.js';
|
|
2
|
+
import { resolveModuleOrPackageSpecifier } from '../../utils/index.js';
|
|
3
|
+
import { createClass } from './creators/createClass.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CUSTOM-ELEMENTS-DEFINE-CALLS
|
|
7
|
+
*
|
|
8
|
+
* Analyzes calls for:
|
|
9
|
+
* @example customElements.define()
|
|
10
|
+
* @example window.customElements.define()
|
|
11
|
+
*/
|
|
12
|
+
export function customElementsDefineCallsPlugin() {
|
|
13
|
+
let counter;
|
|
14
|
+
return {
|
|
15
|
+
name: 'CORE - CUSTOM-ELEMENTS-DEFINE-CALLS',
|
|
16
|
+
analyzePhase({ts, node, moduleDoc, context}){
|
|
17
|
+
if(node?.kind === ts.SyntaxKind.SourceFile) {
|
|
18
|
+
counter = 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (hasIgnoreJSDoc(node))
|
|
22
|
+
return;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @example customElements.define('my-el', MyEl);
|
|
26
|
+
* @example window.customElements.define('my-el', MyEl);
|
|
27
|
+
*/
|
|
28
|
+
if(isCustomElementsDefineCall(node)) {
|
|
29
|
+
const classArg = node.parent.arguments[1];
|
|
30
|
+
let isAnonymousClass = classArg?.kind === ts.SyntaxKind.ClassExpression;
|
|
31
|
+
let isUnnamed = classArg?.name === undefined;
|
|
32
|
+
|
|
33
|
+
if(isAnonymousClass) {
|
|
34
|
+
const klass = createClass(classArg, moduleDoc, context);
|
|
35
|
+
|
|
36
|
+
if(isUnnamed) {
|
|
37
|
+
klass.name = `anonymous_${counter}`;
|
|
38
|
+
}
|
|
39
|
+
moduleDoc.declarations.push(klass);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let elementClass;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @example customElements.define('m-e', class extends HTMLElement{})
|
|
46
|
+
* ^
|
|
47
|
+
*/
|
|
48
|
+
if(isUnnamed) {
|
|
49
|
+
elementClass = `anonymous_${counter}`;
|
|
50
|
+
counter = counter + 1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @example customElements.define('m-e', MyElement)
|
|
55
|
+
* ^^^^^^^^^
|
|
56
|
+
*/
|
|
57
|
+
if(node?.parent?.arguments?.[1]?.text) {
|
|
58
|
+
elementClass = node.parent.arguments[1].text;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @example customElements.define('m-e', class MyElement extends HTMLElement{})
|
|
63
|
+
* ^^^^^^^^^
|
|
64
|
+
*/
|
|
65
|
+
if(classArg?.name) {
|
|
66
|
+
elementClass = classArg?.name?.getText();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const elementTag = node.parent.arguments[0].text;
|
|
70
|
+
|
|
71
|
+
const klass = getDeclarationInFile(elementClass, node?.getSourceFile());
|
|
72
|
+
|
|
73
|
+
if (hasIgnoreJSDoc(klass))
|
|
74
|
+
return;
|
|
75
|
+
|
|
76
|
+
const definitionDoc = {
|
|
77
|
+
kind: 'custom-element-definition',
|
|
78
|
+
name: elementTag,
|
|
79
|
+
declaration: {
|
|
80
|
+
name: elementClass,
|
|
81
|
+
...resolveModuleOrPackageSpecifier(moduleDoc, context, elementClass)
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
moduleDoc.exports = [...(moduleDoc.exports || []), definitionDoc];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/exports.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { getDeclarationInFile, hasIgnoreJSDoc } from '../../utils/ast-helpers.js';
|
|
2
|
+
import {
|
|
3
|
+
hasExportModifier,
|
|
4
|
+
hasDefaultModifier,
|
|
5
|
+
hasNamedExports,
|
|
6
|
+
isReexport,
|
|
7
|
+
} from '../../utils/exports.js';
|
|
8
|
+
import { isBareModuleSpecifier } from '../../utils/index.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* EXPORTS
|
|
12
|
+
*
|
|
13
|
+
* Analyzes a modules exports and adds them to the moduleDoc
|
|
14
|
+
*/
|
|
15
|
+
export function exportsPlugin() {
|
|
16
|
+
return {
|
|
17
|
+
name: 'CORE - EXPORTS',
|
|
18
|
+
analyzePhase({ts, node, moduleDoc}){
|
|
19
|
+
if(hasIgnoreJSDoc(node)) return;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @example export const foo = '';
|
|
23
|
+
*/
|
|
24
|
+
if(hasExportModifier(node) && ts.isVariableStatement(node)) {
|
|
25
|
+
node?.declarationList?.declarations?.forEach(declaration => {
|
|
26
|
+
const _export = {
|
|
27
|
+
kind: 'js',
|
|
28
|
+
name: declaration.name.getText(),
|
|
29
|
+
declaration: {
|
|
30
|
+
name: declaration.name.getText(),
|
|
31
|
+
module: moduleDoc.path,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
moduleDoc.exports = [...(moduleDoc.exports || []), _export];
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @example export default var1;
|
|
41
|
+
*/
|
|
42
|
+
if (node.kind === ts.SyntaxKind.ExportAssignment) {
|
|
43
|
+
const _export = {
|
|
44
|
+
kind: 'js',
|
|
45
|
+
name: 'default',
|
|
46
|
+
declaration: {
|
|
47
|
+
name: node.expression.text,
|
|
48
|
+
module: moduleDoc.path,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
moduleDoc.exports = [...(moduleDoc.exports || []), _export];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (node.kind === ts.SyntaxKind.ExportDeclaration) {
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @example export { var1, var2 };
|
|
58
|
+
*/
|
|
59
|
+
if (hasNamedExports(node) && !isReexport(node)) {
|
|
60
|
+
node.exportClause?.elements?.forEach((element) => {
|
|
61
|
+
if (hasIgnoreJSDoc(element) || hasIgnoreJSDoc(getDeclarationInFile(element, node.getSourceFile())))
|
|
62
|
+
return;
|
|
63
|
+
|
|
64
|
+
const _export = {
|
|
65
|
+
kind: 'js',
|
|
66
|
+
name: element.name.getText(),
|
|
67
|
+
declaration: {
|
|
68
|
+
name: element.propertyName?.getText() || element.name.getText(),
|
|
69
|
+
module: moduleDoc.path,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
moduleDoc.exports = [...(moduleDoc.exports || []), _export];
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @example export * from 'foo';
|
|
79
|
+
* @example export * from './my-module.js';
|
|
80
|
+
*/
|
|
81
|
+
if (isReexport(node) && !hasNamedExports(node)) {
|
|
82
|
+
const _export = {
|
|
83
|
+
kind: 'js',
|
|
84
|
+
name: '*',
|
|
85
|
+
declaration: {
|
|
86
|
+
name: '*',
|
|
87
|
+
package: node.moduleSpecifier.getText().replace(/'/g, ''),
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
moduleDoc.exports = [...(moduleDoc.exports || []), _export];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @example export { var1, var2 } from 'foo';
|
|
95
|
+
* @example export { var1, var2 } from './my-module.js';
|
|
96
|
+
*/
|
|
97
|
+
if (isReexport(node) && hasNamedExports(node)) {
|
|
98
|
+
node.exportClause?.elements?.forEach((element) => {
|
|
99
|
+
const _export = {
|
|
100
|
+
kind: 'js',
|
|
101
|
+
name: element.name.getText(),
|
|
102
|
+
declaration: {
|
|
103
|
+
name: element.propertyName?.getText() || element.name.getText(),
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
if (isBareModuleSpecifier(node.moduleSpecifier.getText())) {
|
|
108
|
+
_export.declaration.package = node.moduleSpecifier.getText().replace(/'/g, '');
|
|
109
|
+
} else {
|
|
110
|
+
_export.declaration.module = node.moduleSpecifier.getText().replace(/'/g, '');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
moduleDoc.exports = [...(moduleDoc.exports || []), _export];
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @example export function foo() {}
|
|
120
|
+
*/
|
|
121
|
+
if (node.kind === ts.SyntaxKind.FunctionDeclaration) {
|
|
122
|
+
if (hasExportModifier(node)) {
|
|
123
|
+
const isDefault = hasDefaultModifier(node);
|
|
124
|
+
const _export = {
|
|
125
|
+
kind: 'js',
|
|
126
|
+
name: isDefault ? 'default' : node.name?.getText() || '',
|
|
127
|
+
declaration: {
|
|
128
|
+
name: node.name?.getText() || '',
|
|
129
|
+
module: moduleDoc.path,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
moduleDoc.exports = [...(moduleDoc.exports || []), _export];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @example export class Class1 {}
|
|
139
|
+
*/
|
|
140
|
+
if (node.kind === ts.SyntaxKind.ClassDeclaration) {
|
|
141
|
+
if (hasExportModifier(node)) {
|
|
142
|
+
const isDefault = hasDefaultModifier(node);
|
|
143
|
+
const _export = {
|
|
144
|
+
kind: 'js',
|
|
145
|
+
name: isDefault ? 'default' : node?.name?.text || '',
|
|
146
|
+
declaration: {
|
|
147
|
+
name: node?.name?.text || '',
|
|
148
|
+
module: moduleDoc.path,
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
moduleDoc.exports = [...(moduleDoc.exports || []), _export];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/function-like.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createFunctionLike } from './creators/createFunctionLike.js';
|
|
2
|
+
import { isMixin } from '../../utils/mixins.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* functionLikePlugin
|
|
6
|
+
*
|
|
7
|
+
* handles functionLikes such as class methods and functions
|
|
8
|
+
* does NOT handle arrow functions
|
|
9
|
+
*/
|
|
10
|
+
export function functionLikePlugin() {
|
|
11
|
+
return {
|
|
12
|
+
name: 'CORE - FUNCTION-LIKE',
|
|
13
|
+
analyzePhase({ts, node, moduleDoc}){
|
|
14
|
+
switch(node.kind) {
|
|
15
|
+
case ts.SyntaxKind.FunctionDeclaration:
|
|
16
|
+
if(!isMixin(node)) {
|
|
17
|
+
const functionLike = createFunctionLike(node);
|
|
18
|
+
moduleDoc.declarations.push(functionLike);
|
|
19
|
+
}
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { extractMixinNodes, isMixin } from '../../utils/mixins.js';
|
|
2
|
+
import { createMixin } from './creators/createMixin.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* mixinPlugin
|
|
6
|
+
*
|
|
7
|
+
* handles mixins
|
|
8
|
+
*/
|
|
9
|
+
export function mixinPlugin() {
|
|
10
|
+
return {
|
|
11
|
+
name: 'CORE - MIXINS',
|
|
12
|
+
analyzePhase({ts, node, moduleDoc, context}){
|
|
13
|
+
switch(node.kind) {
|
|
14
|
+
case ts.SyntaxKind.VariableStatement:
|
|
15
|
+
case ts.SyntaxKind.FunctionDeclaration:
|
|
16
|
+
/**
|
|
17
|
+
* Try to extract mixin nodes, if its a mixin
|
|
18
|
+
*/
|
|
19
|
+
if(isMixin(node)) {
|
|
20
|
+
const { mixinFunction, mixinClass } = extractMixinNodes(node);
|
|
21
|
+
let mixin = createMixin(mixinFunction, mixinClass, moduleDoc, context);
|
|
22
|
+
moduleDoc.declarations.push(mixin);
|
|
23
|
+
}
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|