@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
package/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2022 Google LLC. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # @lit-labs/analyzer
2
+
3
+ A static analyzer for Lit
4
+
5
+ > [!WARNING]
6
+ >
7
+ > This package is part of [Lit Labs](https://lit.dev/docs/libraries/labs/). It
8
+ > is published in order to get feedback on the design and may receive breaking
9
+ > changes or stop being supported.
10
+ >
11
+ > Please read our [Lit Labs documentation](https://lit.dev/docs/libraries/labs/)
12
+ > before using this library in production.
13
+
14
+ ## Overview
15
+
16
+ This package contains static analysis utilities for analyzing source code that contain Lit templates and elements, that might be useful for other programs like linters, IDE plugins, code generators, etc.
17
+
18
+ This is a very early stage Lit Labs package and is not ready for use.
19
+
20
+ ## Usage
21
+
22
+ _This section is incomplete_
23
+
24
+ ### Node
25
+
26
+ ```ts
27
+ import {createPackageAnalyzer} from '@lit-labs/analyzer/package-analyzer.js';
28
+ import * as path from 'path';
29
+
30
+ const packagePath = path.resolve('./my-package');
31
+ const analyzer = createPackageAnalyzer(packagePath);
32
+ const module = analyzer.getModule(
33
+ path.resolve(packagePath, 'src/my-element.ts')
34
+ );
35
+ ```
36
+
37
+ ### Browser
38
+
39
+ You must use a bundler to bundle TypeScript, such as Rollup with the CommonJS plugin.
40
+
41
+ With `@rollup/plugin-commonjs` you need to ignore built-in libraries like `os`, `fs`, etc. You can isgnore these in your Rollup config:
42
+
43
+ rollup.config.js:
44
+
45
+ ```ts
46
+ import commonjs from '@rollup/plugin-commonjs';
47
+
48
+ // ...
49
+ plugins: [
50
+ commonjs({
51
+ ignore: (id) => ['fs', 'os', 'inspector'].includes(id),
52
+ }),
53
+ ],
54
+ // ...
55
+ ```
56
+
57
+ You may need to install the `'path'` package:
58
+
59
+ ```sh
60
+ npm i path
61
+ ```
62
+
63
+ Then you can make an Analyzer using these imports:
64
+
65
+ ```ts
66
+ import {Analyzer} from '@lit-labs/analyzer/lib/analyzer.js';
67
+ import {AbsolutePath} from '@lit-labs/analyzer/lib/paths.js';
68
+ import ts from 'typescript';
69
+ import * as path from 'path';
70
+
71
+ // TODO: show constructing an Analyzer in browser contexts
72
+ ```
73
+
74
+ ## Contributing
75
+
76
+ Please see [CONTRIBUTING.md](../../../CONTRIBUTING.md).
package/index.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ export { Analyzer } from './lib/analyzer.js';
7
+ export type { Package, Module, Reference, Type, Event, Declaration, VariableDeclaration, ClassDeclaration, ClassField, ClassMethod, Parameter, Return, LitElementDeclaration, MixinDeclaration, CustomElementDeclaration, LitElementExport, PackageJson, ModuleWithLitElementDeclarations, DeprecatableDescribed, FunctionDeclaration, } from './lib/model.js';
8
+ export type { AbsolutePath, PackagePath } from './lib/paths.js';
9
+ export { getImportsStringForReferences } from './lib/model.js';
10
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAE3C,YAAY,EACV,OAAO,EACP,MAAM,EACN,SAAS,EACT,IAAI,EACJ,KAAK,EACL,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,SAAS,EACT,MAAM,EACN,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,EACxB,gBAAgB,EAChB,WAAW,EACX,gCAAgC,EAChC,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAC,YAAY,EAAE,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAI9D,OAAO,EAAC,6BAA6B,EAAC,MAAM,gBAAgB,CAAC"}
package/index.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ export { Analyzer } from './lib/analyzer.js';
7
+ // Any non-type exports below must be safe to use on objects between multiple
8
+ // versions of the analyzer library
9
+ export { getImportsStringForReferences } from './lib/model.js';
10
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AA2B3C,6EAA6E;AAC7E,mCAAmC;AACnC,OAAO,EAAC,6BAA6B,EAAC,MAAM,gBAAgB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nexport {Analyzer} from './lib/analyzer.js';\n\nexport type {\n Package,\n Module,\n Reference,\n Type,\n Event,\n Declaration,\n VariableDeclaration,\n ClassDeclaration,\n ClassField,\n ClassMethod,\n Parameter,\n Return,\n LitElementDeclaration,\n MixinDeclaration,\n CustomElementDeclaration,\n LitElementExport,\n PackageJson,\n ModuleWithLitElementDeclarations,\n DeprecatableDescribed,\n FunctionDeclaration,\n} from './lib/model.js';\n\nexport type {AbsolutePath, PackagePath} from './lib/paths.js';\n\n// Any non-type exports below must be safe to use on objects between multiple\n// versions of the analyzer library\nexport {getImportsStringForReferences} from './lib/model.js';\n"]}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import type ts from 'typescript';
7
+ import { AnalyzerInterface, Module, Package, PackageJson } from './model.js';
8
+ import { AbsolutePath } from './paths.js';
9
+ export { PackageJson };
10
+ export type TypeScript = typeof ts;
11
+ export interface AnalyzerInit {
12
+ typescript: TypeScript;
13
+ getProgram: () => ts.Program;
14
+ fs: AnalyzerInterface['fs'];
15
+ path: AnalyzerInterface['path'];
16
+ basePath?: AbsolutePath;
17
+ }
18
+ /**
19
+ * An analyzer for Lit typescript modules.
20
+ */
21
+ export declare class Analyzer implements AnalyzerInterface {
22
+ readonly moduleCache: Map<AbsolutePath, Module>;
23
+ private readonly _getProgram;
24
+ readonly typescript: TypeScript;
25
+ readonly fs: AnalyzerInterface['fs'];
26
+ readonly path: AnalyzerInterface['path'];
27
+ private _commandLine;
28
+ private readonly diagnostics;
29
+ constructor(init: AnalyzerInit);
30
+ get program(): ts.Program;
31
+ get commandLine(): ts.ParsedCommandLine;
32
+ getModule(modulePath: AbsolutePath): Module;
33
+ getPackage(): Package;
34
+ addDiagnostic(diagnostic: ts.Diagnostic): void;
35
+ getDiagnostics(): Generator<ts.Diagnostic, void, unknown>;
36
+ }
37
+ /**
38
+ * Extracts a `ts.ParsedCommandLine` (essentially, the key bits of a
39
+ * `tsconfig.json`) from the analyzer's `ts.Program`.
40
+ *
41
+ * The `ts.getOutputFileNames()` function must be passed a
42
+ * `ts.ParsedCommandLine`; since not all usages of the analyzer create the
43
+ * program directly from a tsconfig (plugins get passed the program only),
44
+ * this allows backing the `ParsedCommandLine` out of an existing program.
45
+ */
46
+ export declare const getCommandLineFromProgram: (analyzer: Analyzer) => ts.ParsedCommandLine;
47
+ //# sourceMappingURL=analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/lib/analyzer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAMjC,OAAO,EAAC,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAC,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AACxC,OAAO,EAAC,WAAW,EAAC,CAAC;AAErB,MAAM,MAAM,UAAU,GAAG,OAAO,EAAE,CAAC;AAEnC,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC;IAC7B,EAAE,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED;;GAEG;AACH,qBAAa,QAAS,YAAW,iBAAiB;IAGhD,QAAQ,CAAC,WAAW,4BAAmC;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAC/C,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,EAAE,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;gBAEvC,IAAI,EAAE,YAAY;IAS9B,IAAI,OAAO,eAEV;IAED,IAAI,WAAW,yBAEd;IAED,SAAS,CAAC,UAAU,EAAE,YAAY;IAIlC,UAAU;IAuBV,aAAa,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU;IAItC,cAAc;CAGhB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GACpC,UAAU,QAAQ,KACjB,EAAE,CAAC,iBA+BL,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { getModule } from './javascript/modules.js';
7
+ import { getPackageInfo, getPackageRootForModulePath, } from './javascript/packages.js';
8
+ import { Package } from './model.js';
9
+ /**
10
+ * An analyzer for Lit typescript modules.
11
+ */
12
+ export class Analyzer {
13
+ constructor(init) {
14
+ // Cache of Module models by path; invalidated when the sourceFile
15
+ // or any of its dependencies change
16
+ this.moduleCache = new Map();
17
+ this._commandLine = undefined;
18
+ this.diagnostics = [];
19
+ ({
20
+ fs: this.fs,
21
+ path: this.path,
22
+ typescript: this.typescript,
23
+ getProgram: this._getProgram,
24
+ } = init);
25
+ }
26
+ get program() {
27
+ return this._getProgram();
28
+ }
29
+ get commandLine() {
30
+ return (this._commandLine ??= getCommandLineFromProgram(this));
31
+ }
32
+ getModule(modulePath) {
33
+ return getModule(modulePath, this);
34
+ }
35
+ getPackage() {
36
+ const rootFileNames = this.program.getRootFileNames();
37
+ // Find the package.json for this package based on the first root filename
38
+ // in the program (we assume all root files in a program belong to the same
39
+ // package)
40
+ if (rootFileNames.length === 0) {
41
+ throw new Error('No source files found in package.');
42
+ }
43
+ const packageInfo = getPackageInfo(rootFileNames[0], this);
44
+ return new Package({
45
+ ...packageInfo,
46
+ modules: rootFileNames.map((fileName) => getModule(this.path.normalize(fileName), this, packageInfo)),
47
+ });
48
+ }
49
+ addDiagnostic(diagnostic) {
50
+ this.diagnostics.push(diagnostic);
51
+ }
52
+ *getDiagnostics() {
53
+ yield* this.typescript.sortAndDeduplicateDiagnostics(this.diagnostics);
54
+ }
55
+ }
56
+ /**
57
+ * Extracts a `ts.ParsedCommandLine` (essentially, the key bits of a
58
+ * `tsconfig.json`) from the analyzer's `ts.Program`.
59
+ *
60
+ * The `ts.getOutputFileNames()` function must be passed a
61
+ * `ts.ParsedCommandLine`; since not all usages of the analyzer create the
62
+ * program directly from a tsconfig (plugins get passed the program only),
63
+ * this allows backing the `ParsedCommandLine` out of an existing program.
64
+ */
65
+ export const getCommandLineFromProgram = (analyzer) => {
66
+ const { program, typescript, path, fs } = analyzer;
67
+ const compilerOptions = program.getCompilerOptions();
68
+ const files = program.getRootFileNames();
69
+ const json = {
70
+ files,
71
+ compilerOptions,
72
+ };
73
+ if (compilerOptions.configFilePath !== undefined) {
74
+ // For a TS project, derive the package root from the config file path
75
+ const packageRoot = path.basename(compilerOptions.configFilePath);
76
+ return typescript.parseJsonConfigFileContent(json, fs, packageRoot, undefined, compilerOptions.configFilePath);
77
+ }
78
+ else {
79
+ // Otherwise, this is a JS project; we can determine the package root
80
+ // based on the package.json location; we can look that up based on
81
+ // the first root file
82
+ const packageRoot = getPackageRootForModulePath(files[0], analyzer
83
+ // Note we don't pass a configFilePath since we don't have one; This just
84
+ // means we can't use ts.getOutputFileNames(), which we isn't needed in
85
+ // JS program
86
+ );
87
+ return typescript.parseJsonConfigFileContent(json, fs, packageRoot);
88
+ }
89
+ };
90
+ //# sourceMappingURL=analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/lib/analyzer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport type ts from 'typescript';\nimport {getModule} from './javascript/modules.js';\nimport {\n getPackageInfo,\n getPackageRootForModulePath,\n} from './javascript/packages.js';\nimport {AnalyzerInterface, Module, Package, PackageJson} from './model.js';\nimport {AbsolutePath} from './paths.js';\nexport {PackageJson};\n\nexport type TypeScript = typeof ts;\n\nexport interface AnalyzerInit {\n typescript: TypeScript;\n getProgram: () => ts.Program;\n fs: AnalyzerInterface['fs'];\n path: AnalyzerInterface['path'];\n basePath?: AbsolutePath;\n}\n\n/**\n * An analyzer for Lit typescript modules.\n */\nexport class Analyzer implements AnalyzerInterface {\n // Cache of Module models by path; invalidated when the sourceFile\n // or any of its dependencies change\n readonly moduleCache = new Map<AbsolutePath, Module>();\n private readonly _getProgram: () => ts.Program;\n readonly typescript: TypeScript;\n readonly fs: AnalyzerInterface['fs'];\n readonly path: AnalyzerInterface['path'];\n private _commandLine: ts.ParsedCommandLine | undefined = undefined;\n private readonly diagnostics: ts.Diagnostic[] = [];\n\n constructor(init: AnalyzerInit) {\n ({\n fs: this.fs,\n path: this.path,\n typescript: this.typescript,\n getProgram: this._getProgram,\n } = init);\n }\n\n get program() {\n return this._getProgram();\n }\n\n get commandLine() {\n return (this._commandLine ??= getCommandLineFromProgram(this));\n }\n\n getModule(modulePath: AbsolutePath) {\n return getModule(modulePath, this);\n }\n\n getPackage() {\n const rootFileNames = this.program.getRootFileNames();\n\n // Find the package.json for this package based on the first root filename\n // in the program (we assume all root files in a program belong to the same\n // package)\n if (rootFileNames.length === 0) {\n throw new Error('No source files found in package.');\n }\n const packageInfo = getPackageInfo(rootFileNames[0] as AbsolutePath, this);\n\n return new Package({\n ...packageInfo,\n modules: rootFileNames.map((fileName) =>\n getModule(\n this.path.normalize(fileName) as AbsolutePath,\n this,\n packageInfo\n )\n ),\n });\n }\n\n addDiagnostic(diagnostic: ts.Diagnostic) {\n this.diagnostics.push(diagnostic);\n }\n\n *getDiagnostics() {\n yield* this.typescript.sortAndDeduplicateDiagnostics(this.diagnostics);\n }\n}\n\n/**\n * Extracts a `ts.ParsedCommandLine` (essentially, the key bits of a\n * `tsconfig.json`) from the analyzer's `ts.Program`.\n *\n * The `ts.getOutputFileNames()` function must be passed a\n * `ts.ParsedCommandLine`; since not all usages of the analyzer create the\n * program directly from a tsconfig (plugins get passed the program only),\n * this allows backing the `ParsedCommandLine` out of an existing program.\n */\nexport const getCommandLineFromProgram = (\n analyzer: Analyzer\n): ts.ParsedCommandLine => {\n const {program, typescript, path, fs} = analyzer;\n const compilerOptions = program.getCompilerOptions();\n const files = program.getRootFileNames();\n const json = {\n files,\n compilerOptions,\n };\n if (compilerOptions.configFilePath !== undefined) {\n // For a TS project, derive the package root from the config file path\n const packageRoot = path.basename(compilerOptions.configFilePath as string);\n return typescript.parseJsonConfigFileContent(\n json,\n fs,\n packageRoot,\n undefined,\n compilerOptions.configFilePath as string\n );\n } else {\n // Otherwise, this is a JS project; we can determine the package root\n // based on the package.json location; we can look that up based on\n // the first root file\n const packageRoot = getPackageRootForModulePath(\n files[0] as AbsolutePath,\n analyzer\n // Note we don't pass a configFilePath since we don't have one; This just\n // means we can't use ts.getOutputFileNames(), which we isn't needed in\n // JS program\n );\n return typescript.parseJsonConfigFileContent(json, fs, packageRoot);\n }\n};\n"]}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ /**
7
+ * @fileoverview
8
+ *
9
+ * Utilities for analyzing native custom elements (i.e. `HTMLElement`)
10
+ * subclasses.
11
+ */
12
+ import type ts from 'typescript';
13
+ import { AnalyzerInterface, CustomElementDeclaration, Event, NamedDescribed } from '../model.js';
14
+ export type CustomElementClassDeclaration = ts.ClassDeclaration & {
15
+ _customElementBrand: never;
16
+ };
17
+ export declare const isCustomElementSubclass: (node: ts.Node, analyzer: AnalyzerInterface) => node is CustomElementClassDeclaration;
18
+ export declare const getTagName: (node: ts.ClassDeclaration | ts.ClassExpression, analyzer: AnalyzerInterface) => string | undefined;
19
+ /**
20
+ * Parses element metadata from jsDoc tags from a LitElement declaration into
21
+ * Maps of <name, info>.
22
+ */
23
+ export declare const getJSDocData: (node: ts.ClassDeclaration, analyzer: AnalyzerInterface) => {
24
+ events: Map<string, Event>;
25
+ slots: Map<string, NamedDescribed>;
26
+ cssProperties: Map<string, NamedDescribed>;
27
+ cssParts: Map<string, NamedDescribed>;
28
+ deprecated?: string | boolean | undefined;
29
+ description?: string | undefined;
30
+ summary?: string | undefined;
31
+ };
32
+ export declare const getCustomElementDeclaration: (node: CustomElementClassDeclaration, analyzer: AnalyzerInterface, isMixinClass?: boolean) => CustomElementDeclaration;
33
+ //# sourceMappingURL=custom-elements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-elements.d.ts","sourceRoot":"","sources":["../../src/lib/custom-elements/custom-elements.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,KAAK,EACL,cAAc,EACf,MAAM,aAAa,CAAC;AAuBrB,MAAM,MAAM,6BAA6B,GAAG,EAAE,CAAC,gBAAgB,GAAG;IAChE,mBAAmB,EAAE,KAAK,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,MAAM,EAAE,CAAC,IAAI,EACb,UAAU,iBAAiB,KAC1B,IAAI,IAAI,6BAiBV,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,MAAM,EAAE,CAAC,gBAAgB,GAAG,EAAE,CAAC,eAAe,EAC9C,UAAU,iBAAiB,KAC1B,MAAM,GAAG,SAuCX,CAAC;AAiBF;;;GAGG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,EAAE,CAAC,gBAAgB,EACzB,UAAU,iBAAiB;;;;;;;;CAoC5B,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,MAAM,6BAA6B,EACnC,UAAU,iBAAiB,EAC3B,eAAe,OAAO,KACrB,wBASF,CAAC"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { getClassMembers, getHeritage } from '../javascript/classes.js';
7
+ import { CustomElementDeclaration, } from '../model.js';
8
+ import { addEventsToMap } from './events.js';
9
+ import { parseNodeJSDocInfo, parseNamedTypedJSDocInfo, } from '../javascript/jsdoc.js';
10
+ import { getBaseTypes } from '../utils.js';
11
+ const _isCustomElementClassDeclaration = (t, analyzer) => {
12
+ const declarations = t.getSymbol()?.getDeclarations();
13
+ return (declarations?.some((declaration) => (analyzer.typescript.isInterfaceDeclaration(declaration) &&
14
+ declaration.name?.text === 'HTMLElement') ||
15
+ isCustomElementSubclass(declaration, analyzer)) === true);
16
+ };
17
+ export const isCustomElementSubclass = (node, analyzer) => {
18
+ if (!analyzer.typescript.isClassLike(node)) {
19
+ return false;
20
+ }
21
+ if (getTagName(node, analyzer) !== undefined) {
22
+ return true;
23
+ }
24
+ const checker = analyzer.program.getTypeChecker();
25
+ const type = checker.getTypeAtLocation(node);
26
+ const baseTypes = getBaseTypes(type);
27
+ for (const t of baseTypes) {
28
+ if (_isCustomElementClassDeclaration(t, analyzer)) {
29
+ return true;
30
+ }
31
+ }
32
+ return false;
33
+ };
34
+ export const getTagName = (node, analyzer) => {
35
+ const jsdocTag = analyzer.typescript
36
+ .getJSDocTags(node)
37
+ .find((tag) => tag.tagName.text.toLowerCase() === 'customelement');
38
+ if (jsdocTag && typeof jsdocTag.comment === 'string') {
39
+ return jsdocTag.comment.trim();
40
+ }
41
+ let tagName = undefined;
42
+ // Otherwise, look for imperative define in the form of:
43
+ // `customElements.define('x-foo', XFoo);`
44
+ node.parent.forEachChild((child) => {
45
+ if (analyzer.typescript.isExpressionStatement(child) &&
46
+ analyzer.typescript.isCallExpression(child.expression) &&
47
+ analyzer.typescript.isPropertyAccessExpression(child.expression.expression) &&
48
+ child.expression.arguments.length >= 2) {
49
+ const [tagNameArg, ctorArg] = child.expression.arguments;
50
+ const { expression, name } = child.expression.expression;
51
+ if (analyzer.typescript.isIdentifier(expression) &&
52
+ expression.text === 'customElements' &&
53
+ analyzer.typescript.isIdentifier(name) &&
54
+ name.text === 'define' &&
55
+ analyzer.typescript.isStringLiteralLike(tagNameArg) &&
56
+ analyzer.typescript.isIdentifier(ctorArg) &&
57
+ ctorArg.text === node.name?.text) {
58
+ tagName = tagNameArg.text;
59
+ }
60
+ }
61
+ });
62
+ return tagName;
63
+ };
64
+ /**
65
+ * Adds name, description, and summary info for a given jsdoc tag into the
66
+ * provided map.
67
+ */
68
+ const addNamedJSDocInfoToMap = (map, tag, analyzer) => {
69
+ const info = parseNamedTypedJSDocInfo(tag, analyzer);
70
+ if (info !== undefined) {
71
+ map.set(info.name, info);
72
+ }
73
+ };
74
+ /**
75
+ * Parses element metadata from jsDoc tags from a LitElement declaration into
76
+ * Maps of <name, info>.
77
+ */
78
+ export const getJSDocData = (node, analyzer) => {
79
+ const events = new Map();
80
+ const slots = new Map();
81
+ const cssProperties = new Map();
82
+ const cssParts = new Map();
83
+ const jsDocTags = analyzer.typescript.getJSDocTags(node);
84
+ if (jsDocTags !== undefined) {
85
+ for (const tag of jsDocTags) {
86
+ switch (tag.tagName.text) {
87
+ case 'fires':
88
+ addEventsToMap(tag, events, analyzer);
89
+ break;
90
+ case 'slot':
91
+ addNamedJSDocInfoToMap(slots, tag, analyzer);
92
+ break;
93
+ case 'cssProp':
94
+ case 'cssprop':
95
+ case 'cssProperty':
96
+ case 'cssproperty':
97
+ addNamedJSDocInfoToMap(cssProperties, tag, analyzer);
98
+ break;
99
+ case 'cssPart':
100
+ case 'csspart':
101
+ addNamedJSDocInfoToMap(cssParts, tag, analyzer);
102
+ break;
103
+ }
104
+ }
105
+ }
106
+ return {
107
+ ...parseNodeJSDocInfo(node, analyzer),
108
+ events,
109
+ slots,
110
+ cssProperties,
111
+ cssParts,
112
+ };
113
+ };
114
+ export const getCustomElementDeclaration = (node, analyzer, isMixinClass) => {
115
+ return new CustomElementDeclaration({
116
+ tagname: getTagName(node, analyzer),
117
+ name: node.name?.text ?? '',
118
+ node,
119
+ ...getJSDocData(node, analyzer),
120
+ getHeritage: () => getHeritage(node, analyzer, isMixinClass),
121
+ ...getClassMembers(node, analyzer),
122
+ });
123
+ };
124
+ //# sourceMappingURL=custom-elements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-elements.js","sourceRoot":"","sources":["../../src/lib/custom-elements/custom-elements.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 native custom elements (i.e. `HTMLElement`)\n * subclasses.\n */\n\nimport type ts from 'typescript';\nimport {getClassMembers, getHeritage} from '../javascript/classes.js';\nimport {\n AnalyzerInterface,\n CustomElementDeclaration,\n Event,\n NamedDescribed,\n} from '../model.js';\nimport {addEventsToMap} from './events.js';\nimport {\n parseNodeJSDocInfo,\n parseNamedTypedJSDocInfo,\n} from '../javascript/jsdoc.js';\nimport {getBaseTypes} from '../utils.js';\n\nconst _isCustomElementClassDeclaration = (\n t: ts.BaseType,\n analyzer: AnalyzerInterface\n): boolean => {\n const declarations = t.getSymbol()?.getDeclarations();\n return (\n declarations?.some(\n (declaration) =>\n (analyzer.typescript.isInterfaceDeclaration(declaration) &&\n declaration.name?.text === 'HTMLElement') ||\n isCustomElementSubclass(declaration, analyzer)\n ) === true\n );\n};\n\nexport type CustomElementClassDeclaration = ts.ClassDeclaration & {\n _customElementBrand: never;\n};\n\nexport const isCustomElementSubclass = (\n node: ts.Node,\n analyzer: AnalyzerInterface\n): node is CustomElementClassDeclaration => {\n if (!analyzer.typescript.isClassLike(node)) {\n return false;\n }\n if (getTagName(node, analyzer) !== undefined) {\n return true;\n }\n const checker = analyzer.program.getTypeChecker();\n const type = checker.getTypeAtLocation(node);\n const baseTypes = getBaseTypes(type);\n\n for (const t of baseTypes) {\n if (_isCustomElementClassDeclaration(t, analyzer)) {\n return true;\n }\n }\n return false;\n};\n\nexport const getTagName = (\n node: ts.ClassDeclaration | ts.ClassExpression,\n analyzer: AnalyzerInterface\n): string | undefined => {\n const jsdocTag = analyzer.typescript\n .getJSDocTags(node)\n .find((tag) => tag.tagName.text.toLowerCase() === 'customelement');\n\n if (jsdocTag && typeof jsdocTag.comment === 'string') {\n return jsdocTag.comment.trim();\n }\n\n let tagName: string | undefined = undefined;\n\n // Otherwise, look for imperative define in the form of:\n // `customElements.define('x-foo', XFoo);`\n node.parent.forEachChild((child) => {\n if (\n analyzer.typescript.isExpressionStatement(child) &&\n analyzer.typescript.isCallExpression(child.expression) &&\n analyzer.typescript.isPropertyAccessExpression(\n child.expression.expression\n ) &&\n child.expression.arguments.length >= 2\n ) {\n const [tagNameArg, ctorArg] = child.expression.arguments;\n const {expression, name} = child.expression.expression;\n if (\n analyzer.typescript.isIdentifier(expression) &&\n expression.text === 'customElements' &&\n analyzer.typescript.isIdentifier(name) &&\n name.text === 'define' &&\n analyzer.typescript.isStringLiteralLike(tagNameArg) &&\n analyzer.typescript.isIdentifier(ctorArg) &&\n ctorArg.text === node.name?.text\n ) {\n tagName = tagNameArg.text;\n }\n }\n });\n\n return tagName;\n};\n\n/**\n * Adds name, description, and summary info for a given jsdoc tag into the\n * provided map.\n */\nconst addNamedJSDocInfoToMap = (\n map: Map<string, NamedDescribed>,\n tag: ts.JSDocTag,\n analyzer: AnalyzerInterface\n) => {\n const info = parseNamedTypedJSDocInfo(tag, analyzer);\n if (info !== undefined) {\n map.set(info.name, info);\n }\n};\n\n/**\n * Parses element metadata from jsDoc tags from a LitElement declaration into\n * Maps of <name, info>.\n */\nexport const getJSDocData = (\n node: ts.ClassDeclaration,\n analyzer: AnalyzerInterface\n) => {\n const events = new Map<string, Event>();\n const slots = new Map<string, NamedDescribed>();\n const cssProperties = new Map<string, NamedDescribed>();\n const cssParts = new Map<string, NamedDescribed>();\n const jsDocTags = analyzer.typescript.getJSDocTags(node);\n if (jsDocTags !== undefined) {\n for (const tag of jsDocTags) {\n switch (tag.tagName.text) {\n case 'fires':\n addEventsToMap(tag, events, analyzer);\n break;\n case 'slot':\n addNamedJSDocInfoToMap(slots, tag, analyzer);\n break;\n case 'cssProp':\n case 'cssprop':\n case 'cssProperty':\n case 'cssproperty':\n addNamedJSDocInfoToMap(cssProperties, tag, analyzer);\n break;\n case 'cssPart':\n case 'csspart':\n addNamedJSDocInfoToMap(cssParts, tag, analyzer);\n break;\n }\n }\n }\n return {\n ...parseNodeJSDocInfo(node, analyzer),\n events,\n slots,\n cssProperties,\n cssParts,\n };\n};\n\nexport const getCustomElementDeclaration = (\n node: CustomElementClassDeclaration,\n analyzer: AnalyzerInterface,\n isMixinClass?: boolean\n): CustomElementDeclaration => {\n return new CustomElementDeclaration({\n tagname: getTagName(node, analyzer),\n name: node.name?.text ?? '',\n node,\n ...getJSDocData(node, analyzer),\n getHeritage: () => getHeritage(node, analyzer, isMixinClass),\n ...getClassMembers(node, analyzer),\n });\n};\n"]}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ /**
7
+ * @fileoverview
8
+ *
9
+ * Utilities for analyzing with events
10
+ */
11
+ import ts from 'typescript';
12
+ import { Event } from '../model.js';
13
+ import { AnalyzerInterface } from '../model.js';
14
+ /**
15
+ * Returns an array of analyzer `Event` models for the given
16
+ * ts.ClassDeclaration.
17
+ */
18
+ export declare const addEventsToMap: (tag: ts.JSDocTag, events: Map<string, Event>, analyzer: AnalyzerInterface) => void;
19
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/lib/custom-elements/events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAC;AAClC,OAAO,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAG9C;;;GAGG;AACH,eAAO,MAAM,cAAc,GACzB,KAAK,EAAE,CAAC,QAAQ,EAChB,QAAQ,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,EAC1B,UAAU,iBAAiB,SAa5B,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { parseNamedTypedJSDocInfo } from '../javascript/jsdoc.js';
7
+ import { getTypeForTypeString } from '../types.js';
8
+ /**
9
+ * Returns an array of analyzer `Event` models for the given
10
+ * ts.ClassDeclaration.
11
+ */
12
+ export const addEventsToMap = (tag, events, analyzer) => {
13
+ const info = parseNamedTypedJSDocInfo(tag, analyzer);
14
+ if (info === undefined) {
15
+ return;
16
+ }
17
+ const { name, type, description, summary } = info;
18
+ events.set(name, {
19
+ name,
20
+ type: type ? getTypeForTypeString(type, tag, analyzer) : undefined,
21
+ description,
22
+ summary,
23
+ });
24
+ };
25
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/lib/custom-elements/events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAC,wBAAwB,EAAC,MAAM,wBAAwB,CAAC;AAGhE,OAAO,EAAC,oBAAoB,EAAC,MAAM,aAAa,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,GAAgB,EAChB,MAA0B,EAC1B,QAA2B,EAC3B,EAAE;IACF,MAAM,IAAI,GAAG,wBAAwB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACrD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO;IACT,CAAC;IACD,MAAM,EAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAC,GAAG,IAAI,CAAC;IAChD,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE;QACf,IAAI;QACJ,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;QAClE,WAAW;QACX,OAAO;KACR,CAAC,CAAC;AACL,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 with events\n */\n\nimport ts from 'typescript';\nimport {parseNamedTypedJSDocInfo} from '../javascript/jsdoc.js';\nimport {Event} from '../model.js';\nimport {AnalyzerInterface} from '../model.js';\nimport {getTypeForTypeString} from '../types.js';\n\n/**\n * Returns an array of analyzer `Event` models for the given\n * ts.ClassDeclaration.\n */\nexport const addEventsToMap = (\n tag: ts.JSDocTag,\n events: Map<string, Event>,\n analyzer: AnalyzerInterface\n) => {\n const info = parseNamedTypedJSDocInfo(tag, analyzer);\n if (info === undefined) {\n return;\n }\n const {name, type, description, summary} = info;\n events.set(name, {\n name,\n type: type ? getTypeForTypeString(type, tag, analyzer) : undefined,\n description,\n summary,\n });\n};\n"]}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ export declare const DiagnosticCode: {
7
+ /**
8
+ * This is the default error code and doesn't indicate any specific error.
9
+ *
10
+ * We start numbering from 548000 to avoid collisions with other projects.
11
+ */
12
+ readonly UNKNOWN: 548000;
13
+ /**
14
+ * This code represents a situation where ordinary and otherwise-valid code
15
+ * is not yet supported in the Lit analyzer. We should aim to remove uses of
16
+ * this code.
17
+ */
18
+ readonly UNSUPPORTED: 548001;
19
+ };
20
+ export type DiagnosticCode = (typeof DiagnosticCode)[keyof typeof DiagnosticCode];
21
+ //# sourceMappingURL=diagnostic-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-code.d.ts","sourceRoot":"","sources":["../src/lib/diagnostic-code.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,cAAc;IACzB;;;;OAIG;;IAGH;;;;OAIG;;CAEK,CAAC;AAMX,MAAM,MAAM,cAAc,GACxB,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,OAAO,cAAc,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ export const DiagnosticCode = {
7
+ /**
8
+ * This is the default error code and doesn't indicate any specific error.
9
+ *
10
+ * We start numbering from 548000 to avoid collisions with other projects.
11
+ */
12
+ UNKNOWN: 548000, // The letters L-I-T are on digits 5-4-8 on a phone keypad.
13
+ /**
14
+ * This code represents a situation where ordinary and otherwise-valid code
15
+ * is not yet supported in the Lit analyzer. We should aim to remove uses of
16
+ * this code.
17
+ */
18
+ UNSUPPORTED: 548001,
19
+ };
20
+ //# sourceMappingURL=diagnostic-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-code.js","sourceRoot":"","sources":["../src/lib/diagnostic-code.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B;;;;OAIG;IACH,OAAO,EAAE,MAAM,EAAE,2DAA2D;IAE5E;;;;OAIG;IACH,WAAW,EAAE,MAAM;CACX,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nexport const DiagnosticCode = {\n /**\n * This is the default error code and doesn't indicate any specific error.\n *\n * We start numbering from 548000 to avoid collisions with other projects.\n */\n UNKNOWN: 548000, // The letters L-I-T are on digits 5-4-8 on a phone keypad.\n\n /**\n * This code represents a situation where ordinary and otherwise-valid code\n * is not yet supported in the Lit analyzer. We should aim to remove uses of\n * this code.\n */\n UNSUPPORTED: 548001,\n} as const;\n\n// This lets the `DiagnosticCode` type act as an enum by extracting a union of\n// the value types of the `DiagnosticCode` object's properties.\n//\n// https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums\nexport type DiagnosticCode =\n (typeof DiagnosticCode)[keyof typeof DiagnosticCode];\n"]}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import type ts from 'typescript';
7
+ import { DiagnosticCode } from './diagnostic-code.js';
8
+ export type TypeScript = typeof ts;
9
+ export interface DiagnosticOptions {
10
+ typescript: TypeScript;
11
+ node: ts.Node;
12
+ message: string;
13
+ category?: ts.DiagnosticCategory;
14
+ code?: DiagnosticCode | undefined;
15
+ }
16
+ export declare const createDiagnostic: ({ typescript, node, message, category, code, }: DiagnosticOptions) => {
17
+ file: ts.SourceFile;
18
+ start: number;
19
+ length: number;
20
+ category: ts.DiagnosticCategory;
21
+ code: DiagnosticCode;
22
+ messageText: string;
23
+ };
24
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/lib/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAEpD,MAAM,MAAM,UAAU,GAAG,OAAO,EAAE,CAAC;AAEnC,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC;IACjC,IAAI,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CACnC;AAED,eAAO,MAAM,gBAAgB,GAAI,gDAM9B,iBAAiB;;;;;;;CASnB,CAAC"}
package/lib/errors.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { DiagnosticCode } from './diagnostic-code.js';
7
+ export const createDiagnostic = ({ typescript, node, message, category, code, }) => {
8
+ return {
9
+ file: node.getSourceFile(),
10
+ start: node.getStart(),
11
+ length: node.getWidth(),
12
+ category: category ?? typescript.DiagnosticCategory.Error,
13
+ code: code ?? DiagnosticCode.UNKNOWN,
14
+ messageText: message ?? '',
15
+ };
16
+ };
17
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/lib/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAYpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAC/B,UAAU,EACV,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,IAAI,GACc,EAAE,EAAE;IACtB,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE;QAC1B,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE;QACtB,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE;QACvB,QAAQ,EAAE,QAAQ,IAAI,UAAU,CAAC,kBAAkB,CAAC,KAAK;QACzD,IAAI,EAAE,IAAI,IAAI,cAAc,CAAC,OAAO;QACpC,WAAW,EAAE,OAAO,IAAI,EAAE;KAC3B,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport type ts from 'typescript';\nimport {DiagnosticCode} from './diagnostic-code.js';\n\nexport type TypeScript = typeof ts;\n\nexport interface DiagnosticOptions {\n typescript: TypeScript;\n node: ts.Node;\n message: string;\n category?: ts.DiagnosticCategory;\n code?: DiagnosticCode | undefined;\n}\n\nexport const createDiagnostic = ({\n typescript,\n node,\n message,\n category,\n code,\n}: DiagnosticOptions) => {\n return {\n file: node.getSourceFile(),\n start: node.getStart(),\n length: node.getWidth(),\n category: category ?? typescript.DiagnosticCategory.Error,\n code: code ?? DiagnosticCode.UNKNOWN,\n messageText: message ?? '',\n };\n};\n"]}