From 5b59d496893457a4615e835dcfd9aee140379fab Mon Sep 17 00:00:00 2001 From: Mauricio Araldi Date: Fri, 24 Jan 2025 11:47:15 +0100 Subject: [PATCH 1/3] feat(litelement-static-property-obj): added member discovery for this format. added tests for this format --- package-lock.json | 44 ++++++++++------ package.json | 4 +- .../flavors/lit-element/discover-members.ts | 22 +++++--- test/flavors/lit-element/member-test.ts | 50 +++++++++++++++++++ 4 files changed, 95 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index d6c1563f..8da29487 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "web-component-analyzer", - "version": "2.0.0-next.5", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "web-component-analyzer", - "version": "2.0.0-next.5", + "version": "2.0.0", "license": "MIT", "dependencies": { "fast-glob": "^3.2.2", "ts-simple-type": "2.0.0-next.0", - "typescript": "~5.2.0", + "typescript": "~5.7.3", "yargs": "^17.7.2" }, "bin": { @@ -21,7 +21,7 @@ "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.3", - "@rollup/plugin-typescript": "^11.1.5", + "@rollup/plugin-typescript": "^12.1.2", "@types/node": "^18.0.13", "@types/yargs": "^17.0.28", "@typescript-eslint/eslint-plugin": "^6.7.5", @@ -30,7 +30,7 @@ "cross-env": "^7.0.2", "eslint": "^8.51.0", "eslint-config-prettier": "^9.0.0", - "husky": "^8.0.3", + "husky": "^8.0.0", "lint-staged": "^14.0.1", "prettier": "^3.0.3", "rimraf": "^3.0.2", @@ -385,12 +385,12 @@ } }, "node_modules/@rollup/plugin-typescript": { - "version": "11.1.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz", - "integrity": "sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==", + "version": "12.1.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.2.tgz", + "integrity": "sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^5.0.1", + "@rollup/pluginutils": "^5.1.0", "resolve": "^1.22.1" }, "engines": { @@ -411,14 +411,14 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz", - "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" + "picomatch": "^4.0.2" }, "engines": { "node": ">=14.0.0" @@ -432,6 +432,18 @@ } } }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.0.2.tgz", @@ -5188,9 +5200,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index fab85b93..c3e22c46 100644 --- a/package.json +++ b/package.json @@ -52,13 +52,13 @@ "dependencies": { "fast-glob": "^3.2.2", "ts-simple-type": "2.0.0-next.0", - "typescript": "~5.2.0", + "typescript": "~5.7.3", "yargs": "^17.7.2" }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.3", - "@rollup/plugin-typescript": "^11.1.5", + "@rollup/plugin-typescript": "^12.1.2", "@types/node": "^18.0.13", "@types/yargs": "^17.0.28", "@typescript-eslint/eslint-plugin": "^6.7.5", diff --git a/src/analyze/flavors/lit-element/discover-members.ts b/src/analyze/flavors/lit-element/discover-members.ts index bb9ad642..15542e42 100644 --- a/src/analyze/flavors/lit-element/discover-members.ts +++ b/src/analyze/flavors/lit-element/discover-members.ts @@ -1,4 +1,4 @@ -import { GetAccessorDeclaration, Node, PropertyDeclaration, PropertySignature, ReturnStatement, SetAccessorDeclaration } from "typescript"; +import { Expression, GetAccessorDeclaration, Node, PropertyDeclaration, PropertySignature, ReturnStatement, SetAccessorDeclaration } from "typescript"; import { ComponentMember } from "../../types/features/component-member"; import { LitElementPropertyConfig } from "../../types/features/lit-element-property-config"; import { getMemberVisibilityFromNode, getModifiersFromNode, getNodeSourceFileLang, hasModifier } from "../../util/ast-util"; @@ -23,13 +23,21 @@ export function discoverMembers(node: Node, context: AnalyzerDeclarationVisitCon return undefined; } + // static properties = { myProp: {type: String} } + if (ts.isPropertyDeclaration(node) && hasModifier(node, ts.SyntaxKind.StaticKeyword, ts)) { + const name = node.name.getText(); + if (name === "properties" && node.initializer != null) { + return parseStaticProperties(node.initializer, context); + } + } + // static get properties() { return { myProp: {type: String} } } if (ts.isGetAccessor(node) && hasModifier(node, ts.SyntaxKind.StaticKeyword, ts)) { const name = node.name.getText(); if (name === "properties" && node.body != null) { const returnStatement = node.body.statements.find(ts.isReturnStatement.bind(ts)); - if (returnStatement != null) { - return parseStaticProperties(returnStatement, context); + if (returnStatement != null && returnStatement.expression != null) { + return parseStaticProperties(returnStatement.expression, context); } } } @@ -155,17 +163,17 @@ function getLitAttributeName(propName: string, litConfig: LitElementPropertyConf /** * Visits static properties * static get properties() { return { myProp: {type: String, attribute: "my-attr"} } } - * @param returnStatement + * @param expression * @param context */ -function parseStaticProperties(returnStatement: ReturnStatement, context: AnalyzerDeclarationVisitContext): ComponentMember[] { +function parseStaticProperties(expression: Expression, context: AnalyzerDeclarationVisitContext): ComponentMember[] { const { ts } = context; const memberResults: ComponentMember[] = []; - if (returnStatement.expression != null && ts.isObjectLiteralExpression(returnStatement.expression)) { + if (expression != null && ts.isObjectLiteralExpression(expression)) { // Each property in the object literal expression corresponds to a class field. - for (const propNode of returnStatement.expression.properties) { + for (const propNode of expression.properties) { // Get propName const propName = propNode.name != null && ts.isIdentifier(propNode.name) ? propNode.name.text : undefined; if (propName == null) { diff --git a/test/flavors/lit-element/member-test.ts b/test/flavors/lit-element/member-test.ts index 989c1e01..aeaa1060 100644 --- a/test/flavors/lit-element/member-test.ts +++ b/test/flavors/lit-element/member-test.ts @@ -50,6 +50,56 @@ tsTest("LitElement: Discovers properties from 'static get properties'", t => { ); }); +tsTest("LitElement: Discovers properties from 'static properties = {}'", t => { + const { + results: [result], + checker + } = analyzeTextWithCurrentTsModule(` + /** + * @element + */ + class MyElement extends HTMLElement { + static properties = { + /** + * This is a comment + * @default hello 123 + * @type {String} + */ + myProp: {type: String} + } + } + `); + + const { members = [] } = result.componentDefinitions[0]?.declaration || {}; + + assertHasMembers( + members, + [ + { + kind: "property", + propName: "myProp", + attrName: "myProp", + jsDoc: { + description: "This is a comment" + }, + default: "hello 123", + typeHint: "String", + type: () => ({ kind: "STRING" }), + visibility: undefined, + reflect: "to-property", + deprecated: undefined, + required: undefined + }, + { + kind: "property", + propName: "properties", + } + ], + t, + checker + ); +}); + tsTest("LitElement: Discovers properties from '@property'", t => { const { results: [result], From 83e66d0574655c459098cacfac1ea868c0921e5c Mon Sep 17 00:00:00 2001 From: Mauricio Araldi Date: Fri, 24 Jan 2025 11:47:27 +0100 Subject: [PATCH 2/3] feat(litelement-static-property-obj): added member discovery for this format. added tests for this format --- src/analyze/flavors/lit-element/discover-members.ts | 10 +++++++++- test/flavors/lit-element/member-test.ts | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/analyze/flavors/lit-element/discover-members.ts b/src/analyze/flavors/lit-element/discover-members.ts index 15542e42..ccd79670 100644 --- a/src/analyze/flavors/lit-element/discover-members.ts +++ b/src/analyze/flavors/lit-element/discover-members.ts @@ -1,4 +1,12 @@ -import { Expression, GetAccessorDeclaration, Node, PropertyDeclaration, PropertySignature, ReturnStatement, SetAccessorDeclaration } from "typescript"; +import { + Expression, + GetAccessorDeclaration, + Node, + PropertyDeclaration, + PropertySignature, + ReturnStatement, + SetAccessorDeclaration +} from "typescript"; import { ComponentMember } from "../../types/features/component-member"; import { LitElementPropertyConfig } from "../../types/features/lit-element-property-config"; import { getMemberVisibilityFromNode, getModifiersFromNode, getNodeSourceFileLang, hasModifier } from "../../util/ast-util"; diff --git a/test/flavors/lit-element/member-test.ts b/test/flavors/lit-element/member-test.ts index aeaa1060..ef78b466 100644 --- a/test/flavors/lit-element/member-test.ts +++ b/test/flavors/lit-element/member-test.ts @@ -92,7 +92,7 @@ tsTest("LitElement: Discovers properties from 'static properties = {}'", t => { }, { kind: "property", - propName: "properties", + propName: "properties" } ], t, From 67e32406855eabaa9f5caebe81f211e257eb7cf5 Mon Sep 17 00:00:00 2001 From: Mauricio Araldi Date: Fri, 24 Jan 2025 11:49:12 +0100 Subject: [PATCH 3/3] feat(litelement-static-property-obj): removed test changes --- package-lock.json | 38 +++++++++++++------------------------- package.json | 4 ++-- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8da29487..494915d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "fast-glob": "^3.2.2", "ts-simple-type": "2.0.0-next.0", - "typescript": "~5.7.3", + "typescript": "~5.2.0", "yargs": "^17.7.2" }, "bin": { @@ -21,7 +21,7 @@ "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.3", - "@rollup/plugin-typescript": "^12.1.2", + "@rollup/plugin-typescript": "^11.1.5", "@types/node": "^18.0.13", "@types/yargs": "^17.0.28", "@typescript-eslint/eslint-plugin": "^6.7.5", @@ -385,12 +385,12 @@ } }, "node_modules/@rollup/plugin-typescript": { - "version": "12.1.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.2.tgz", - "integrity": "sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg==", + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz", + "integrity": "sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^5.1.0", + "@rollup/pluginutils": "^5.0.1", "resolve": "^1.22.1" }, "engines": { @@ -411,14 +411,14 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", - "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz", + "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==", "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" + "picomatch": "^2.3.1" }, "engines": { "node": ">=14.0.0" @@ -432,18 +432,6 @@ } } }, - "node_modules/@rollup/pluginutils/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.0.2.tgz", @@ -5200,9 +5188,9 @@ } }, "node_modules/typescript": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", - "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index c3e22c46..fab85b93 100644 --- a/package.json +++ b/package.json @@ -52,13 +52,13 @@ "dependencies": { "fast-glob": "^3.2.2", "ts-simple-type": "2.0.0-next.0", - "typescript": "~5.7.3", + "typescript": "~5.2.0", "yargs": "^17.7.2" }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.3", - "@rollup/plugin-typescript": "^12.1.2", + "@rollup/plugin-typescript": "^11.1.5", "@types/node": "^18.0.13", "@types/yargs": "^17.0.28", "@typescript-eslint/eslint-plugin": "^6.7.5",