From 4d95d77f0ac12eb1a4f42fb5546a475c7fa8e182 Mon Sep 17 00:00:00 2001 From: runem Date: Thu, 20 Feb 2020 10:22:34 +0100 Subject: [PATCH] Setup no-incompatible-property-type and remove no-unknown-property-converter --- README.md | 73 +- dev/src/my-element-1.ts | 8 +- docs/readme/rules.md | 42 +- packages/lit-analyzer/README.md | 1262 +++++++-------- .../analyze/default-lit-analyzer-context.ts | 4 +- .../html/lit-html-document-analyzer.ts | 3 +- .../src/analyze/lit-analyzer-config.ts | 7 - .../lit-analyzer/src/analyze/lit-analyzer.ts | 2 +- .../parse-documents-in-source-file.ts | 3 +- .../src/analyze/types/lit-diagnostic.ts | 14 +- .../src/analyze/util/array-util.ts | 17 + .../src/analyze/util/general-util.ts | 8 - .../lit-analyzer/src/cli/analyze-globs.ts | 2 +- packages/lit-analyzer/src/cli/cli.ts | 1 - .../rules/no-incompatible-property-type.ts | 235 +++ .../src/rules/no-invalid-attribute-name.ts | 50 +- .../src/rules/no-invalid-property.ts | 215 +-- .../src/rules/no-invalid-tag-name.ts | 3 +- packages/ts-lit-plugin/README.md | 83 +- packages/vscode-lit-plugin/README.md | 1414 +++++++++-------- packages/vscode-lit-plugin/package.json | 11 - .../schemas/tsconfig.schema.json | 5 - 22 files changed, 1862 insertions(+), 1600 deletions(-) create mode 100644 packages/lit-analyzer/src/analyze/util/array-util.ts create mode 100644 packages/lit-analyzer/src/rules/no-incompatible-property-type.ts diff --git a/README.md b/README.md index d43676d5..34e5e88e 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,55 @@ -

lit-analyzer

-

- Monorepo for tools that analyze lit-html templates
- -

- -
- -

+

lit-analyzer

+

+ Monorepo for tools that analyze lit-html templates
+ +

+ +
+ + +

Downloads per Month Downloads per Month Downloads per Month -Contributors -

- -This mono-repository consists of the following tools: - -- [**`vscode-lit-plugin`**](/packages/vscode-lit-plugin) VS Code plugin that adds syntax highlighting, type checking and code completion for lit-html. - -- [**`ts-lit-plugin`**](/packages/ts-lit-plugin) Typescript plugin that adds type checking and code completion to lit-html templates. - -- [**`lit-analyzer`**](/packages/lit-analyzer) CLI that analyzes lit-html templates in your code to validate html and type check bindings. +Contributors +

+ + +This mono-repository consists of the following tools: + +- [**`vscode-lit-plugin`**](/packages/vscode-lit-plugin) VS Code plugin that adds syntax highlighting, type checking and code completion for lit-html. + +- [**`ts-lit-plugin`**](/packages/ts-lit-plugin) Typescript plugin that adds type checking and code completion to lit-html templates. + +- [**`lit-analyzer`**](/packages/lit-analyzer) CLI that analyzes lit-html templates in your code to validate html and type check bindings. + [![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#rules) -## ➤ Rules - -You can find a list of all rules [here](https://github.com/runem/lit-analyzer/blob/master/docs/readme/rules.md). +## ➤ Rules + +You can find a list of all rules [here](https://github.com/runem/lit-analyzer/blob/master/docs/readme/rules.md). + [![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#contributing) -## ➤ Contributing - -If you are interested in contributing to this repository please read [`contributing.md`](/CONTRIBUTING.md) +## ➤ Contributing + +If you are interested in contributing to this repository please read [`contributing.md`](/CONTRIBUTING.md) + [![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#contributors) -## ➤ Contributors - -| [Rune Mehlsen](https://twitter.com/runemehlsen) | [Andreas Mehlsen](https://twitter.com/andreasmehlsen) | [Peter Burns](https://twitter.com/rictic) | [You?](https://github.com/runem/lit-analyzer/blob/master/CONTRIBUTING.md) | -| :--------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | -| [Rune Mehlsen](https://twitter.com/runemehlsen) | [Andreas Mehlsen](https://twitter.com/andreasmehlsen) | [Peter Burns](https://twitter.com/rictic) | [You?](https://github.com/runem/lit-analyzer/blob/master/CONTRIBUTING.md) | +## ➤ Contributors + + +| [Rune Mehlsen](https://twitter.com/runemehlsen) | [Andreas Mehlsen](https://twitter.com/andreasmehlsen) | [Peter Burns](https://twitter.com/rictic) | [You?](https://github.com/runem/lit-analyzer/blob/master/CONTRIBUTING.md) | +|:--------------------------------------------------:|:--------------------------------------------------:|:--------------------------------------------------:|:--------------------------------------------------:| +| [Rune Mehlsen](https://twitter.com/runemehlsen) | [Andreas Mehlsen](https://twitter.com/andreasmehlsen) | [Peter Burns](https://twitter.com/rictic) | [You?](https://github.com/runem/lit-analyzer/blob/master/CONTRIBUTING.md) | + [![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#license) -## ➤ License - -Licensed under [MIT](https://opensource.org/licenses/MIT). +## ➤ License + +Licensed under [MIT](https://opensource.org/licenses/MIT). diff --git a/dev/src/my-element-1.ts b/dev/src/my-element-1.ts index 4c8c9a46..4cb5f680 100644 --- a/dev/src/my-element-1.ts +++ b/dev/src/my-element-1.ts @@ -3,12 +3,16 @@ import "./my-element-2"; @customElement("my-element") export class MyElement extends LitElement { - @property({ attribute: "hello" }) test: number | undefined; + @property({ attribute: "hell>o" }) test: number | undefined; - @property({ type: String }) test2: number | undefined; + @property({ type: Date }) test2: number | undefined; @internalProperty() internal: number | undefined; + static get observedAttributes() { + return ["this is a test", "testing"]; + } + render() { return html` diff --git a/docs/readme/rules.md b/docs/readme/rules.md index aab3ef3b..11a76803 100644 --- a/docs/readme/rules.md +++ b/docs/readme/rules.md @@ -43,7 +43,6 @@ Each rule can have severity of `off`, `warning` or `error`. You can toggle rules | Rule | Description | Severity normal | Severity strict | | :------ | ----------- | --------------- | --------------- | | [no-incompatible-property-type](#-no-incompatible-property-type) | When using the @property decorator in Typescript, the property option `type` is checked against the declared property Typescript type | error | error | -| [no-unknown-property-converter](#-no-unknown-property-converter) | LitElement provides default converters. For example 'Function' is not a valid default converter type for a LitElement-managed property. | error | error | | [no-invalid-attribute-name](#-no-invalid-attribute-name) | When using the property option `attribute`, the value is checked to make sure it's a valid attribute name. | error | error | | [no-invalid-tag-name](#-no-invalid-tag-name) | When defining a custom element the tag name is checked to make sure it's valid. | error | error | @@ -398,7 +397,15 @@ html`` #### 💞 no-incompatible-property-type -When using the @property decorator in Typescript, the property option `type` is checked against the declared property Typescript type. +This rule checks that LitElement-controlled properties are correctly configured in accordance with the default value converter. + +The following is a summary of what this rule does: + +1. The `type` given to the LitElement property configuration is checked against the actual Typescript type of the property. +2. The default converter only accepts the types `String`, `Boolean`, `Number`, `Array` and `Object`, so all other values for `type` are considered warnings. +3. The absence of a `type` is only considered a warning if the property is not assignable to the `string` type. + +This rule will not check for a given LitElement-controlled property if the property has custom converter configured. The following examples are considered warnings: @@ -409,30 +416,7 @@ class MyElement extends LitElement { @property({type: Boolean}) count: number; @property({type: String}) disabled: boolean; @property({type: Object}) list: ListItem[]; -} -``` - -The following examples are not considered warnings: - - -```js -class MyElement extends LitElement { - @property({type: String}) text: string; - @property({type: Number}) count: number; - @property({type: Boolean}) disabled: boolean; - @property({type: Array}) list: ListItem[]; -} -``` - -#### 👎 no-unknown-property-converter - -The default converter in LitElement only accepts `String`, `Boolean`, `Number`, `Array` and `Object`, so all other values for `type` are considered warnings. This check doesn't run if a custom converter is used. - -The following example is considered a warning: - -```js -class MyElement extends LitElement { static get properties () { return { callback: { @@ -446,11 +430,16 @@ class MyElement extends LitElement { } ``` -The following example is not considered a warning: +The following examples are not considered warnings: ```js class MyElement extends LitElement { + @property({type: String}) text: string; + @property({type: Number}) count: number; + @property({type: Boolean}) disabled: boolean; + @property({type: Array}) list: ListItem[]; + static get properties () { return { callback: { @@ -462,6 +451,7 @@ class MyElement extends LitElement { } } } + } ``` diff --git a/packages/lit-analyzer/README.md b/packages/lit-analyzer/README.md index a7961be0..266a9325 100644 --- a/packages/lit-analyzer/README.md +++ b/packages/lit-analyzer/README.md @@ -1,654 +1,656 @@ -

lit-analyzer

-

- CLI that type checks bindings in lit-html templates
- -

- -
- -

+

lit-analyzer

+

+ CLI that type checks bindings in lit-html templates
+ +

+ +
+ +

Downloads per month NPM Version Dependencies -Contributors -

+Contributors +

+ + + + [![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#installation) -## ➤ Installation - - -```bash -npm install lit-analyzer -g -``` - -**Note:** - -- If you use Visual Studio Code you can also install the [lit-plugin](https://marketplace.visualstudio.com/items?itemName=runem.lit-plugin) extension. -- If you use Typescript you can also install [ts-lit-plugin](https://github.com/runem/lit-analyzer/blob/master/packages/ts-lit-plugin). +## ➤ Installation + + +```bash +npm install lit-analyzer -g +``` + +**Note:** + +- If you use Visual Studio Code you can also install the [lit-plugin](https://marketplace.visualstudio.com/items?itemName=runem.lit-plugin) extension. +- If you use Typescript you can also install [ts-lit-plugin](https://github.com/runem/lit-analyzer/blob/master/packages/ts-lit-plugin). + [![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#usage) -## ➤ Usage - -`lit-analyzer` analyzes an optional `input glob` and emits the output to the console as default. When the `input glob` is omitted it will analyze all components in `src`. - - -```bash -lit-analyzer src -lit-analyzer "src/**/*.{js,ts}" -lit-analyzer my-element.js -lit-analyzer --format markdown --outFile result.md -``` +## ➤ Usage + +`lit-analyzer` analyzes an optional `input glob` and emits the output to the console as default. When the `input glob` is omitted it will analyze all components in `src`. + + +```bash +lit-analyzer src +lit-analyzer "src/**/*.{js,ts}" +lit-analyzer my-element.js +lit-analyzer --format markdown --outFile result.md +``` + [![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#configuration) -## ➤ Configuration - -You can configure the CLI with arguments: - - -```bash -lit-analyzer --strict --rules.no-unknown-tag-name off --format markdown -``` - -**Note:** You can also configure the CLI using a `tsconfig.json` file (see [ts-lit-plugin](https://github.com/runem/lit-analyzer/blob/master/packages/ts-lit-plugin)). - -### Available arguments - - -| Option | Description | Type | Default | -| :----- | ----------- | ---- | ------- | -| `--help` | Print help message | `boolean` | | -| `--rules.rule-name` | Enable or disable rules (example: --rules.no-unknown-tag-name off). Severity can be "off" \| "warn" \| "error". See a list of rules [here](https://github.com/runem/lit-analyzer/blob/master/docs/readme/rules.md). | `{"rule-name": "off" \| "warn" \| "error"}` | | -| `--strict` | Enable strict mode. This changes the default ruleset | `boolean` | | -| `--format` | Change the format of how diagnostics are reported | `code` \| `list` \| `markdown` | code | -| `--maxWarnings` | Fail only when the number of warnings is larger than this number | `number` | -1 | -| `--outFile` | Emit all output to a single file | `filePath` | | -| `--quiet` | Report only errors and not warnings | `boolean` | | -| `--failFast` | Exit the process right after the first problem has been found | `boolean` | | -| `--debug` | Enable CLI debug mode | `boolean` | | +## ➤ Configuration + +You can configure the CLI with arguments: + + +```bash +lit-analyzer --strict --rules.no-unknown-tag-name off --format markdown +``` + +**Note:** You can also configure the CLI using a `tsconfig.json` file (see [ts-lit-plugin](https://github.com/runem/lit-analyzer/blob/master/packages/ts-lit-plugin)). + +### Available arguments + + +| Option | Description | Type | Default | +| :----- | ----------- | ---- | ------- | +| `--help` | Print help message | `boolean` | | +| `--rules.rule-name` | Enable or disable rules (example: --rules.no-unknown-tag-name off). Severity can be "off" \| "warn" \| "error". See a list of rules [here](https://github.com/runem/lit-analyzer/blob/master/docs/readme/rules.md). | `{"rule-name": "off" \| "warn" \| "error"}` | | +| `--strict` | Enable strict mode. This changes the default ruleset | `boolean` | | +| `--format` | Change the format of how diagnostics are reported | `code` \| `list` \| `markdown` | code | +| `--maxWarnings` | Fail only when the number of warnings is larger than this number | `number` | -1 | +| `--outFile` | Emit all output to a single file | `filePath` | | +| `--quiet` | Report only errors and not warnings | `boolean` | | +| `--failFast` | Exit the process right after the first problem has been found | `boolean` | | +| `--debug` | Enable CLI debug mode | `boolean` | | + [![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#rules) -## ➤ Rules - -The default severity of each rule depend on the `strict` [configuration option](#-configuration). Strict mode is disabled as default. - -Each rule can have severity of `off`, `warning` or `error`. You can toggle rules as you like. - -**Validating custom elements** - - -| Rule | Description | Severity normal | Severity strict | -| :------ | ----------- | --------------- | --------------- | -| [no-unknown-tag-name](#-no-unknown-tag-name) | The existence of tag names are checked. Be aware that not all custom elements from libraries will be found out of the box. | off | warning | -| [no-missing-import](#-no-missing-import) | When using custom elements in HTML it is checked if the element has been imported and is available in the current context. | off | warning | -| [no-unclosed-tag](#-no-unclosed-tag) | Unclosed tags, and invalid self closing tags like custom elements tags, are checked. | warning | error | - -**Validating binding names** - - -| Rule | Description | Severity normal | Severity strict | -| :------ | ----------- | --------------- | --------------- | -| [no-unknown-attribute](#-no-unknown-attribute-no-unknown-property)
[no-unknown-property](#-no-unknown-attribute-no-unknown-property) | You will get a warning whenever you use an unknown attribute or property within your `lit-html` template. | off | warning | -| [no-unknown-event](#-no-unknown-event) | When using event bindings it's checked that the event names are fired. | off | off | -| [no-unknown-slot](#-no-unknown-slot) | Using the "@slot" jsdoc tag on your custom element class, you can tell which slots are accepted for a particular element. | off | warning | - -**Validating binding types** - - -| Rule | Description | Severity normal | Severity strict | -| :------ | ----------- | --------------- | --------------- | -| [no-invalid-boolean-binding](#-no-invalid-boolean-binding) | Disallow boolean attribute bindings on non-boolean types. | error | error | -| [no-expressionless-property-binding](#-no-expressionless-property-binding) | Disallow property bindings without an expression. | error | error | -| [no-noncallable-event-binding](#-no-noncallable-event-binding) | Disallow event listener bindings with a noncallable type. | error | error | -| [no-boolean-in-attribute-binding](#-no-boolean-in-attribute-binding) | Disallow attribute bindings with a boolean type. | error | error | -| [no-complex-attribute-binding](#-no-complex-attribute-binding) | Disallow attribute bindings with a complex type. | error | error | -| [no-nullable-attribute-binding](#-no-nullable-attribute-binding) | Disallow attribute bindings with nullable types such as "null" or "undefined". | error | error | -| [no-incompatible-type-binding](#-no-incompatible-type-binding) | Disallow incompatible type in bindings. | error | error | -| [no-invalid-directive-binding](#-no-invalid-directive-binding) | Disallow using built-in directives in unsupported bindings. | error | error | -| [no-unintended-mixed-binding](#-no-unintended-mixed-binding) | Disallow mixed value bindings where a character `'`, `"`, `}` or `/` is unintentionally included in the binding. | warn | warn | - -**Validating LitElement** - - -| Rule | Description | Severity normal | Severity strict | -| :------ | ----------- | --------------- | --------------- | -| [no-incompatible-property-type](#-no-incompatible-property-type) | When using the @property decorator in Typescript, the property option `type` is checked against the declared property Typescript type | error | error | -| [no-unknown-property-converter](#-no-unknown-property-converter) | LitElement provides default converters. For example 'Function' is not a valid default converter type for a LitElement-managed property. | error | error | -| [no-invalid-attribute-name](#-no-invalid-attribute-name) | When using the property option `attribute`, the value is checked to make sure it's a valid attribute name. | error | error | -| [no-invalid-tag-name](#-no-invalid-tag-name) | When defining a custom element the tag name is checked to make sure it's valid. | error | error | - -**Validating CSS** - - -| Rule | Description | Severity normal | Severity strict | -| :------ | ----------- | --------------- | --------------- | -| [💅 no-invalid-css](#-no-invalid-css) | CSS within the tagged template literal `css` will be validated. | warning | error | - -### Validating custom elements - -All web components in your code are analyzed using [web-component-analyzer](https://github.com/runem/web-component-analyzer) which supports native custom elements and web components built with LitElement. - -#### 🤷‍ no-unknown-tag-name - -Web components defined in libraries need to either extend the global `HTMLElementTagNameMap` (typescript definition file) or include the "@customElement tag-name" jsdoc on the custom element class. - -Below you will see an example of what to add to your library typescript definition files if you want type checking support for a given html tag name. - - -```typescript -declare global { - interface HTMLElementTagNameMap { - "my-element": MyElement; - } -} -``` - -#### 📣 no-missing-import - -When using custom elements in HTML it is checked if the element has been imported and is available in the current context. It's considered imported if any imported module (or their imports) defines the custom element. - -The following example is considered a warning: - - -```js -// No import of "my-element" -html`` -``` - -The following example is not considered a warning: - - -```js -import "my-element.js"; -html`` -``` - -#### ☯ no-unclosed-tag - -Unclosed tags, and invalid self closing tags like custom elements tags, are checked. - -The following examples are considered warnings: - - -```js -html`
` -html`