@oicl-lit/analyzer 0.14.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.
Files changed (115) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +76 -0
  3. package/index.d.ts +10 -0
  4. package/index.d.ts.map +1 -0
  5. package/index.js +10 -0
  6. package/index.js.map +1 -0
  7. package/lib/analyzer.d.ts +47 -0
  8. package/lib/analyzer.d.ts.map +1 -0
  9. package/lib/analyzer.js +90 -0
  10. package/lib/analyzer.js.map +1 -0
  11. package/lib/custom-elements/custom-elements.d.ts +33 -0
  12. package/lib/custom-elements/custom-elements.d.ts.map +1 -0
  13. package/lib/custom-elements/custom-elements.js +124 -0
  14. package/lib/custom-elements/custom-elements.js.map +1 -0
  15. package/lib/custom-elements/events.d.ts +19 -0
  16. package/lib/custom-elements/events.d.ts.map +1 -0
  17. package/lib/custom-elements/events.js +25 -0
  18. package/lib/custom-elements/events.js.map +1 -0
  19. package/lib/diagnostic-code.d.ts +21 -0
  20. package/lib/diagnostic-code.d.ts.map +1 -0
  21. package/lib/diagnostic-code.js +20 -0
  22. package/lib/diagnostic-code.js.map +1 -0
  23. package/lib/errors.d.ts +24 -0
  24. package/lib/errors.d.ts.map +1 -0
  25. package/lib/errors.js +17 -0
  26. package/lib/errors.js.map +1 -0
  27. package/lib/javascript/classes.d.ts +50 -0
  28. package/lib/javascript/classes.d.ts.map +1 -0
  29. package/lib/javascript/classes.js +307 -0
  30. package/lib/javascript/classes.js.map +1 -0
  31. package/lib/javascript/functions.d.ts +31 -0
  32. package/lib/javascript/functions.d.ts.map +1 -0
  33. package/lib/javascript/functions.js +144 -0
  34. package/lib/javascript/functions.js.map +1 -0
  35. package/lib/javascript/jsdoc.d.ts +67 -0
  36. package/lib/javascript/jsdoc.d.ts.map +1 -0
  37. package/lib/javascript/jsdoc.js +244 -0
  38. package/lib/javascript/jsdoc.js.map +1 -0
  39. package/lib/javascript/mixins.d.ts +45 -0
  40. package/lib/javascript/mixins.d.ts.map +1 -0
  41. package/lib/javascript/mixins.js +147 -0
  42. package/lib/javascript/mixins.js.map +1 -0
  43. package/lib/javascript/modules.d.ts +42 -0
  44. package/lib/javascript/modules.d.ts.map +1 -0
  45. package/lib/javascript/modules.js +277 -0
  46. package/lib/javascript/modules.js.map +1 -0
  47. package/lib/javascript/packages.d.ts +18 -0
  48. package/lib/javascript/packages.d.ts.map +1 -0
  49. package/lib/javascript/packages.js +53 -0
  50. package/lib/javascript/packages.js.map +1 -0
  51. package/lib/javascript/variables.d.ts +29 -0
  52. package/lib/javascript/variables.d.ts.map +1 -0
  53. package/lib/javascript/variables.js +143 -0
  54. package/lib/javascript/variables.js.map +1 -0
  55. package/lib/lit/decorators.d.ts +36 -0
  56. package/lib/lit/decorators.d.ts.map +1 -0
  57. package/lib/lit/decorators.js +32 -0
  58. package/lib/lit/decorators.js.map +1 -0
  59. package/lib/lit/lit-element.d.ts +39 -0
  60. package/lib/lit/lit-element.d.ts.map +1 -0
  61. package/lib/lit/lit-element.js +96 -0
  62. package/lib/lit/lit-element.js.map +1 -0
  63. package/lib/lit/modules.d.ts +28 -0
  64. package/lib/lit/modules.d.ts.map +1 -0
  65. package/lib/lit/modules.js +62 -0
  66. package/lib/lit/modules.js.map +1 -0
  67. package/lib/lit/properties.d.ts +43 -0
  68. package/lib/lit/properties.d.ts.map +1 -0
  69. package/lib/lit/properties.js +268 -0
  70. package/lib/lit/properties.js.map +1 -0
  71. package/lib/lit/template.d.ts +110 -0
  72. package/lib/lit/template.d.ts.map +1 -0
  73. package/lib/lit/template.js +412 -0
  74. package/lib/lit/template.js.map +1 -0
  75. package/lib/lit-element/decorators.d.ts +11 -0
  76. package/lib/lit-element/decorators.d.ts.map +1 -0
  77. package/lib/lit-element/decorators.js +11 -0
  78. package/lib/lit-element/decorators.js.map +1 -0
  79. package/lib/lit-element/lit-element.d.ts +11 -0
  80. package/lib/lit-element/lit-element.d.ts.map +1 -0
  81. package/lib/lit-element/lit-element.js +11 -0
  82. package/lib/lit-element/lit-element.js.map +1 -0
  83. package/lib/lit-element/properties.d.ts +11 -0
  84. package/lib/lit-element/properties.d.ts.map +1 -0
  85. package/lib/lit-element/properties.js +11 -0
  86. package/lib/lit-element/properties.js.map +1 -0
  87. package/lib/model.d.ts +506 -0
  88. package/lib/model.d.ts.map +1 -0
  89. package/lib/model.js +392 -0
  90. package/lib/model.js.map +1 -0
  91. package/lib/package-analyzer.d.ts +25 -0
  92. package/lib/package-analyzer.d.ts.map +1 -0
  93. package/lib/package-analyzer.js +81 -0
  94. package/lib/package-analyzer.js.map +1 -0
  95. package/lib/paths.d.ts +24 -0
  96. package/lib/paths.d.ts.map +1 -0
  97. package/lib/paths.js +35 -0
  98. package/lib/paths.js.map +1 -0
  99. package/lib/references.d.ts +107 -0
  100. package/lib/references.d.ts.map +1 -0
  101. package/lib/references.js +345 -0
  102. package/lib/references.js.map +1 -0
  103. package/lib/types.d.ts +25 -0
  104. package/lib/types.d.ts.map +1 -0
  105. package/lib/types.js +257 -0
  106. package/lib/types.js.map +1 -0
  107. package/lib/utils.d.ts +22 -0
  108. package/lib/utils.d.ts.map +1 -0
  109. package/lib/utils.js +51 -0
  110. package/lib/utils.js.map +1 -0
  111. package/package-analyzer.d.ts +8 -0
  112. package/package-analyzer.d.ts.map +1 -0
  113. package/package-analyzer.js +8 -0
  114. package/package-analyzer.js.map +1 -0
  115. package/package.json +109 -0
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ /**
7
+ * @fileoverview
8
+ *
9
+ * Utilities for analyzing JSDoc comments
10
+ */
11
+ import type ts from 'typescript';
12
+ import { Described, TypedNamedDescribed, DeprecatableDescribed, AnalyzerInterface } from '../model.js';
13
+ export type TypeScript = typeof ts;
14
+ /**
15
+ * @fileoverview
16
+ *
17
+ * Utilities for parsing JSDoc comments.
18
+ */
19
+ /**
20
+ * Returns true if given node has a JSDoc tag
21
+ */
22
+ export declare const hasJSDocTag: (ts: TypeScript, node: ts.Node, tag: string) => boolean;
23
+ /**
24
+ * Parses name, type, and description from JSDoc tag for things like `@fires`.
25
+ *
26
+ * Supports the following patterns following the tag (TS parses the tag for us):
27
+ * * @fires event-name
28
+ * * @fires event-name description
29
+ * * @fires event-name - description
30
+ * * @fires event-name: description
31
+ * * @fires event-name {Type}
32
+ * * @fires event-name {Type} description
33
+ * * @fires event-name {Type} - description
34
+ * * @fires event-name {Type}: description
35
+ * * @fires {Type} event-name
36
+ * * @fires {Type} event-name description
37
+ * * @fires {Type} event-name - description
38
+ * * @fires {Type} event-name: description
39
+ * * @slot name
40
+ * * @slot name description
41
+ * * @slot name - description
42
+ * * @slot name: description
43
+ * * @cssProp [--name=default]
44
+ * * @cssProp [--name=default] description
45
+ * * @cssProp [--name=default] - description
46
+ * * @cssProp [--name=default]: description
47
+ * * @cssprop {<color>} [--name=default]
48
+ * * @cssprop {<color>} [--name=default] description
49
+ * * @cssprop {<color>} [--name=default] - description
50
+ * * @cssprop {<color>} [--name=default]: description
51
+ */
52
+ export declare const parseNamedTypedJSDocInfo: (tag: ts.JSDocTag, analyzer: AnalyzerInterface) => TypedNamedDescribed | undefined;
53
+ /**
54
+ * Parses the description from JSDoc tag for things like `@return`.
55
+ */
56
+ export declare const parseJSDocDescription: (tag: ts.JSDocTag, analyzer: AnalyzerInterface) => Described | undefined;
57
+ /**
58
+ * Parse summary, description, and deprecated information from JSDoc comments on
59
+ * a given node.
60
+ */
61
+ export declare const parseNodeJSDocInfo: (node: ts.Node, analyzer: AnalyzerInterface) => DeprecatableDescribed;
62
+ /**
63
+ * Parse summary, description, and deprecated information from JSDoc comments on
64
+ * a given source file.
65
+ */
66
+ export declare const parseModuleJSDocInfo: (sourceFile: ts.SourceFile, analyzer: AnalyzerInterface) => DeprecatableDescribed;
67
+ //# sourceMappingURL=jsdoc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsdoc.d.ts","sourceRoot":"","sources":["../../src/lib/javascript/jsdoc.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EAElB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,UAAU,GAAG,OAAO,EAAE,CAAC;AAEnC;;;;GAIG;AAEH;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,IAAI,UAAU,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,MAAM,YAErE,CAAC;AA0CF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,wBAAwB,GACnC,KAAK,EAAE,CAAC,QAAQ,EAChB,UAAU,iBAAiB,oCAiC5B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAChC,KAAK,EAAE,CAAC,QAAQ,EAChB,UAAU,iBAAiB,KAC1B,SAAS,GAAG,SAMd,CAAC;AAoFF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,EAAE,CAAC,IAAI,EACb,UAAU,iBAAiB,KAC1B,qBA+BF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAC/B,YAAY,EAAE,CAAC,UAAU,EACzB,UAAU,iBAAiB,0BAmB5B,CAAC"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { createDiagnostic } from '../errors.js';
7
+ /**
8
+ * @fileoverview
9
+ *
10
+ * Utilities for parsing JSDoc comments.
11
+ */
12
+ /**
13
+ * Returns true if given node has a JSDoc tag
14
+ */
15
+ export const hasJSDocTag = (ts, node, tag) => {
16
+ return ts.getJSDocTags(node).some((t) => t.tagName.text === tag);
17
+ };
18
+ /**
19
+ * Remove line feeds from JSDoc comments, so they are normalized to
20
+ * unix `\n` line endings.
21
+ */
22
+ const normalizeLineEndings = (s) => s.replace(/\r/g, '').trim();
23
+ // Regex for parsing name, type, and description from JSDoc comments
24
+ const parseNameTypeDescRE = /^\[?(?<name>[^{}[\]\s=]+)(?:=(?<defaultValue>[^\]]+))?\]?(?:\s+{(?<type>.*)})?(?:\s+-\s+)?(?<description>[\s\S]*)$/m;
25
+ // Regex for parsing type, name, and description from JSDoc comments
26
+ const parseTypeNameDescRE = /^\{(?<type>.+)\}\s+\[?(?<name>[^{}[\]\s=]+)(?:=(?<defaultValue>[^\]]+))?\]?(?:\s+-\s+)?(?<description>[\s\S]*)$/m;
27
+ const getJSDocTagComment = (tag, analyzer) => {
28
+ let { comment } = tag;
29
+ if (comment === undefined) {
30
+ return undefined;
31
+ }
32
+ if (Array.isArray(comment)) {
33
+ comment = comment.map((c) => c.text).join('');
34
+ }
35
+ if (typeof comment !== 'string') {
36
+ analyzer.addDiagnostic(createDiagnostic({
37
+ typescript: analyzer.typescript,
38
+ node: tag,
39
+ message: `JSDoc error: unsupported node type`,
40
+ }));
41
+ return undefined;
42
+ }
43
+ return normalizeLineEndings(comment).trim();
44
+ };
45
+ const isModuleJSDocTag = (tag) => tag.tagName.text === 'module' ||
46
+ tag.tagName.text === 'fileoverview' ||
47
+ tag.tagName.text === 'packageDocumentation';
48
+ /**
49
+ * Parses name, type, and description from JSDoc tag for things like `@fires`.
50
+ *
51
+ * Supports the following patterns following the tag (TS parses the tag for us):
52
+ * * @fires event-name
53
+ * * @fires event-name description
54
+ * * @fires event-name - description
55
+ * * @fires event-name: description
56
+ * * @fires event-name {Type}
57
+ * * @fires event-name {Type} description
58
+ * * @fires event-name {Type} - description
59
+ * * @fires event-name {Type}: description
60
+ * * @fires {Type} event-name
61
+ * * @fires {Type} event-name description
62
+ * * @fires {Type} event-name - description
63
+ * * @fires {Type} event-name: description
64
+ * * @slot name
65
+ * * @slot name description
66
+ * * @slot name - description
67
+ * * @slot name: description
68
+ * * @cssProp [--name=default]
69
+ * * @cssProp [--name=default] description
70
+ * * @cssProp [--name=default] - description
71
+ * * @cssProp [--name=default]: description
72
+ * * @cssprop {<color>} [--name=default]
73
+ * * @cssprop {<color>} [--name=default] description
74
+ * * @cssprop {<color>} [--name=default] - description
75
+ * * @cssprop {<color>} [--name=default]: description
76
+ */
77
+ export const parseNamedTypedJSDocInfo = (tag, analyzer) => {
78
+ const comment = getJSDocTagComment(tag, analyzer);
79
+ if (comment == undefined) {
80
+ return undefined;
81
+ }
82
+ const regex = comment.charAt(0) === '{' ? parseTypeNameDescRE : parseNameTypeDescRE;
83
+ const nameTypeDesc = comment.match(regex);
84
+ if (nameTypeDesc === null) {
85
+ analyzer.addDiagnostic(createDiagnostic({
86
+ typescript: analyzer.typescript,
87
+ node: tag,
88
+ message: `JSDoc error: unexpected JSDoc format`,
89
+ }));
90
+ return undefined;
91
+ }
92
+ const { name, type, defaultValue, description } = nameTypeDesc.groups;
93
+ const info = { name };
94
+ if (description.length > 0) {
95
+ info.description = normalizeLineEndings(description);
96
+ }
97
+ if (defaultValue?.length > 0) {
98
+ info.default = defaultValue;
99
+ }
100
+ if (tag.tagName.text.toLowerCase().startsWith('cssprop')) {
101
+ info.syntax = type;
102
+ }
103
+ else {
104
+ info.type = type;
105
+ }
106
+ return info;
107
+ };
108
+ /**
109
+ * Parses the description from JSDoc tag for things like `@return`.
110
+ */
111
+ export const parseJSDocDescription = (tag, analyzer) => {
112
+ const description = getJSDocTagComment(tag, analyzer);
113
+ if (description == undefined || description.length === 0) {
114
+ return {};
115
+ }
116
+ return { description };
117
+ };
118
+ /**
119
+ * Add `@description`, `@summary`, and `@deprecated` JSDoc tag info to the
120
+ * given info object.
121
+ */
122
+ const addJSDocTagInfo = (info, jsDocTags, analyzer) => {
123
+ for (const tag of jsDocTags) {
124
+ const comment = getJSDocTagComment(tag, analyzer);
125
+ switch (tag.tagName.text.toLowerCase()) {
126
+ case 'description':
127
+ case 'fileoverview':
128
+ case 'packagedocumentation':
129
+ if (comment !== undefined) {
130
+ info.description = comment;
131
+ }
132
+ break;
133
+ case 'summary':
134
+ if (comment !== undefined) {
135
+ info.summary = comment;
136
+ }
137
+ break;
138
+ case 'deprecated':
139
+ info.deprecated = comment !== undefined ? comment : true;
140
+ break;
141
+ }
142
+ }
143
+ };
144
+ const moduleJSDocsMap = new WeakMap();
145
+ /**
146
+ * Returns the module-level JSDoc comment blocks for a given source file.
147
+ *
148
+ * Note that TS does not have a concept of module-level JSDoc; if it
149
+ * exists, it will always be attached to the first statement in the module.
150
+ *
151
+ * Thus, we parse module-level documentation using the following heuristic:
152
+ * - If the first statement only has one JSDoc block, it is only treated as
153
+ * module documentation if it contains a `@module`, `@fileoverview`, or
154
+ * `@packageDocumentation` tag. This is required to disambiguate a module
155
+ * description (with an undocumented first statement) from documentation
156
+ * for the first statement.
157
+ * - If the first statement has more than one JSDoc block, we collect all
158
+ * but the last and use those, regardless of whether they contain one
159
+ * of the above module-designating tags (the last one is assumed to belong
160
+ * to the first statement).
161
+ *
162
+ * This function caches its result against the given sourceFile, since it is
163
+ * needed both to find the module comment and to filter out module comments
164
+ * node comments.
165
+ */
166
+ const getModuleJSDocs = (typescript, sourceFile) => {
167
+ let moduleJSDocs = moduleJSDocsMap.get(sourceFile);
168
+ if (moduleJSDocs !== undefined) {
169
+ return moduleJSDocs;
170
+ }
171
+ // Get the first child in the sourceFile; note that returning the first child
172
+ // from `ts.forEachChild` is more robust than `sourceFile.getChildAt(0)`,
173
+ // since `forEachChild` flattens embedded arrays that the child APIs would
174
+ // otherwise return.
175
+ const firstChild = typescript.forEachChild(sourceFile, (n) => n);
176
+ if (firstChild === undefined) {
177
+ moduleJSDocs = [];
178
+ }
179
+ else {
180
+ // Get the JSDoc blocks attached to the first child (they oddly show up
181
+ // in the node's children)
182
+ const jsDocs = firstChild.getChildren().filter(typescript.isJSDoc);
183
+ // If there is more than one leading JSDoc block, grab all but the last,
184
+ // otherwise grab the one (see heuristic above)
185
+ moduleJSDocs = jsDocs.slice(0, jsDocs.length > 1 ? -1 : 1);
186
+ // If there is only one leading JSDoc block, it must have a module tag
187
+ if (jsDocs.length === 1 && !jsDocs[0].tags?.some(isModuleJSDocTag)) {
188
+ moduleJSDocs = [];
189
+ }
190
+ }
191
+ moduleJSDocsMap.set(sourceFile, moduleJSDocs);
192
+ return moduleJSDocs;
193
+ };
194
+ /**
195
+ * Parse summary, description, and deprecated information from JSDoc comments on
196
+ * a given node.
197
+ */
198
+ export const parseNodeJSDocInfo = (node, analyzer) => {
199
+ const info = {};
200
+ const moduleJSDocs = getModuleJSDocs(analyzer.typescript, node.getSourceFile());
201
+ // Module-level docs (that are explicitly tagged as such) may be
202
+ // attached to the first declaration if the declaration is undocumented,
203
+ // so we filter those out since they shouldn't apply to a
204
+ // declaration node
205
+ const jsDocTags = analyzer.typescript
206
+ .getJSDocTags(node)
207
+ .filter(({ parent }) => !moduleJSDocs.includes(parent));
208
+ if (jsDocTags !== undefined) {
209
+ addJSDocTagInfo(info, jsDocTags, analyzer);
210
+ }
211
+ if (info.description === undefined) {
212
+ const comment = normalizeLineEndings(node
213
+ .getChildren()
214
+ .filter(analyzer.typescript.isJSDoc)
215
+ .filter((c) => !moduleJSDocs.includes(c))
216
+ .map((n) => n.comment)
217
+ .filter((c) => c !== undefined)
218
+ .join('\n'));
219
+ if (comment.length > 0) {
220
+ info.description = comment;
221
+ }
222
+ }
223
+ return info;
224
+ };
225
+ /**
226
+ * Parse summary, description, and deprecated information from JSDoc comments on
227
+ * a given source file.
228
+ */
229
+ export const parseModuleJSDocInfo = (sourceFile, analyzer) => {
230
+ const moduleJSDocs = getModuleJSDocs(analyzer.typescript, sourceFile);
231
+ const info = {};
232
+ addJSDocTagInfo(info, moduleJSDocs.flatMap((m) => m.tags ?? []), analyzer);
233
+ if (info.description === undefined) {
234
+ const comment = moduleJSDocs
235
+ .map((d) => d.comment)
236
+ .filter((c) => c !== undefined)
237
+ .join('\n');
238
+ if (comment.length > 0) {
239
+ info.description = comment;
240
+ }
241
+ }
242
+ return info;
243
+ };
244
+ //# sourceMappingURL=jsdoc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsdoc.js","sourceRoot":"","sources":["../../src/lib/javascript/jsdoc.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAW9C;;;;GAIG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAc,EAAE,IAAa,EAAE,GAAW,EAAE,EAAE;IACxE,OAAO,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;AACnE,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,oBAAoB,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAExE,oEAAoE;AACpE,MAAM,mBAAmB,GACvB,qHAAqH,CAAC;AAExH,oEAAoE;AACpE,MAAM,mBAAmB,GACvB,kHAAkH,CAAC;AAErH,MAAM,kBAAkB,GAAG,CAAC,GAAgB,EAAE,QAA2B,EAAE,EAAE;IAC3E,IAAI,EAAC,OAAO,EAAC,GAAG,GAAG,CAAC;IACpB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,QAAQ,CAAC,aAAa,CACpB,gBAAgB,CAAC;YACf,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,oCAAoC;SAC9C,CAAC,CACH,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9C,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,GAAgB,EAAE,EAAE,CAC5C,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ;IAC7B,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,cAAc;IACnC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,sBAAsB,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,GAAgB,EAChB,QAA2B,EAC3B,EAAE;IACF,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAClD,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GACT,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAC;IACxE,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,QAAQ,CAAC,aAAa,CACpB,gBAAgB,CAAC;YACf,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,sCAAsC;SAChD,CAAC,CACH,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,EAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAC,GAAG,YAAY,CAAC,MAAO,CAAC;IACrE,MAAM,IAAI,GAAwB,EAAC,IAAI,EAAC,CAAC;IACzC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,YAAY,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC;IAC9B,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACxD,IAAwB,CAAC,MAAM,GAAG,IAAI,CAAC;IAC1C,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,GAAgB,EAChB,QAA2B,EACJ,EAAE;IACzB,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACtD,IAAI,WAAW,IAAI,SAAS,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,EAAC,WAAW,EAAC,CAAC;AACvB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,eAAe,GAAG,CACtB,IAA2B,EAC3B,SAAiC,EACjC,QAA2B,EAC3B,EAAE;IACF,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAClD,QAAQ,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvC,KAAK,aAAa,CAAC;YACnB,KAAK,cAAc,CAAC;YACpB,KAAK,sBAAsB;gBACzB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;gBAC7B,CAAC;gBACD,MAAM;YACR,KAAK,SAAS;gBACZ,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACzB,CAAC;gBACD,MAAM;YACR,KAAK,YAAY;gBACf,IAAI,CAAC,UAAU,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;gBACzD,MAAM;QACV,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,IAAI,OAAO,EAA6B,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,eAAe,GAAG,CAAC,UAAsB,EAAE,UAAyB,EAAE,EAAE;IAC5E,IAAI,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACnD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,6EAA6E;IAC7E,yEAAyE;IACzE,0EAA0E;IAC1E,oBAAoB;IACpB,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACjE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,YAAY,GAAG,EAAE,CAAC;IACpB,CAAC;SAAM,CAAC;QACN,uEAAuE;QACvE,0BAA0B;QAC1B,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACnE,wEAAwE;QACxE,+CAA+C;QAC/C,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,sEAAsE;QACtE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACnE,YAAY,GAAG,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IACD,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,YAAa,CAAC,CAAC;IAC/C,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,IAAa,EACb,QAA2B,EACJ,EAAE;IACzB,MAAM,IAAI,GAA0B,EAAE,CAAC;IACvC,MAAM,YAAY,GAAG,eAAe,CAClC,QAAQ,CAAC,UAAU,EACnB,IAAI,CAAC,aAAa,EAAE,CACrB,CAAC;IACF,gEAAgE;IAChE,wEAAwE;IACxE,yDAAyD;IACzD,mBAAmB;IACnB,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU;SAClC,YAAY,CAAC,IAAI,CAAC;SAClB,MAAM,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAkB,CAAC,CAAC,CAAC;IACpE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,oBAAoB,CAClC,IAAI;aACD,WAAW,EAAE;aACb,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;aACnC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;aACxC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;aACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;aAC9B,IAAI,CAAC,IAAI,CAAC,CACd,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,UAAyB,EACzB,QAA2B,EAC3B,EAAE;IACF,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACtE,MAAM,IAAI,GAA0B,EAAE,CAAC;IACvC,eAAe,CACb,IAAI,EACJ,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EACzC,QAAQ,CACT,CAAC;IACF,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,YAAY;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;aACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;aAC9B,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * @fileoverview\n *\n * Utilities for analyzing JSDoc comments\n */\n\nimport type ts from 'typescript';\nimport {createDiagnostic} from '../errors.js';\nimport {\n Described,\n TypedNamedDescribed,\n DeprecatableDescribed,\n AnalyzerInterface,\n CSSPropertyInfo,\n} from '../model.js';\n\nexport type TypeScript = typeof ts;\n\n/**\n * @fileoverview\n *\n * Utilities for parsing JSDoc comments.\n */\n\n/**\n * Returns true if given node has a JSDoc tag\n */\nexport const hasJSDocTag = (ts: TypeScript, node: ts.Node, tag: string) => {\n return ts.getJSDocTags(node).some((t) => t.tagName.text === tag);\n};\n\n/**\n * Remove line feeds from JSDoc comments, so they are normalized to\n * unix `\\n` line endings.\n */\nconst normalizeLineEndings = (s: string) => s.replace(/\\r/g, '').trim();\n\n// Regex for parsing name, type, and description from JSDoc comments\nconst parseNameTypeDescRE =\n /^\\[?(?<name>[^{}[\\]\\s=]+)(?:=(?<defaultValue>[^\\]]+))?\\]?(?:\\s+{(?<type>.*)})?(?:\\s+-\\s+)?(?<description>[\\s\\S]*)$/m;\n\n// Regex for parsing type, name, and description from JSDoc comments\nconst parseTypeNameDescRE =\n /^\\{(?<type>.+)\\}\\s+\\[?(?<name>[^{}[\\]\\s=]+)(?:=(?<defaultValue>[^\\]]+))?\\]?(?:\\s+-\\s+)?(?<description>[\\s\\S]*)$/m;\n\nconst getJSDocTagComment = (tag: ts.JSDocTag, analyzer: AnalyzerInterface) => {\n let {comment} = tag;\n if (comment === undefined) {\n return undefined;\n }\n if (Array.isArray(comment)) {\n comment = comment.map((c) => c.text).join('');\n }\n if (typeof comment !== 'string') {\n analyzer.addDiagnostic(\n createDiagnostic({\n typescript: analyzer.typescript,\n node: tag,\n message: `JSDoc error: unsupported node type`,\n })\n );\n return undefined;\n }\n return normalizeLineEndings(comment).trim();\n};\n\nconst isModuleJSDocTag = (tag: ts.JSDocTag) =>\n tag.tagName.text === 'module' ||\n tag.tagName.text === 'fileoverview' ||\n tag.tagName.text === 'packageDocumentation';\n\n/**\n * Parses name, type, and description from JSDoc tag for things like `@fires`.\n *\n * Supports the following patterns following the tag (TS parses the tag for us):\n * * @fires event-name\n * * @fires event-name description\n * * @fires event-name - description\n * * @fires event-name: description\n * * @fires event-name {Type}\n * * @fires event-name {Type} description\n * * @fires event-name {Type} - description\n * * @fires event-name {Type}: description\n * * @fires {Type} event-name\n * * @fires {Type} event-name description\n * * @fires {Type} event-name - description\n * * @fires {Type} event-name: description\n * * @slot name\n * * @slot name description\n * * @slot name - description\n * * @slot name: description\n * * @cssProp [--name=default]\n * * @cssProp [--name=default] description\n * * @cssProp [--name=default] - description\n * * @cssProp [--name=default]: description\n * * @cssprop {<color>} [--name=default]\n * * @cssprop {<color>} [--name=default] description\n * * @cssprop {<color>} [--name=default] - description\n * * @cssprop {<color>} [--name=default]: description\n */\nexport const parseNamedTypedJSDocInfo = (\n tag: ts.JSDocTag,\n analyzer: AnalyzerInterface\n) => {\n const comment = getJSDocTagComment(tag, analyzer);\n if (comment == undefined) {\n return undefined;\n }\n const regex =\n comment.charAt(0) === '{' ? parseTypeNameDescRE : parseNameTypeDescRE;\n const nameTypeDesc = comment.match(regex);\n if (nameTypeDesc === null) {\n analyzer.addDiagnostic(\n createDiagnostic({\n typescript: analyzer.typescript,\n node: tag,\n message: `JSDoc error: unexpected JSDoc format`,\n })\n );\n return undefined;\n }\n const {name, type, defaultValue, description} = nameTypeDesc.groups!;\n const info: TypedNamedDescribed = {name};\n if (description.length > 0) {\n info.description = normalizeLineEndings(description);\n }\n if (defaultValue?.length > 0) {\n info.default = defaultValue;\n }\n if (tag.tagName.text.toLowerCase().startsWith('cssprop')) {\n (info as CSSPropertyInfo).syntax = type;\n } else {\n info.type = type;\n }\n return info;\n};\n\n/**\n * Parses the description from JSDoc tag for things like `@return`.\n */\nexport const parseJSDocDescription = (\n tag: ts.JSDocTag,\n analyzer: AnalyzerInterface\n): Described | undefined => {\n const description = getJSDocTagComment(tag, analyzer);\n if (description == undefined || description.length === 0) {\n return {};\n }\n return {description};\n};\n\n/**\n * Add `@description`, `@summary`, and `@deprecated` JSDoc tag info to the\n * given info object.\n */\nconst addJSDocTagInfo = (\n info: DeprecatableDescribed,\n jsDocTags: readonly ts.JSDocTag[],\n analyzer: AnalyzerInterface\n) => {\n for (const tag of jsDocTags) {\n const comment = getJSDocTagComment(tag, analyzer);\n switch (tag.tagName.text.toLowerCase()) {\n case 'description':\n case 'fileoverview':\n case 'packagedocumentation':\n if (comment !== undefined) {\n info.description = comment;\n }\n break;\n case 'summary':\n if (comment !== undefined) {\n info.summary = comment;\n }\n break;\n case 'deprecated':\n info.deprecated = comment !== undefined ? comment : true;\n break;\n }\n }\n};\n\nconst moduleJSDocsMap = new WeakMap<ts.SourceFile, ts.JSDoc[]>();\n\n/**\n * Returns the module-level JSDoc comment blocks for a given source file.\n *\n * Note that TS does not have a concept of module-level JSDoc; if it\n * exists, it will always be attached to the first statement in the module.\n *\n * Thus, we parse module-level documentation using the following heuristic:\n * - If the first statement only has one JSDoc block, it is only treated as\n * module documentation if it contains a `@module`, `@fileoverview`, or\n * `@packageDocumentation` tag. This is required to disambiguate a module\n * description (with an undocumented first statement) from documentation\n * for the first statement.\n * - If the first statement has more than one JSDoc block, we collect all\n * but the last and use those, regardless of whether they contain one\n * of the above module-designating tags (the last one is assumed to belong\n * to the first statement).\n *\n * This function caches its result against the given sourceFile, since it is\n * needed both to find the module comment and to filter out module comments\n * node comments.\n */\nconst getModuleJSDocs = (typescript: TypeScript, sourceFile: ts.SourceFile) => {\n let moduleJSDocs = moduleJSDocsMap.get(sourceFile);\n if (moduleJSDocs !== undefined) {\n return moduleJSDocs;\n }\n // Get the first child in the sourceFile; note that returning the first child\n // from `ts.forEachChild` is more robust than `sourceFile.getChildAt(0)`,\n // since `forEachChild` flattens embedded arrays that the child APIs would\n // otherwise return.\n const firstChild = typescript.forEachChild(sourceFile, (n) => n);\n if (firstChild === undefined) {\n moduleJSDocs = [];\n } else {\n // Get the JSDoc blocks attached to the first child (they oddly show up\n // in the node's children)\n const jsDocs = firstChild.getChildren().filter(typescript.isJSDoc);\n // If there is more than one leading JSDoc block, grab all but the last,\n // otherwise grab the one (see heuristic above)\n moduleJSDocs = jsDocs.slice(0, jsDocs.length > 1 ? -1 : 1);\n // If there is only one leading JSDoc block, it must have a module tag\n if (jsDocs.length === 1 && !jsDocs[0].tags?.some(isModuleJSDocTag)) {\n moduleJSDocs = [];\n }\n }\n moduleJSDocsMap.set(sourceFile, moduleJSDocs!);\n return moduleJSDocs;\n};\n\n/**\n * Parse summary, description, and deprecated information from JSDoc comments on\n * a given node.\n */\nexport const parseNodeJSDocInfo = (\n node: ts.Node,\n analyzer: AnalyzerInterface\n): DeprecatableDescribed => {\n const info: DeprecatableDescribed = {};\n const moduleJSDocs = getModuleJSDocs(\n analyzer.typescript,\n node.getSourceFile()\n );\n // Module-level docs (that are explicitly tagged as such) may be\n // attached to the first declaration if the declaration is undocumented,\n // so we filter those out since they shouldn't apply to a\n // declaration node\n const jsDocTags = analyzer.typescript\n .getJSDocTags(node)\n .filter(({parent}) => !moduleJSDocs.includes(parent as ts.JSDoc));\n if (jsDocTags !== undefined) {\n addJSDocTagInfo(info, jsDocTags, analyzer);\n }\n if (info.description === undefined) {\n const comment = normalizeLineEndings(\n node\n .getChildren()\n .filter(analyzer.typescript.isJSDoc)\n .filter((c) => !moduleJSDocs.includes(c))\n .map((n) => n.comment)\n .filter((c) => c !== undefined)\n .join('\\n')\n );\n if (comment.length > 0) {\n info.description = comment;\n }\n }\n return info;\n};\n\n/**\n * Parse summary, description, and deprecated information from JSDoc comments on\n * a given source file.\n */\nexport const parseModuleJSDocInfo = (\n sourceFile: ts.SourceFile,\n analyzer: AnalyzerInterface\n) => {\n const moduleJSDocs = getModuleJSDocs(analyzer.typescript, sourceFile);\n const info: DeprecatableDescribed = {};\n addJSDocTagInfo(\n info,\n moduleJSDocs.flatMap((m) => m.tags ?? []),\n analyzer\n );\n if (info.description === undefined) {\n const comment = moduleJSDocs\n .map((d) => d.comment)\n .filter((c) => c !== undefined)\n .join('\\n');\n if (comment.length > 0) {\n info.description = comment;\n }\n }\n return info;\n};\n"]}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ /**
7
+ * @fileoverview
8
+ *
9
+ * Utilities for working with mixins
10
+ */
11
+ import type ts from 'typescript';
12
+ import { AnalyzerInterface, MixinDeclarationInit } from '../model.js';
13
+ /**
14
+ * If the given variable declaration was a mixin function, returns a
15
+ * MixinDeclaration initialisation object, otherwise returns undefined.
16
+ *
17
+ * The mixin logic requires a few important syntactic heuristics to be met in
18
+ * order to be detected as a mixin:
19
+ *
20
+ * - a super class parameter (by any name) which is later used as a base class
21
+ * - a function body (rather than an arrow function)
22
+ * - an internal class which extends the previously mentioned super class parameter
23
+ * - a return statement returning the class
24
+ *
25
+ * For example:
26
+ *
27
+ * ```
28
+ * function MyMixin(superClass) {
29
+ * class MixedClass extends superClass {
30
+ * // ...
31
+ * }
32
+ * return MixedClass;
33
+ * }
34
+ * ```
35
+ *
36
+ * You can read more about this pattern in the TypeScript docs here:
37
+ * https://www.typescriptlang.org/docs/handbook/mixins.html
38
+ *
39
+ * If the function is unannotated and does not match the above mixin shape, it
40
+ * will silently just be analyzed as a simple function and not a mixin. However,
41
+ * the `@mixin` annotation can be added to produce specific diagnostic errors
42
+ * when a condition for being analyzed as a mixin is not met.
43
+ */
44
+ export declare const maybeGetMixinFromFunctionLike: (fn: ts.FunctionLikeDeclaration, name: string, analyzer: AnalyzerInterface) => MixinDeclarationInit | undefined;
45
+ //# sourceMappingURL=mixins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mixins.d.ts","sourceRoot":"","sources":["../../src/lib/javascript/mixins.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAC,iBAAiB,EAAE,oBAAoB,EAAC,MAAM,aAAa,CAAC;AA+BpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,6BAA6B,GACxC,IAAI,EAAE,CAAC,uBAAuB,EAC9B,MAAM,MAAM,EACZ,UAAU,iBAAiB,KAC1B,oBAAoB,GAAG,SAwHzB,CAAC"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { getClassDeclaration } from './classes.js';
7
+ import { createDiagnostic } from '../errors.js';
8
+ import { DiagnosticCode } from '../diagnostic-code.js';
9
+ import { getSymbolForName } from '../references.js';
10
+ const nodeHasMixinHint = (node, analyzer) => analyzer.typescript
11
+ .getJSDocTags(node)
12
+ .some((tag) => tag.tagName.text === 'mixin');
13
+ const addDiagnosticIfMixin = (node, hasMixinHint, message, analyzer) => {
14
+ if (hasMixinHint) {
15
+ analyzer.addDiagnostic(createDiagnostic({
16
+ typescript: analyzer.typescript,
17
+ node,
18
+ message,
19
+ code: DiagnosticCode.UNSUPPORTED,
20
+ category: analyzer.typescript.DiagnosticCategory.Warning,
21
+ }));
22
+ }
23
+ return undefined;
24
+ };
25
+ /**
26
+ * If the given variable declaration was a mixin function, returns a
27
+ * MixinDeclaration initialisation object, otherwise returns undefined.
28
+ *
29
+ * The mixin logic requires a few important syntactic heuristics to be met in
30
+ * order to be detected as a mixin:
31
+ *
32
+ * - a super class parameter (by any name) which is later used as a base class
33
+ * - a function body (rather than an arrow function)
34
+ * - an internal class which extends the previously mentioned super class parameter
35
+ * - a return statement returning the class
36
+ *
37
+ * For example:
38
+ *
39
+ * ```
40
+ * function MyMixin(superClass) {
41
+ * class MixedClass extends superClass {
42
+ * // ...
43
+ * }
44
+ * return MixedClass;
45
+ * }
46
+ * ```
47
+ *
48
+ * You can read more about this pattern in the TypeScript docs here:
49
+ * https://www.typescriptlang.org/docs/handbook/mixins.html
50
+ *
51
+ * If the function is unannotated and does not match the above mixin shape, it
52
+ * will silently just be analyzed as a simple function and not a mixin. However,
53
+ * the `@mixin` annotation can be added to produce specific diagnostic errors
54
+ * when a condition for being analyzed as a mixin is not met.
55
+ */
56
+ export const maybeGetMixinFromFunctionLike = (fn, name, analyzer) => {
57
+ const hasMixinHint = nodeHasMixinHint(fn, analyzer);
58
+ if (fn.parameters === undefined || fn.parameters.length < 1) {
59
+ addDiagnosticIfMixin(fn, hasMixinHint, `Expected mixin to have a superClass parameter.`, analyzer);
60
+ return undefined;
61
+ }
62
+ const functionBody = fn.body;
63
+ if (functionBody === undefined) {
64
+ addDiagnosticIfMixin(fn, hasMixinHint, `Expected mixin to have a block function body.`, analyzer);
65
+ return undefined;
66
+ }
67
+ let classDeclaration;
68
+ let returnStatement;
69
+ if (analyzer.typescript.isBlock(functionBody)) {
70
+ for (const s of functionBody.statements) {
71
+ if (analyzer.typescript.isClassDeclaration(s)) {
72
+ classDeclaration = s;
73
+ }
74
+ if (analyzer.typescript.isReturnStatement(s)) {
75
+ returnStatement = s;
76
+ if (classDeclaration === undefined &&
77
+ s.expression !== undefined &&
78
+ analyzer.typescript.isClassLike(s.expression)) {
79
+ classDeclaration = s.expression;
80
+ }
81
+ }
82
+ }
83
+ if (returnStatement === undefined) {
84
+ addDiagnosticIfMixin(fn, hasMixinHint, `Expected mixin to contain a return statement returning a class.`, analyzer);
85
+ return undefined;
86
+ }
87
+ }
88
+ else if (analyzer.typescript.isClassLike(functionBody)) {
89
+ classDeclaration = functionBody;
90
+ }
91
+ if (classDeclaration === undefined) {
92
+ addDiagnosticIfMixin(fn, hasMixinHint, `Expected mixin to contain a class declaration statement.`, analyzer);
93
+ return undefined;
94
+ }
95
+ const extendsClause = classDeclaration.heritageClauses?.find((c) => c.token === analyzer.typescript.SyntaxKind.ExtendsKeyword);
96
+ if (extendsClause === undefined) {
97
+ addDiagnosticIfMixin(fn, hasMixinHint, `Expected mixin to contain class declaration extending a superClass argument to function.`, analyzer);
98
+ return undefined;
99
+ }
100
+ if (extendsClause.types.length !== 1) {
101
+ analyzer.addDiagnostic(createDiagnostic({
102
+ typescript: analyzer.typescript,
103
+ node: extendsClause,
104
+ message: 'Internal error: did not expect a mixin class extends clause to have multiple types',
105
+ code: DiagnosticCode.UNSUPPORTED,
106
+ category: analyzer.typescript.DiagnosticCategory.Warning,
107
+ }));
108
+ return undefined;
109
+ }
110
+ const superClassArgIndex = findSuperClassArgIndexFromHeritage(fn, extendsClause.types[0].expression, analyzer);
111
+ if (superClassArgIndex < 0) {
112
+ analyzer.addDiagnostic(createDiagnostic({
113
+ typescript: analyzer.typescript,
114
+ node: extendsClause,
115
+ message: 'Did not find a "superClass" argument used in the extends clause of mixin class.',
116
+ code: DiagnosticCode.UNSUPPORTED,
117
+ category: analyzer.typescript.DiagnosticCategory.Warning,
118
+ }));
119
+ return undefined;
120
+ }
121
+ const classDeclarationName = classDeclaration.name?.text ?? name;
122
+ return {
123
+ node: fn,
124
+ name,
125
+ superClassArgIndex,
126
+ classDeclaration: getClassDeclaration(classDeclaration, classDeclarationName, analyzer, undefined, true /* isMixinClass */),
127
+ };
128
+ };
129
+ const findSuperClassArgIndexFromHeritage = (mixinFunction, expression, analyzer) => {
130
+ if (analyzer.typescript.isIdentifier(expression)) {
131
+ const paramSymbol = getSymbolForName(expression.text, expression, analyzer);
132
+ if (paramSymbol?.declarations) {
133
+ const paramDecl = paramSymbol.declarations;
134
+ return mixinFunction.parameters.findIndex((param) => paramDecl.includes(param));
135
+ }
136
+ }
137
+ else if (analyzer.typescript.isCallExpression(expression)) {
138
+ for (const arg of expression.arguments) {
139
+ const index = findSuperClassArgIndexFromHeritage(mixinFunction, arg, analyzer);
140
+ if (index >= 0) {
141
+ return index;
142
+ }
143
+ }
144
+ }
145
+ return -1;
146
+ };
147
+ //# sourceMappingURL=mixins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mixins.js","sourceRoot":"","sources":["../../src/lib/javascript/mixins.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2024 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * @fileoverview\n *\n * Utilities for working with mixins\n */\n\nimport type ts from 'typescript';\nimport {AnalyzerInterface, MixinDeclarationInit} from '../model.js';\nimport {getClassDeclaration} from './classes.js';\nimport {createDiagnostic} from '../errors.js';\nimport {DiagnosticCode} from '../diagnostic-code.js';\nimport {getSymbolForName} from '../references.js';\n\nconst nodeHasMixinHint = (node: ts.Node, analyzer: AnalyzerInterface) =>\n analyzer.typescript\n .getJSDocTags(node)\n .some((tag) => tag.tagName.text === 'mixin');\n\nconst addDiagnosticIfMixin = (\n node: ts.Node,\n hasMixinHint: boolean,\n message: string,\n analyzer: AnalyzerInterface\n) => {\n if (hasMixinHint) {\n analyzer.addDiagnostic(\n createDiagnostic({\n typescript: analyzer.typescript,\n node,\n message,\n code: DiagnosticCode.UNSUPPORTED,\n category: analyzer.typescript.DiagnosticCategory.Warning,\n })\n );\n }\n return undefined;\n};\n\n/**\n * If the given variable declaration was a mixin function, returns a\n * MixinDeclaration initialisation object, otherwise returns undefined.\n *\n * The mixin logic requires a few important syntactic heuristics to be met in\n * order to be detected as a mixin:\n *\n * - a super class parameter (by any name) which is later used as a base class\n * - a function body (rather than an arrow function)\n * - an internal class which extends the previously mentioned super class parameter\n * - a return statement returning the class\n *\n * For example:\n *\n * ```\n * function MyMixin(superClass) {\n * class MixedClass extends superClass {\n * // ...\n * }\n * return MixedClass;\n * }\n * ```\n *\n * You can read more about this pattern in the TypeScript docs here:\n * https://www.typescriptlang.org/docs/handbook/mixins.html\n *\n * If the function is unannotated and does not match the above mixin shape, it\n * will silently just be analyzed as a simple function and not a mixin. However,\n * the `@mixin` annotation can be added to produce specific diagnostic errors\n * when a condition for being analyzed as a mixin is not met.\n */\nexport const maybeGetMixinFromFunctionLike = (\n fn: ts.FunctionLikeDeclaration,\n name: string,\n analyzer: AnalyzerInterface\n): MixinDeclarationInit | undefined => {\n const hasMixinHint = nodeHasMixinHint(fn, analyzer);\n if (fn.parameters === undefined || fn.parameters.length < 1) {\n addDiagnosticIfMixin(\n fn,\n hasMixinHint,\n `Expected mixin to have a superClass parameter.`,\n analyzer\n );\n return undefined;\n }\n const functionBody = fn.body;\n if (functionBody === undefined) {\n addDiagnosticIfMixin(\n fn,\n hasMixinHint,\n `Expected mixin to have a block function body.`,\n analyzer\n );\n return undefined;\n }\n let classDeclaration: ts.ClassLikeDeclaration | undefined;\n let returnStatement: ts.ReturnStatement | undefined;\n if (analyzer.typescript.isBlock(functionBody)) {\n for (const s of functionBody.statements) {\n if (analyzer.typescript.isClassDeclaration(s)) {\n classDeclaration = s;\n }\n if (analyzer.typescript.isReturnStatement(s)) {\n returnStatement = s;\n\n if (\n classDeclaration === undefined &&\n s.expression !== undefined &&\n analyzer.typescript.isClassLike(s.expression)\n ) {\n classDeclaration = s.expression;\n }\n }\n }\n\n if (returnStatement === undefined) {\n addDiagnosticIfMixin(\n fn,\n hasMixinHint,\n `Expected mixin to contain a return statement returning a class.`,\n analyzer\n );\n return undefined;\n }\n } else if (analyzer.typescript.isClassLike(functionBody)) {\n classDeclaration = functionBody;\n }\n if (classDeclaration === undefined) {\n addDiagnosticIfMixin(\n fn,\n hasMixinHint,\n `Expected mixin to contain a class declaration statement.`,\n analyzer\n );\n return undefined;\n }\n const extendsClause = classDeclaration.heritageClauses?.find(\n (c) => c.token === analyzer.typescript.SyntaxKind.ExtendsKeyword\n );\n if (extendsClause === undefined) {\n addDiagnosticIfMixin(\n fn,\n hasMixinHint,\n `Expected mixin to contain class declaration extending a superClass argument to function.`,\n analyzer\n );\n return undefined;\n }\n if (extendsClause.types.length !== 1) {\n analyzer.addDiagnostic(\n createDiagnostic({\n typescript: analyzer.typescript,\n node: extendsClause,\n message:\n 'Internal error: did not expect a mixin class extends clause to have multiple types',\n code: DiagnosticCode.UNSUPPORTED,\n category: analyzer.typescript.DiagnosticCategory.Warning,\n })\n );\n return undefined;\n }\n const superClassArgIndex = findSuperClassArgIndexFromHeritage(\n fn,\n extendsClause.types[0].expression,\n analyzer\n );\n if (superClassArgIndex < 0) {\n analyzer.addDiagnostic(\n createDiagnostic({\n typescript: analyzer.typescript,\n node: extendsClause,\n message:\n 'Did not find a \"superClass\" argument used in the extends clause of mixin class.',\n code: DiagnosticCode.UNSUPPORTED,\n category: analyzer.typescript.DiagnosticCategory.Warning,\n })\n );\n return undefined;\n }\n\n const classDeclarationName = classDeclaration.name?.text ?? name;\n\n return {\n node: fn,\n name,\n superClassArgIndex,\n classDeclaration: getClassDeclaration(\n classDeclaration,\n classDeclarationName,\n analyzer,\n undefined,\n true /* isMixinClass */\n ),\n };\n};\n\nconst findSuperClassArgIndexFromHeritage = (\n mixinFunction: ts.FunctionLikeDeclaration,\n expression: ts.Expression,\n analyzer: AnalyzerInterface\n): number => {\n if (analyzer.typescript.isIdentifier(expression)) {\n const paramSymbol = getSymbolForName(expression.text, expression, analyzer);\n\n if (paramSymbol?.declarations) {\n const paramDecl = paramSymbol.declarations;\n return mixinFunction.parameters.findIndex((param) =>\n paramDecl.includes(param)\n );\n }\n } else if (analyzer.typescript.isCallExpression(expression)) {\n for (const arg of expression.arguments) {\n const index = findSuperClassArgIndexFromHeritage(\n mixinFunction,\n arg,\n analyzer\n );\n if (index >= 0) {\n return index;\n }\n }\n }\n return -1;\n};\n"]}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ /**
7
+ * @fileoverview
8
+ *
9
+ * Utilities for analyzing ES modules
10
+ */
11
+ import type ts from 'typescript';
12
+ import { Module, AnalyzerInterface, PackageInfo, Declaration, ModuleInfo } from '../model.js';
13
+ import { AbsolutePath } from '../paths.js';
14
+ export type TypeScript = typeof ts;
15
+ /**
16
+ * Returns the sourcePath, jsPath, and package.json contents of the containing
17
+ * package for the given module path.
18
+ *
19
+ * This is a minimal subset of module information needed for constructing a
20
+ * Reference object for a module.
21
+ */
22
+ export declare const getModuleInfo: (modulePath: AbsolutePath, analyzer: AnalyzerInterface, packageInfo?: PackageInfo) => ModuleInfo;
23
+ /**
24
+ * Returns an analyzer `Module` model for the given module path.
25
+ */
26
+ export declare const getModule: (modulePath: AbsolutePath, analyzer: AnalyzerInterface, packageInfo?: PackageInfo) => Module;
27
+ /**
28
+ * Resolves a module specifier expression node to an absolute path on disk.
29
+ */
30
+ export declare const getPathForModuleSpecifierExpression: (specifierExpression: ts.Expression, analyzer: AnalyzerInterface) => AbsolutePath | undefined;
31
+ /**
32
+ * Resolve a module specifier to an absolute path on disk.
33
+ */
34
+ export declare const getPathForModuleSpecifier: (specifier: string, location: ts.Node, analyzer: AnalyzerInterface) => AbsolutePath | undefined;
35
+ /**
36
+ * Returns the declaration for the named export of the given module path;
37
+ * note that if the given module re-exported a declaration from another
38
+ * module, references are followed to the concrete declaration, which is
39
+ * returned.
40
+ */
41
+ export declare const getResolvedExportFromSourcePath: (modulePath: AbsolutePath, name: string, analyzer: AnalyzerInterface) => Declaration;
42
+ //# sourceMappingURL=modules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../../src/lib/javascript/modules.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EACL,MAAM,EACN,iBAAiB,EACjB,WAAW,EACX,WAAW,EAIX,UAAU,EAEX,MAAM,aAAa,CAAC;AAOrB,OAAO,EAAC,YAAY,EAAiC,MAAM,aAAa,CAAC;AAWzE,MAAM,MAAM,UAAU,GAAG,OAAO,EAAE,CAAC;AAEnC;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GACxB,YAAY,YAAY,EACxB,UAAU,iBAAiB,EAC3B,cAAa,WAAkD,KAC9D,UAuBF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS,GACpB,YAAY,YAAY,EACxB,UAAU,iBAAiB,EAC3B,cAAa,WAAkD,WAiHhE,CAAC;AA6IF;;GAEG;AACH,eAAO,MAAM,mCAAmC,GAC9C,qBAAqB,EAAE,CAAC,UAAU,EAClC,UAAU,iBAAiB,KAC1B,YAAY,GAAG,SAGjB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,GACpC,WAAW,MAAM,EACjB,UAAU,EAAE,CAAC,IAAI,EACjB,UAAU,iBAAiB,KAC1B,YAAY,GAAG,SAmBjB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,GAC1C,YAAY,YAAY,EACxB,MAAM,MAAM,EACZ,UAAU,iBAAiB,gBACgC,CAAC"}