@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,277 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { Module, } from '../model.js';
7
+ import { getClassDeclarationInfo } from './classes.js';
8
+ import { getExportAssignmentVariableDeclarationInfo, getVariableDeclarationInfo, getEnumDeclarationInfo, } from './variables.js';
9
+ import { absoluteToPackage } from '../paths.js';
10
+ import { getPackageInfo } from './packages.js';
11
+ import { createDiagnostic } from '../errors.js';
12
+ import { getExportReferences, getImportReferenceForSpecifierExpression, getSpecifierString, } from '../references.js';
13
+ import { parseModuleJSDocInfo } from './jsdoc.js';
14
+ import { getFunctionDeclarationInfo } from './functions.js';
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 const getModuleInfo = (modulePath, analyzer, packageInfo = getPackageInfo(modulePath, analyzer)) => {
23
+ // The packageRoot for this module is needed for translating the source file
24
+ // path to a package relative path, and the packageName is needed for
25
+ // generating references to any symbols in this module.
26
+ const { rootDir, packageJson } = packageInfo;
27
+ const absJsPath = getJSPathFromSourcePath(modulePath, analyzer);
28
+ const jsPath = absJsPath !== undefined
29
+ ? absoluteToPackage(absJsPath, rootDir, analyzer.path.sep)
30
+ : 'not/implemented';
31
+ const sourcePath = absoluteToPackage(analyzer.path.normalize(modulePath), rootDir, analyzer.path.sep);
32
+ return {
33
+ jsPath,
34
+ sourcePath,
35
+ packageJson,
36
+ };
37
+ };
38
+ /**
39
+ * Returns an analyzer `Module` model for the given module path.
40
+ */
41
+ export const getModule = (modulePath, analyzer, packageInfo = getPackageInfo(modulePath, analyzer)) => {
42
+ const { typescript: ts } = analyzer;
43
+ // Return cached module if we've parsed this sourceFile already and its
44
+ // dependencies haven't changed
45
+ const cachedModule = getAndValidateModuleFromCache(modulePath, analyzer);
46
+ if (cachedModule !== undefined) {
47
+ return cachedModule;
48
+ }
49
+ const sourceFile = analyzer.program.getSourceFile(analyzer.path.normalize(modulePath));
50
+ if (sourceFile === undefined) {
51
+ throw new Error(`Program did not contain a source file for ${modulePath}`);
52
+ }
53
+ const dependencies = new Set();
54
+ const declarationMap = new Map();
55
+ const exportMap = new Map();
56
+ const reexports = [];
57
+ const addDeclaration = (info) => {
58
+ const { name, node, factory, isExport } = info;
59
+ if (declarationMap.has(name)) {
60
+ analyzer.addDiagnostic(createDiagnostic({
61
+ typescript: ts,
62
+ node,
63
+ message: `Duplicate declaration '${name}'`,
64
+ category: ts.DiagnosticCategory.Error,
65
+ }));
66
+ return;
67
+ }
68
+ declarationMap.set(name, factory);
69
+ if (isExport) {
70
+ exportMap.set(name, name);
71
+ }
72
+ };
73
+ // Find and add models for declarations in the module
74
+ // TODO(kschaaf): Add Function and MixinDeclarations
75
+ for (const statement of sourceFile.statements) {
76
+ if (ts.isClassDeclaration(statement)) {
77
+ const decl = getClassDeclarationInfo(statement, analyzer);
78
+ if (decl !== undefined) {
79
+ addDeclaration(decl);
80
+ }
81
+ // Ignore non-implementation signatures of overloaded functions by
82
+ // checking for `statement.body`.
83
+ }
84
+ else if (ts.isFunctionDeclaration(statement) && statement.body) {
85
+ const decl = getFunctionDeclarationInfo(statement, analyzer);
86
+ if (decl !== undefined) {
87
+ addDeclaration(decl);
88
+ }
89
+ }
90
+ else if (ts.isVariableStatement(statement)) {
91
+ getVariableDeclarationInfo(statement, analyzer).forEach(addDeclaration);
92
+ }
93
+ else if (ts.isEnumDeclaration(statement)) {
94
+ addDeclaration(getEnumDeclarationInfo(statement, analyzer));
95
+ }
96
+ else if (ts.isExportDeclaration(statement) && !statement.isTypeOnly) {
97
+ const { exportClause, moduleSpecifier } = statement;
98
+ if (exportClause === undefined) {
99
+ // Case: `export * from 'foo';` The `exportClause` is undefined for
100
+ // wildcard exports. Add the re-exported module specifier to the
101
+ // `reexports` list, and we will add references to the exportMap lazily
102
+ // the first time exports are queried
103
+ if (moduleSpecifier === undefined) {
104
+ analyzer.addDiagnostic(createDiagnostic({
105
+ typescript: ts,
106
+ node: statement,
107
+ message: `Unexpected syntax: expected a wildcard export to always have a module specifier.`,
108
+ }));
109
+ }
110
+ else {
111
+ reexports.push(moduleSpecifier);
112
+ }
113
+ }
114
+ else {
115
+ // Case: `export {...}` and `export {...} from '...'`
116
+ // Add all of the exports in this export statement to the exportMap
117
+ getExportReferences(exportClause, moduleSpecifier, analyzer).forEach(({ exportName, decNameOrRef }) => exportMap.set(exportName, decNameOrRef));
118
+ }
119
+ }
120
+ else if (ts.isExportAssignment(statement)) {
121
+ addDeclaration(getExportAssignmentVariableDeclarationInfo(statement, analyzer));
122
+ }
123
+ else if (ts.isImportDeclaration(statement)) {
124
+ const path = getPathForModuleSpecifierExpression(statement.moduleSpecifier, analyzer);
125
+ if (path !== undefined) {
126
+ dependencies.add(path);
127
+ }
128
+ }
129
+ }
130
+ // Construct module and save in cache
131
+ const module = new Module({
132
+ ...getModuleInfo(modulePath, analyzer, packageInfo),
133
+ sourceFile,
134
+ declarationMap,
135
+ dependencies,
136
+ exportMap,
137
+ finalizeExports: () => finalizeExports(reexports, exportMap, analyzer),
138
+ ...parseModuleJSDocInfo(sourceFile, analyzer),
139
+ });
140
+ analyzer.moduleCache.set(analyzer.path.normalize(sourceFile.fileName), module);
141
+ return module;
142
+ };
143
+ /**
144
+ * For any re-exported modules (i.e. `export * from 'foo'`), add all of the
145
+ * exported names of the reexported module to the given exportMap, with
146
+ * References into that module.
147
+ */
148
+ const finalizeExports = (reexportSpecifiers, exportMap, analyzer) => {
149
+ for (const moduleSpecifier of reexportSpecifiers) {
150
+ const path = getPathForModuleSpecifierExpression(moduleSpecifier, analyzer);
151
+ if (path === undefined) {
152
+ continue;
153
+ }
154
+ const module = getModule(path, analyzer);
155
+ for (const name of module.exportNames) {
156
+ exportMap.set(name, getImportReferenceForSpecifierExpression(moduleSpecifier, name, analyzer));
157
+ }
158
+ }
159
+ };
160
+ /**
161
+ * Returns a cached Module model for the given module path if it and all of its
162
+ * dependencies' models are still valid since the model was cached. If the
163
+ * cached module is out-of-date and needs to be re-created, this method returns
164
+ * undefined.
165
+ */
166
+ const getAndValidateModuleFromCache = (modulePath, analyzer, seen = new Set([modulePath])) => {
167
+ const module = analyzer.moduleCache.get(modulePath);
168
+ // A cached module is only valid if the source file that was used has not
169
+ // changed in the current program, and if all of its dependencies are still
170
+ // valid
171
+ if (module !== undefined) {
172
+ if (module.sourceFile === analyzer.program.getSourceFile(modulePath) &&
173
+ depsAreValid(module, analyzer, seen)) {
174
+ return module;
175
+ }
176
+ analyzer.moduleCache.delete(modulePath);
177
+ }
178
+ return undefined;
179
+ };
180
+ /**
181
+ * Returns true if all dependencies of the module are still valid.
182
+ */
183
+ const depsAreValid = (module, analyzer, seen) => Array.from(module.dependencies).every((path) =>
184
+ // `seen` is initialized only once, at the entry point for the initial
185
+ // call to `getAndValidateModuleFromCache`, and modulePaths are only added
186
+ // to `seen` at the deepest part of the recursion, in `depIsValid`
187
+ // because of that, we can be confident that a module path which was 'seen'
188
+ // has already been validated by `depIsValid` and can be safely skipped here.
189
+ seen.has(path) || depIsValid(path, analyzer, seen));
190
+ /**
191
+ * Returns true if the given dependency is valid, meaning that if it has a
192
+ * cached model, the model is still valid. Dependencies that don't yet have a
193
+ * cached model are considered valid.
194
+ */
195
+ const depIsValid = (modulePath, analyzer, seen) => {
196
+ seen.add(modulePath);
197
+ if (analyzer.moduleCache.has(modulePath)) {
198
+ // If a dep has a model, it is valid only if its deps are valid
199
+ return Boolean(getAndValidateModuleFromCache(modulePath, analyzer, seen));
200
+ }
201
+ else {
202
+ // Deps that don't have a cached model are considered valid
203
+ return true;
204
+ }
205
+ };
206
+ /**
207
+ * For a given source file, return its associated JS file.
208
+ *
209
+ * For a JS source file, these will be the same thing. For a TS file, we use the
210
+ * TS API to determine where the associated JS will be output based on tsconfig
211
+ * settings.
212
+ */
213
+ const getJSPathFromSourcePath = (sourcePath, analyzer) => {
214
+ sourcePath = analyzer.path.normalize(sourcePath);
215
+ // If the source file was already JS, just return that
216
+ if (sourcePath.endsWith('.js')) {
217
+ return sourcePath;
218
+ }
219
+ // TODO(kschaaf): If the source file was a declaration file, this means we're
220
+ // likely getting information about an externally imported package that had
221
+ // types. In this case, we'll need to update our logic to resolve the import
222
+ // specifier to the JS path (in addition to the source file path that we do
223
+ // today). Unfortunately, TS's specifier resolver always prefers a declaration
224
+ // file, and due to type roots and other tsconfig fancies, it's not
225
+ // straightforward to go from a declaration file to a source file. In order to
226
+ // properly implement this we'll probably need to bring our own node module
227
+ // resolver ala https://www.npmjs.com/package/resolve. That change should be
228
+ // done along with the custom-elements.json manifest work.
229
+ if (sourcePath.endsWith('.d.ts')) {
230
+ return undefined;
231
+ }
232
+ // Use the TS API to determine where the associated JS will be output based
233
+ // on tsconfig settings.
234
+ const outputPath = analyzer.typescript
235
+ .getOutputFileNames(analyzer.commandLine, sourcePath, false)
236
+ .filter((f) => f.endsWith('.js'))[0];
237
+ // TODO(kschaaf): this could happen if someone imported only a .d.ts file;
238
+ // we might need to handle this differently
239
+ if (outputPath === undefined) {
240
+ throw new Error(`Could not determine output filename for '${sourcePath}'`);
241
+ }
242
+ // The filename appears to come out of the ts API with
243
+ // unix separators; since sourcePath uses OS separators, normalize this so
244
+ // that all our model paths are OS-native
245
+ return analyzer.path.normalize(outputPath);
246
+ };
247
+ /**
248
+ * Resolves a module specifier expression node to an absolute path on disk.
249
+ */
250
+ export const getPathForModuleSpecifierExpression = (specifierExpression, analyzer) => {
251
+ const specifier = getSpecifierString(specifierExpression);
252
+ return getPathForModuleSpecifier(specifier, specifierExpression, analyzer);
253
+ };
254
+ /**
255
+ * Resolve a module specifier to an absolute path on disk.
256
+ */
257
+ export const getPathForModuleSpecifier = (specifier, location, analyzer) => {
258
+ const resolvedPath = analyzer.typescript.resolveModuleName(specifier, location.getSourceFile().fileName, analyzer.commandLine.options, analyzer.fs).resolvedModule?.resolvedFileName;
259
+ if (resolvedPath === undefined) {
260
+ analyzer.addDiagnostic(createDiagnostic({
261
+ typescript: analyzer.typescript,
262
+ node: location,
263
+ message: `Could not resolve specifier ${specifier} to filesystem path.`,
264
+ category: analyzer.typescript.DiagnosticCategory.Error,
265
+ }));
266
+ return undefined;
267
+ }
268
+ return analyzer.path.normalize(resolvedPath);
269
+ };
270
+ /**
271
+ * Returns the declaration for the named export of the given module path;
272
+ * note that if the given module re-exported a declaration from another
273
+ * module, references are followed to the concrete declaration, which is
274
+ * returned.
275
+ */
276
+ export const getResolvedExportFromSourcePath = (modulePath, name, analyzer) => getModule(modulePath, analyzer)?.getResolvedExport(name);
277
+ //# sourceMappingURL=modules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modules.js","sourceRoot":"","sources":["../../src/lib/javascript/modules.ts"],"names":[],"mappings":"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","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 ES modules\n */\n\nimport type ts from 'typescript';\nimport {\n Module,\n AnalyzerInterface,\n PackageInfo,\n Declaration,\n DeclarationInfo,\n ExportMap,\n DeclarationMap,\n ModuleInfo,\n LocalNameOrReference,\n} from '../model.js';\nimport {getClassDeclarationInfo} from './classes.js';\nimport {\n getExportAssignmentVariableDeclarationInfo,\n getVariableDeclarationInfo,\n getEnumDeclarationInfo,\n} from './variables.js';\nimport {AbsolutePath, PackagePath, absoluteToPackage} from '../paths.js';\nimport {getPackageInfo} from './packages.js';\nimport {createDiagnostic} from '../errors.js';\nimport {\n getExportReferences,\n getImportReferenceForSpecifierExpression,\n getSpecifierString,\n} from '../references.js';\nimport {parseModuleJSDocInfo} from './jsdoc.js';\nimport {getFunctionDeclarationInfo} from './functions.js';\n\nexport type TypeScript = typeof ts;\n\n/**\n * Returns the sourcePath, jsPath, and package.json contents of the containing\n * package for the given module path.\n *\n * This is a minimal subset of module information needed for constructing a\n * Reference object for a module.\n */\nexport const getModuleInfo = (\n modulePath: AbsolutePath,\n analyzer: AnalyzerInterface,\n packageInfo: PackageInfo = getPackageInfo(modulePath, analyzer)\n): ModuleInfo => {\n // The packageRoot for this module is needed for translating the source file\n // path to a package relative path, and the packageName is needed for\n // generating references to any symbols in this module.\n const {rootDir, packageJson} = packageInfo;\n const absJsPath = getJSPathFromSourcePath(\n modulePath as AbsolutePath,\n analyzer\n );\n const jsPath =\n absJsPath !== undefined\n ? absoluteToPackage(absJsPath, rootDir, analyzer.path.sep)\n : ('not/implemented' as PackagePath);\n const sourcePath = absoluteToPackage(\n analyzer.path.normalize(modulePath) as AbsolutePath,\n rootDir,\n analyzer.path.sep\n );\n return {\n jsPath,\n sourcePath,\n packageJson,\n };\n};\n\n/**\n * Returns an analyzer `Module` model for the given module path.\n */\nexport const getModule = (\n modulePath: AbsolutePath,\n analyzer: AnalyzerInterface,\n packageInfo: PackageInfo = getPackageInfo(modulePath, analyzer)\n) => {\n const {typescript: ts} = analyzer;\n // Return cached module if we've parsed this sourceFile already and its\n // dependencies haven't changed\n const cachedModule = getAndValidateModuleFromCache(modulePath, analyzer);\n if (cachedModule !== undefined) {\n return cachedModule;\n }\n const sourceFile = analyzer.program.getSourceFile(\n analyzer.path.normalize(modulePath)\n );\n if (sourceFile === undefined) {\n throw new Error(`Program did not contain a source file for ${modulePath}`);\n }\n\n const dependencies = new Set<AbsolutePath>();\n const declarationMap: DeclarationMap = new Map<string, () => Declaration>();\n const exportMap: ExportMap = new Map<string, LocalNameOrReference>();\n const reexports: ts.Expression[] = [];\n const addDeclaration = (info: DeclarationInfo) => {\n const {name, node, factory, isExport} = info;\n if (declarationMap.has(name)) {\n analyzer.addDiagnostic(\n createDiagnostic({\n typescript: ts,\n node,\n message: `Duplicate declaration '${name}'`,\n category: ts.DiagnosticCategory.Error,\n })\n );\n return;\n }\n declarationMap.set(name, factory);\n if (isExport) {\n exportMap.set(name, name);\n }\n };\n\n // Find and add models for declarations in the module\n // TODO(kschaaf): Add Function and MixinDeclarations\n for (const statement of sourceFile.statements) {\n if (ts.isClassDeclaration(statement)) {\n const decl = getClassDeclarationInfo(statement, analyzer);\n if (decl !== undefined) {\n addDeclaration(decl);\n }\n // Ignore non-implementation signatures of overloaded functions by\n // checking for `statement.body`.\n } else if (ts.isFunctionDeclaration(statement) && statement.body) {\n const decl = getFunctionDeclarationInfo(statement, analyzer);\n if (decl !== undefined) {\n addDeclaration(decl);\n }\n } else if (ts.isVariableStatement(statement)) {\n getVariableDeclarationInfo(statement, analyzer).forEach(addDeclaration);\n } else if (ts.isEnumDeclaration(statement)) {\n addDeclaration(getEnumDeclarationInfo(statement, analyzer));\n } else if (ts.isExportDeclaration(statement) && !statement.isTypeOnly) {\n const {exportClause, moduleSpecifier} = statement;\n if (exportClause === undefined) {\n // Case: `export * from 'foo';` The `exportClause` is undefined for\n // wildcard exports. Add the re-exported module specifier to the\n // `reexports` list, and we will add references to the exportMap lazily\n // the first time exports are queried\n if (moduleSpecifier === undefined) {\n analyzer.addDiagnostic(\n createDiagnostic({\n typescript: ts,\n node: statement,\n message: `Unexpected syntax: expected a wildcard export to always have a module specifier.`,\n })\n );\n } else {\n reexports.push(moduleSpecifier);\n }\n } else {\n // Case: `export {...}` and `export {...} from '...'`\n // Add all of the exports in this export statement to the exportMap\n getExportReferences(exportClause, moduleSpecifier, analyzer).forEach(\n ({exportName, decNameOrRef}) =>\n exportMap.set(exportName, decNameOrRef)\n );\n }\n } else if (ts.isExportAssignment(statement)) {\n addDeclaration(\n getExportAssignmentVariableDeclarationInfo(statement, analyzer)\n );\n } else if (ts.isImportDeclaration(statement)) {\n const path = getPathForModuleSpecifierExpression(\n statement.moduleSpecifier,\n analyzer\n );\n if (path !== undefined) {\n dependencies.add(path);\n }\n }\n }\n // Construct module and save in cache\n const module = new Module({\n ...getModuleInfo(modulePath, analyzer, packageInfo),\n sourceFile,\n declarationMap,\n dependencies,\n exportMap,\n finalizeExports: () => finalizeExports(reexports, exportMap, analyzer),\n ...parseModuleJSDocInfo(sourceFile, analyzer),\n });\n analyzer.moduleCache.set(\n analyzer.path.normalize(sourceFile.fileName) as AbsolutePath,\n module\n );\n return module;\n};\n\n/**\n * For any re-exported modules (i.e. `export * from 'foo'`), add all of the\n * exported names of the reexported module to the given exportMap, with\n * References into that module.\n */\nconst finalizeExports = (\n reexportSpecifiers: ts.Expression[],\n exportMap: ExportMap,\n analyzer: AnalyzerInterface\n) => {\n for (const moduleSpecifier of reexportSpecifiers) {\n const path = getPathForModuleSpecifierExpression(moduleSpecifier, analyzer);\n if (path === undefined) {\n continue;\n }\n const module = getModule(path, analyzer);\n for (const name of module.exportNames) {\n exportMap.set(\n name,\n getImportReferenceForSpecifierExpression(\n moduleSpecifier,\n name,\n analyzer\n )\n );\n }\n }\n};\n\n/**\n * Returns a cached Module model for the given module path if it and all of its\n * dependencies' models are still valid since the model was cached. If the\n * cached module is out-of-date and needs to be re-created, this method returns\n * undefined.\n */\nconst getAndValidateModuleFromCache = (\n modulePath: AbsolutePath,\n analyzer: AnalyzerInterface,\n seen = new Set<AbsolutePath>([modulePath])\n): Module | undefined => {\n const module = analyzer.moduleCache.get(modulePath);\n // A cached module is only valid if the source file that was used has not\n // changed in the current program, and if all of its dependencies are still\n // valid\n if (module !== undefined) {\n if (\n module.sourceFile === analyzer.program.getSourceFile(modulePath) &&\n depsAreValid(module, analyzer, seen)\n ) {\n return module;\n }\n analyzer.moduleCache.delete(modulePath);\n }\n return undefined;\n};\n\n/**\n * Returns true if all dependencies of the module are still valid.\n */\nconst depsAreValid = (\n module: Module,\n analyzer: AnalyzerInterface,\n seen: Set<AbsolutePath>\n): boolean =>\n Array.from(module.dependencies).every(\n (path) =>\n // `seen` is initialized only once, at the entry point for the initial\n // call to `getAndValidateModuleFromCache`, and modulePaths are only added\n // to `seen` at the deepest part of the recursion, in `depIsValid`\n // because of that, we can be confident that a module path which was 'seen'\n // has already been validated by `depIsValid` and can be safely skipped here.\n seen.has(path) || depIsValid(path, analyzer, seen)\n );\n\n/**\n * Returns true if the given dependency is valid, meaning that if it has a\n * cached model, the model is still valid. Dependencies that don't yet have a\n * cached model are considered valid.\n */\nconst depIsValid = (\n modulePath: AbsolutePath,\n analyzer: AnalyzerInterface,\n seen: Set<AbsolutePath>\n) => {\n seen.add(modulePath);\n if (analyzer.moduleCache.has(modulePath)) {\n // If a dep has a model, it is valid only if its deps are valid\n return Boolean(getAndValidateModuleFromCache(modulePath, analyzer, seen));\n } else {\n // Deps that don't have a cached model are considered valid\n return true;\n }\n};\n\n/**\n * For a given source file, return its associated JS file.\n *\n * For a JS source file, these will be the same thing. For a TS file, we use the\n * TS API to determine where the associated JS will be output based on tsconfig\n * settings.\n */\nconst getJSPathFromSourcePath = (\n sourcePath: AbsolutePath,\n analyzer: AnalyzerInterface\n) => {\n sourcePath = analyzer.path.normalize(sourcePath) as AbsolutePath;\n // If the source file was already JS, just return that\n if (sourcePath.endsWith('.js')) {\n return sourcePath;\n }\n // TODO(kschaaf): If the source file was a declaration file, this means we're\n // likely getting information about an externally imported package that had\n // types. In this case, we'll need to update our logic to resolve the import\n // specifier to the JS path (in addition to the source file path that we do\n // today). Unfortunately, TS's specifier resolver always prefers a declaration\n // file, and due to type roots and other tsconfig fancies, it's not\n // straightforward to go from a declaration file to a source file. In order to\n // properly implement this we'll probably need to bring our own node module\n // resolver ala https://www.npmjs.com/package/resolve. That change should be\n // done along with the custom-elements.json manifest work.\n if (sourcePath.endsWith('.d.ts')) {\n return undefined;\n }\n // Use the TS API to determine where the associated JS will be output based\n // on tsconfig settings.\n const outputPath = analyzer.typescript\n .getOutputFileNames(analyzer.commandLine, sourcePath, false)\n .filter((f) => f.endsWith('.js'))[0];\n // TODO(kschaaf): this could happen if someone imported only a .d.ts file;\n // we might need to handle this differently\n if (outputPath === undefined) {\n throw new Error(`Could not determine output filename for '${sourcePath}'`);\n }\n // The filename appears to come out of the ts API with\n // unix separators; since sourcePath uses OS separators, normalize this so\n // that all our model paths are OS-native\n return analyzer.path.normalize(outputPath) as AbsolutePath;\n};\n\n/**\n * Resolves a module specifier expression node to an absolute path on disk.\n */\nexport const getPathForModuleSpecifierExpression = (\n specifierExpression: ts.Expression,\n analyzer: AnalyzerInterface\n): AbsolutePath | undefined => {\n const specifier = getSpecifierString(specifierExpression);\n return getPathForModuleSpecifier(specifier, specifierExpression, analyzer);\n};\n\n/**\n * Resolve a module specifier to an absolute path on disk.\n */\nexport const getPathForModuleSpecifier = (\n specifier: string,\n location: ts.Node,\n analyzer: AnalyzerInterface\n): AbsolutePath | undefined => {\n const resolvedPath = analyzer.typescript.resolveModuleName(\n specifier,\n location.getSourceFile().fileName,\n analyzer.commandLine.options,\n analyzer.fs\n ).resolvedModule?.resolvedFileName;\n if (resolvedPath === undefined) {\n analyzer.addDiagnostic(\n createDiagnostic({\n typescript: analyzer.typescript,\n node: location,\n message: `Could not resolve specifier ${specifier} to filesystem path.`,\n category: analyzer.typescript.DiagnosticCategory.Error,\n })\n );\n return undefined;\n }\n return analyzer.path.normalize(resolvedPath) as AbsolutePath;\n};\n\n/**\n * Returns the declaration for the named export of the given module path;\n * note that if the given module re-exported a declaration from another\n * module, references are followed to the concrete declaration, which is\n * returned.\n */\nexport const getResolvedExportFromSourcePath = (\n modulePath: AbsolutePath,\n name: string,\n analyzer: AnalyzerInterface\n) => getModule(modulePath, analyzer)?.getResolvedExport(name);\n"]}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { AnalyzerInterface, PackageInfo } from '../model.js';
7
+ import { AbsolutePath } from '../paths.js';
8
+ /**
9
+ * Starting from a given module path, searches up until the nearest package.json
10
+ * is found, returning that folder. If none is found, an error is thrown.
11
+ */
12
+ export declare const getPackageRootForModulePath: (modulePath: AbsolutePath, analyzer: AnalyzerInterface) => AbsolutePath;
13
+ /**
14
+ * Returns an analyzer `PackageInfo` model for the nearest package of the given
15
+ * path.
16
+ */
17
+ export declare const getPackageInfo: (path: AbsolutePath, analyzer: AnalyzerInterface) => PackageInfo;
18
+ //# sourceMappingURL=packages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packages.d.ts","sourceRoot":"","sources":["../../src/lib/javascript/packages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,iBAAiB,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AACxE,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GACtC,YAAY,YAAY,EACxB,UAAU,iBAAiB,KAC1B,YAYF,CAAC;AAkBF;;;GAGG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,YAAY,EAClB,UAAU,iBAAiB,gBAe5B,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { PackageInfo } from '../model.js';
7
+ /**
8
+ * Starting from a given module path, searches up until the nearest package.json
9
+ * is found, returning that folder. If none is found, an error is thrown.
10
+ */
11
+ export const getPackageRootForModulePath = (modulePath, analyzer) => {
12
+ // TODO(kschaaf): Add caching & invalidation
13
+ const { fs, path } = analyzer;
14
+ let searchDir = modulePath;
15
+ const root = path.parse(searchDir).root;
16
+ while (!fs.fileExists(path.join(searchDir, 'package.json'))) {
17
+ if (searchDir === root) {
18
+ throw new Error(`No package.json found for module path ${modulePath}`);
19
+ }
20
+ searchDir = path.dirname(searchDir);
21
+ }
22
+ return searchDir;
23
+ };
24
+ /**
25
+ * Reads and parses a package.json file contained in the given folder.
26
+ */
27
+ const getPackageJsonFromPackageRoot = (packageRoot, analyzer) => {
28
+ // TODO(kschaaf): Add caching & invalidation
29
+ const { fs, path } = analyzer;
30
+ const packageJson = fs.readFile(path.join(packageRoot, 'package.json'));
31
+ if (packageJson !== undefined) {
32
+ return JSON.parse(packageJson);
33
+ }
34
+ throw new Error(`No package.json found at ${packageRoot}`);
35
+ };
36
+ /**
37
+ * Returns an analyzer `PackageInfo` model for the nearest package of the given
38
+ * path.
39
+ */
40
+ export const getPackageInfo = (path, analyzer) => {
41
+ const rootDir = getPackageRootForModulePath(path, analyzer);
42
+ const packageJson = getPackageJsonFromPackageRoot(rootDir, analyzer);
43
+ const { name } = packageJson;
44
+ if (name === undefined) {
45
+ throw new Error(`Expected package name in ${analyzer.path.join(rootDir, 'package.json')}`);
46
+ }
47
+ return new PackageInfo({
48
+ name,
49
+ rootDir: analyzer.path.normalize(rootDir),
50
+ packageJson,
51
+ });
52
+ };
53
+ //# sourceMappingURL=packages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packages.js","sourceRoot":"","sources":["../../src/lib/javascript/packages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAoB,WAAW,EAAc,MAAM,aAAa,CAAC;AAGxE;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CACzC,UAAwB,EACxB,QAA2B,EACb,EAAE;IAChB,4CAA4C;IAC5C,MAAM,EAAC,EAAE,EAAE,IAAI,EAAC,GAAG,QAAQ,CAAC;IAC5B,IAAI,SAAS,GAAG,UAAoB,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;QAC5D,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,yCAAyC,UAAU,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,SAAyB,CAAC;AACnC,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,6BAA6B,GAAG,CACpC,WAAyB,EACzB,QAA2B,EACd,EAAE;IACf,4CAA4C;IAC5C,MAAM,EAAC,EAAE,EAAE,IAAI,EAAC,GAAG,QAAQ,CAAC;IAC5B,MAAM,WAAW,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;IACxE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAgB,CAAC;IAChD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,4BAA4B,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,IAAkB,EAClB,QAA2B,EAC3B,EAAE;IACF,MAAM,OAAO,GAAG,2BAA2B,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,6BAA6B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACrE,MAAM,EAAC,IAAI,EAAC,GAAG,WAAW,CAAC;IAC3B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,4BAA4B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,CAC1E,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,WAAW,CAAC;QACrB,IAAI;QACJ,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAiB;QACzD,WAAW;KACZ,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport {AnalyzerInterface, PackageInfo, PackageJson} from '../model.js';\nimport {AbsolutePath} from '../paths.js';\n\n/**\n * Starting from a given module path, searches up until the nearest package.json\n * is found, returning that folder. If none is found, an error is thrown.\n */\nexport const getPackageRootForModulePath = (\n modulePath: AbsolutePath,\n analyzer: AnalyzerInterface\n): AbsolutePath => {\n // TODO(kschaaf): Add caching & invalidation\n const {fs, path} = analyzer;\n let searchDir = modulePath as string;\n const root = path.parse(searchDir).root;\n while (!fs.fileExists(path.join(searchDir, 'package.json'))) {\n if (searchDir === root) {\n throw new Error(`No package.json found for module path ${modulePath}`);\n }\n searchDir = path.dirname(searchDir);\n }\n return searchDir as AbsolutePath;\n};\n\n/**\n * Reads and parses a package.json file contained in the given folder.\n */\nconst getPackageJsonFromPackageRoot = (\n packageRoot: AbsolutePath,\n analyzer: AnalyzerInterface\n): PackageJson => {\n // TODO(kschaaf): Add caching & invalidation\n const {fs, path} = analyzer;\n const packageJson = fs.readFile(path.join(packageRoot, 'package.json'));\n if (packageJson !== undefined) {\n return JSON.parse(packageJson) as PackageJson;\n }\n throw new Error(`No package.json found at ${packageRoot}`);\n};\n\n/**\n * Returns an analyzer `PackageInfo` model for the nearest package of the given\n * path.\n */\nexport const getPackageInfo = (\n path: AbsolutePath,\n analyzer: AnalyzerInterface\n) => {\n const rootDir = getPackageRootForModulePath(path, analyzer);\n const packageJson = getPackageJsonFromPackageRoot(rootDir, analyzer);\n const {name} = packageJson;\n if (name === undefined) {\n throw new Error(\n `Expected package name in ${analyzer.path.join(rootDir, 'package.json')}`\n );\n }\n return new PackageInfo({\n name,\n rootDir: analyzer.path.normalize(rootDir) as AbsolutePath,\n packageJson,\n });\n};\n"]}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ /**
7
+ * @fileoverview
8
+ *
9
+ * Utilities for analyzing variable declarations
10
+ */
11
+ import type ts from 'typescript';
12
+ import { VariableDeclaration, AnalyzerInterface, DeclarationInfo } from '../model.js';
13
+ export type TypeScript = typeof ts;
14
+ /**
15
+ * Returns name and model factories for all variable
16
+ * declarations in a variable statement.
17
+ */
18
+ export declare const getVariableDeclarationInfo: (statement: ts.VariableStatement, analyzer: AnalyzerInterface) => DeclarationInfo[];
19
+ /**
20
+ * Returns declaration info & factory for a default export assignment.
21
+ */
22
+ export declare const getExportAssignmentVariableDeclarationInfo: (exportAssignment: ts.ExportAssignment, analyzer: AnalyzerInterface) => DeclarationInfo;
23
+ export declare const getEnumDeclarationInfo: (dec: ts.EnumDeclaration, analyzer: AnalyzerInterface) => {
24
+ name: string;
25
+ node: ts.EnumDeclaration;
26
+ factory: () => VariableDeclaration;
27
+ isExport: boolean;
28
+ };
29
+ //# sourceMappingURL=variables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../src/lib/javascript/variables.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EAEhB,MAAM,aAAa,CAAC;AASrB,MAAM,MAAM,UAAU,GAAG,OAAO,EAAE,CAAC;AA8DnC;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GACrC,WAAW,EAAE,CAAC,iBAAiB,EAC/B,UAAU,iBAAiB,KAC1B,eAAe,EAQjB,CAAC;AA0DF;;GAEG;AACH,eAAO,MAAM,0CAA0C,GACrD,kBAAkB,EAAE,CAAC,gBAAgB,EACrC,UAAU,iBAAiB,KAC1B,eAQF,CAAC;AAsBF,eAAO,MAAM,sBAAsB,GACjC,KAAK,EAAE,CAAC,eAAe,EACvB,UAAU,iBAAiB;;;;;CAQ5B,CAAC"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { VariableDeclaration, } from '../model.js';
7
+ import { hasExportModifier } from '../utils.js';
8
+ import { getTypeForNode } from '../types.js';
9
+ import { parseNodeJSDocInfo } from './jsdoc.js';
10
+ import { getFunctionDeclaration } from './functions.js';
11
+ import { getClassDeclaration, maybeGetAppliedMixin } from './classes.js';
12
+ import { createDiagnostic } from '../errors.js';
13
+ import { DiagnosticCode } from '../diagnostic-code.js';
14
+ /**
15
+ * Returns an analyzer `VariableDeclaration` model for the given
16
+ * ts.Identifier within a potentially nested ts.VariableDeclaration.
17
+ */
18
+ const getVariableDeclaration = (statement, dec, name, analyzer) => {
19
+ const { typescript: ts } = analyzer;
20
+ // For const variable declarations initialized to functions or classes, we
21
+ // treat these as FunctionDeclaration and ClassDeclaration, respectively since
22
+ // they are (mostly) unobservably different to the module consumer and we can
23
+ // give better docs this way
24
+ if (ts.isVariableDeclaration(dec) &&
25
+ Boolean(statement.declarationList.flags & ts.NodeFlags.Const) &&
26
+ dec.initializer !== undefined) {
27
+ const { initializer } = dec;
28
+ if (ts.isArrowFunction(initializer) ||
29
+ ts.isFunctionExpression(initializer)) {
30
+ return getFunctionDeclaration(initializer, name.getText(), analyzer, statement);
31
+ }
32
+ else if (ts.isClassExpression(initializer)) {
33
+ return getClassDeclaration(initializer, name.getText(), analyzer, statement);
34
+ }
35
+ else {
36
+ // This supports const assignments of mixins applied to classes, ala:
37
+ // `export const MyClassWithSomeMixin = SomeMixin(MyClass);`
38
+ const classDec = maybeGetAppliedMixin(initializer, name, analyzer);
39
+ if (classDec !== undefined) {
40
+ return classDec;
41
+ }
42
+ }
43
+ }
44
+ return new VariableDeclaration({
45
+ name: name.text,
46
+ node: dec,
47
+ type: getTypeForNode(name, analyzer),
48
+ ...parseNodeJSDocInfo(statement, analyzer),
49
+ });
50
+ };
51
+ /**
52
+ * Returns name and model factories for all variable
53
+ * declarations in a variable statement.
54
+ */
55
+ export const getVariableDeclarationInfo = (statement, analyzer) => {
56
+ const isExport = hasExportModifier(analyzer.typescript, statement);
57
+ const { declarationList } = statement;
58
+ return declarationList.declarations
59
+ .map((d) => getVariableDeclarationInfoList(statement, d, d.name, isExport, analyzer))
60
+ .flat();
61
+ };
62
+ /**
63
+ * For a given `VariableName` (which might be a simple identifier or a
64
+ * destructuring pattern which contains more identifiers), return an array of
65
+ * tuples of name and factory for each declaration.
66
+ */
67
+ const getVariableDeclarationInfoList = (statement, dec, name, isExport, analyzer) => {
68
+ const { typescript: ts } = analyzer;
69
+ if (ts.isIdentifier(name)) {
70
+ return [
71
+ {
72
+ name: name.text,
73
+ node: name,
74
+ factory: () => getVariableDeclaration(statement, dec, name, analyzer),
75
+ isExport,
76
+ },
77
+ ];
78
+ }
79
+ else if (
80
+ // Recurse into the elements of an array/object destructuring variable
81
+ // declaration to find the identifiers
82
+ ts.isObjectBindingPattern(name) ||
83
+ ts.isArrayBindingPattern(name)) {
84
+ const els = name.elements.filter((el) => ts.isBindingElement(el));
85
+ return els
86
+ .map((el) => getVariableDeclarationInfoList(statement, dec, el.name, isExport, analyzer))
87
+ .flat();
88
+ }
89
+ else {
90
+ analyzer.addDiagnostic(createDiagnostic({
91
+ typescript: ts,
92
+ node: dec,
93
+ message: `Expected declaration name to either be an identifier or a destructuring`,
94
+ category: ts.DiagnosticCategory.Warning,
95
+ code: DiagnosticCode.UNSUPPORTED,
96
+ }));
97
+ return [];
98
+ }
99
+ };
100
+ /**
101
+ * Returns declaration info & factory for a default export assignment.
102
+ */
103
+ export const getExportAssignmentVariableDeclarationInfo = (exportAssignment, analyzer) => {
104
+ return {
105
+ name: 'default',
106
+ node: exportAssignment,
107
+ factory: () => getExportAssignmentVariableDeclaration(exportAssignment, analyzer),
108
+ isExport: true,
109
+ };
110
+ };
111
+ /**
112
+ * Returns an analyzer `VariableDeclaration` model for the given default
113
+ * ts.ExportAssignment, handling the case of: `export const 'some expression'`;
114
+ *
115
+ * Note that even though this technically isn't a VariableDeclaration in
116
+ * TS, we model it as one since it could unobservably be implemented as
117
+ * `const varDec = 'some expression'; export {varDec as default} `
118
+ */
119
+ const getExportAssignmentVariableDeclaration = (exportAssignment, analyzer) => {
120
+ return new VariableDeclaration({
121
+ name: 'default',
122
+ node: exportAssignment,
123
+ type: getTypeForNode(exportAssignment.expression, analyzer),
124
+ ...parseNodeJSDocInfo(exportAssignment, analyzer),
125
+ });
126
+ };
127
+ export const getEnumDeclarationInfo = (dec, analyzer) => {
128
+ return {
129
+ name: dec.name.text,
130
+ node: dec,
131
+ factory: () => getEnumDeclaration(dec, analyzer),
132
+ isExport: hasExportModifier(analyzer.typescript, dec),
133
+ };
134
+ };
135
+ const getEnumDeclaration = (dec, analyzer) => {
136
+ return new VariableDeclaration({
137
+ name: dec.name.text,
138
+ node: dec,
139
+ type: getTypeForNode(dec.name, analyzer),
140
+ ...parseNodeJSDocInfo(dec, analyzer),
141
+ });
142
+ };
143
+ //# sourceMappingURL=variables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variables.js","sourceRoot":"","sources":["../../src/lib/javascript/variables.ts"],"names":[],"mappings":"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","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 variable declarations\n */\n\nimport type ts from 'typescript';\nimport {\n VariableDeclaration,\n AnalyzerInterface,\n DeclarationInfo,\n Declaration,\n} from '../model.js';\nimport {hasExportModifier} from '../utils.js';\nimport {getTypeForNode} from '../types.js';\nimport {parseNodeJSDocInfo} from './jsdoc.js';\nimport {getFunctionDeclaration} from './functions.js';\nimport {getClassDeclaration, maybeGetAppliedMixin} from './classes.js';\nimport {createDiagnostic} from '../errors.js';\nimport {DiagnosticCode} from '../diagnostic-code.js';\n\nexport type TypeScript = typeof ts;\n\ntype VariableName =\n | ts.Identifier\n | ts.ObjectBindingPattern\n | ts.ArrayBindingPattern;\n\n/**\n * Returns an analyzer `VariableDeclaration` model for the given\n * ts.Identifier within a potentially nested ts.VariableDeclaration.\n */\nconst getVariableDeclaration = (\n statement: ts.VariableStatement,\n dec: ts.VariableDeclaration,\n name: ts.Identifier,\n analyzer: AnalyzerInterface\n): Declaration => {\n const {typescript: ts} = analyzer;\n // For const variable declarations initialized to functions or classes, we\n // treat these as FunctionDeclaration and ClassDeclaration, respectively since\n // they are (mostly) unobservably different to the module consumer and we can\n // give better docs this way\n if (\n ts.isVariableDeclaration(dec) &&\n Boolean(statement.declarationList.flags & ts.NodeFlags.Const) &&\n dec.initializer !== undefined\n ) {\n const {initializer} = dec;\n if (\n ts.isArrowFunction(initializer) ||\n ts.isFunctionExpression(initializer)\n ) {\n return getFunctionDeclaration(\n initializer,\n name.getText(),\n analyzer,\n statement\n );\n } else if (ts.isClassExpression(initializer)) {\n return getClassDeclaration(\n initializer,\n name.getText(),\n analyzer,\n statement\n );\n } else {\n // This supports const assignments of mixins applied to classes, ala:\n // `export const MyClassWithSomeMixin = SomeMixin(MyClass);`\n const classDec = maybeGetAppliedMixin(initializer, name, analyzer);\n if (classDec !== undefined) {\n return classDec;\n }\n }\n }\n return new VariableDeclaration({\n name: name.text,\n node: dec,\n type: getTypeForNode(name, analyzer),\n ...parseNodeJSDocInfo(statement, analyzer),\n });\n};\n\n/**\n * Returns name and model factories for all variable\n * declarations in a variable statement.\n */\nexport const getVariableDeclarationInfo = (\n statement: ts.VariableStatement,\n analyzer: AnalyzerInterface\n): DeclarationInfo[] => {\n const isExport = hasExportModifier(analyzer.typescript, statement);\n const {declarationList} = statement;\n return declarationList.declarations\n .map((d) =>\n getVariableDeclarationInfoList(statement, d, d.name, isExport, analyzer)\n )\n .flat();\n};\n\n/**\n * For a given `VariableName` (which might be a simple identifier or a\n * destructuring pattern which contains more identifiers), return an array of\n * tuples of name and factory for each declaration.\n */\nconst getVariableDeclarationInfoList = (\n statement: ts.VariableStatement,\n dec: ts.VariableDeclaration,\n name: VariableName,\n isExport: boolean,\n analyzer: AnalyzerInterface\n): DeclarationInfo[] => {\n const {typescript: ts} = analyzer;\n if (ts.isIdentifier(name)) {\n return [\n {\n name: name.text,\n node: name,\n factory: () => getVariableDeclaration(statement, dec, name, analyzer),\n isExport,\n },\n ];\n } else if (\n // Recurse into the elements of an array/object destructuring variable\n // declaration to find the identifiers\n ts.isObjectBindingPattern(name) ||\n ts.isArrayBindingPattern(name)\n ) {\n const els = name.elements.filter((el) =>\n ts.isBindingElement(el)\n ) as ts.BindingElement[];\n return els\n .map((el) =>\n getVariableDeclarationInfoList(\n statement,\n dec,\n el.name,\n isExport,\n analyzer\n )\n )\n .flat();\n } else {\n analyzer.addDiagnostic(\n createDiagnostic({\n typescript: ts,\n node: dec,\n message: `Expected declaration name to either be an identifier or a destructuring`,\n category: ts.DiagnosticCategory.Warning,\n code: DiagnosticCode.UNSUPPORTED,\n })\n );\n return [];\n }\n};\n\n/**\n * Returns declaration info & factory for a default export assignment.\n */\nexport const getExportAssignmentVariableDeclarationInfo = (\n exportAssignment: ts.ExportAssignment,\n analyzer: AnalyzerInterface\n): DeclarationInfo => {\n return {\n name: 'default',\n node: exportAssignment,\n factory: () =>\n getExportAssignmentVariableDeclaration(exportAssignment, analyzer),\n isExport: true,\n };\n};\n\n/**\n * Returns an analyzer `VariableDeclaration` model for the given default\n * ts.ExportAssignment, handling the case of: `export const 'some expression'`;\n *\n * Note that even though this technically isn't a VariableDeclaration in\n * TS, we model it as one since it could unobservably be implemented as\n * `const varDec = 'some expression'; export {varDec as default} `\n */\nconst getExportAssignmentVariableDeclaration = (\n exportAssignment: ts.ExportAssignment,\n analyzer: AnalyzerInterface\n): VariableDeclaration => {\n return new VariableDeclaration({\n name: 'default',\n node: exportAssignment,\n type: getTypeForNode(exportAssignment.expression, analyzer),\n ...parseNodeJSDocInfo(exportAssignment, analyzer),\n });\n};\n\nexport const getEnumDeclarationInfo = (\n dec: ts.EnumDeclaration,\n analyzer: AnalyzerInterface\n) => {\n return {\n name: dec.name.text,\n node: dec,\n factory: () => getEnumDeclaration(dec, analyzer),\n isExport: hasExportModifier(analyzer.typescript, dec),\n };\n};\n\nconst getEnumDeclaration = (\n dec: ts.EnumDeclaration,\n analyzer: AnalyzerInterface\n) => {\n return new VariableDeclaration({\n name: dec.name.text,\n node: dec,\n type: getTypeForNode(dec.name, analyzer),\n ...parseNodeJSDocInfo(dec, analyzer),\n });\n};\n"]}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ /**
7
+ * @fileoverview
8
+ *
9
+ * Utilities for analyzing ReactiveElement decorators.
10
+ */
11
+ import type ts from 'typescript';
12
+ export type TypeScript = typeof ts;
13
+ export declare const isCustomElementDecorator: (ts: TypeScript, decorator: ts.Decorator) => decorator is CustomElementDecorator;
14
+ /**
15
+ * A narrower type for ts.Decorator that represents the shape of an analyzable
16
+ * `@customElement('x')` callsite.
17
+ */
18
+ export interface CustomElementDecorator extends ts.Decorator {
19
+ readonly expression: ts.CallExpression;
20
+ }
21
+ export declare const getPropertyDecorator: (ts: TypeScript, declaration: ts.PropertyDeclaration) => PropertyDecorator | undefined;
22
+ /**
23
+ * A narrower type for ts.Decorator that represents the shape of an analyzable
24
+ * `@customElement('x')` callsite.
25
+ */
26
+ interface PropertyDecorator extends ts.Decorator {
27
+ readonly expression: ts.CallExpression;
28
+ }
29
+ /**
30
+ * Gets the property options object from a `@property()` decorator callsite.
31
+ *
32
+ * Only works with an object literal passed as the first argument.
33
+ */
34
+ export declare const getPropertyOptions: (ts: TypeScript, decorator: PropertyDecorator) => ts.ObjectLiteralExpression | undefined;
35
+ export {};
36
+ //# sourceMappingURL=decorators.d.ts.map