diff --git a/.changeset/big-swans-applaud.md b/.changeset/big-swans-applaud.md new file mode 100644 index 00000000..10716834 --- /dev/null +++ b/.changeset/big-swans-applaud.md @@ -0,0 +1,5 @@ +--- +"@jackolope/lit-analyzer": patch +--- + +Update parse5 logic to use the built-in types instead of custom ones diff --git a/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-attr-assignment.ts b/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-attr-assignment.ts index 91b7192f..fe8535a2 100644 --- a/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-attr-assignment.ts +++ b/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-attr-assignment.ts @@ -3,9 +3,8 @@ import type { HtmlNodeAttrAssignment } from "../../../../../types/html-node/html import { HtmlNodeAttrAssignmentKind } from "../../../../../types/html-node/html-node-attr-assignment-types.js"; import type { HtmlNodeAttr } from "../../../../../types/html-node/html-node-attr-types.js"; import type { Range } from "../../../../../types/range.js"; -import type { IP5NodeAttr, IP5TagNode } from "../parse-html-p5/parse-html-types.js"; -import { getSourceLocation } from "../parse-html-p5/parse-html-types.js"; import type { ParseHtmlContext } from "./parse-html-context.js"; +import type { DefaultTreeAdapterTypes, Token } from "parse5"; /** * Parses a html attribute assignment. @@ -15,8 +14,8 @@ import type { ParseHtmlContext } from "./parse-html-context.js"; * @param context */ export function parseHtmlAttrAssignment( - p5Node: IP5TagNode, - p5Attr: IP5NodeAttr, + p5Node: DefaultTreeAdapterTypes.Element, + p5Attr: Token.Attribute, htmlAttr: HtmlNodeAttr, context: ParseHtmlContext ): HtmlNodeAttrAssignment | undefined { @@ -70,13 +69,18 @@ export function parseHtmlAttrAssignment( } } -function getAssignmentLocation(p5Node: IP5TagNode, p5Attr: IP5NodeAttr, htmlAttr: HtmlNodeAttr, context: ParseHtmlContext): Range | undefined { - const sourceLocation = getSourceLocation(p5Node); +function getAssignmentLocation( + p5Node: DefaultTreeAdapterTypes.Element, + p5Attr: Token.Attribute, + htmlAttr: HtmlNodeAttr, + context: ParseHtmlContext +): Range | undefined { + const sourceLocation = p5Node.sourceCodeLocation; if (sourceLocation == null) { return undefined; } - const htmlAttrLocation = (sourceLocation.startTag.attrs || {})[p5Attr.name]; + const htmlAttrLocation = ((sourceLocation.startTag as Token.LocationWithAttributes)?.attrs || {})[p5Attr.name]; if (htmlAttrLocation == null) return undefined; const nameEndOffset = htmlAttr.location.name.end; diff --git a/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-attribute.ts b/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-attribute.ts index 336d19d6..5fb4ef77 100644 --- a/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-attribute.ts +++ b/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-attribute.ts @@ -6,17 +6,16 @@ import { import type { HtmlNodeAttr, IHtmlNodeAttrBase, IHtmlNodeAttrSourceCodeLocation } from "../../../../../types/html-node/html-node-attr-types.js"; import { HtmlNodeAttrKind } from "../../../../../types/html-node/html-node-attr-types.js"; import { parseLitAttrName } from "../../../../../util/general-util.js"; -import type { IP5NodeAttr, IP5TagNode } from "../parse-html-p5/parse-html-types.js"; -import { getSourceLocation } from "../parse-html-p5/parse-html-types.js"; import { parseHtmlAttrAssignment } from "./parse-html-attr-assignment.js"; import type { ParseHtmlAttrContext } from "./parse-html-attr-context.js"; +import type { DefaultTreeAdapterTypes, Token } from "parse5"; /** * Creates multiple html attributes based on multiple p5Attributes. * @param p5Node * @param context */ -export function parseHtmlNodeAttrs(p5Node: IP5TagNode, context: ParseHtmlAttrContext): HtmlNodeAttr[] { +export function parseHtmlNodeAttrs(p5Node: DefaultTreeAdapterTypes.Element, context: ParseHtmlAttrContext): HtmlNodeAttr[] { return p5Node.attrs .map(htmlAttr => parseHtmlNodeAttr(p5Node, htmlAttr, { @@ -33,7 +32,11 @@ export function parseHtmlNodeAttrs(p5Node: IP5TagNode, context: ParseHtmlAttrCon * @param p5Attr * @param context */ -export function parseHtmlNodeAttr(p5Node: IP5TagNode, p5Attr: IP5NodeAttr, context: ParseHtmlAttrContext): HtmlNodeAttr | undefined { +export function parseHtmlNodeAttr( + p5Node: DefaultTreeAdapterTypes.Element, + p5Attr: Token.Attribute, + context: ParseHtmlAttrContext +): HtmlNodeAttr | undefined { const { htmlNode } = context; const { name, modifier } = parseLitAttrName(p5Attr.name); @@ -63,10 +66,14 @@ export function parseHtmlNodeAttr(p5Node: IP5TagNode, p5Attr: IP5NodeAttr, conte * @param p5Attr * @param context */ -function makeHtmlAttrLocation(p5Node: IP5TagNode, p5Attr: IP5NodeAttr, context: ParseHtmlAttrContext): IHtmlNodeAttrSourceCodeLocation | undefined { +function makeHtmlAttrLocation( + p5Node: DefaultTreeAdapterTypes.Element, + p5Attr: Token.Attribute, + context: ParseHtmlAttrContext +): IHtmlNodeAttrSourceCodeLocation | undefined { const { name, modifier } = parseLitAttrName(p5Attr.name); - const sourceLocation = getSourceLocation(p5Node); + const sourceLocation = p5Node.sourceCodeLocation; if (sourceLocation == null) { return undefined; } @@ -75,7 +82,7 @@ function makeHtmlAttrLocation(p5Node: IP5TagNode, p5Attr: IP5NodeAttr, context: // Parse5 lowercases source code location attr keys but doesnt lowercase the attr name when it comes to svg. // It would be correct not to lowercase the attr names because svg is case sensitive const sourceCodeLocationName = `${p5Attr.prefix || ""}${(p5Attr.prefix && ":") || ""}${p5Attr.name}`.toLowerCase(); - const htmlAttrLocation = (sourceLocation.startTag.attrs || {})[sourceCodeLocationName]; + const htmlAttrLocation = ((sourceLocation.startTag as Token.LocationWithAttributes)?.attrs || {})[sourceCodeLocationName]; const start = htmlAttrLocation.startOffset; const end = htmlAttrLocation.endOffset; return { diff --git a/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-node.ts b/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-node.ts index fb44c6e7..485ba695 100644 --- a/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-node.ts +++ b/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-node/parse-html-node.ts @@ -2,8 +2,7 @@ import { TS_IGNORE_FLAG } from "../../../../../constants.js"; import type { HtmlNode, IHtmlNodeBase, IHtmlNodeSourceCodeLocation } from "../../../../../types/html-node/html-node-types.js"; import { HtmlNodeKind } from "../../../../../types/html-node/html-node-types.js"; import { isCommentNode, isTagNode } from "../parse-html-p5/parse-html.js"; -import type { IP5TagNode, P5Node } from "../parse-html-p5/parse-html-types.js"; -import { getSourceLocation } from "../parse-html-p5/parse-html-types.js"; +import type { DefaultTreeAdapterTypes } from "parse5"; import { parseHtmlNodeAttrs } from "./parse-html-attribute.js"; import type { ParseHtmlContext } from "./parse-html-context.js"; @@ -13,7 +12,7 @@ import type { ParseHtmlContext } from "./parse-html-context.js"; * @param parent * @param context */ -export function parseHtmlNodes(p5Nodes: P5Node[], parent: HtmlNode | undefined, context: ParseHtmlContext): HtmlNode[] { +export function parseHtmlNodes(p5Nodes: DefaultTreeAdapterTypes.Node[], parent: HtmlNode | undefined, context: ParseHtmlContext): HtmlNode[] { const htmlNodes: HtmlNode[] = []; let ignoreNextNode = false; for (const p5Node of p5Nodes) { @@ -45,9 +44,13 @@ export function parseHtmlNodes(p5Nodes: P5Node[], parent: HtmlNode | undefined, * @param parent * @param context */ -export function parseHtmlNode(p5Node: IP5TagNode, parent: HtmlNode | undefined, context: ParseHtmlContext): HtmlNode | undefined { +export function parseHtmlNode( + p5Node: DefaultTreeAdapterTypes.Element, + parent: HtmlNode | undefined, + context: ParseHtmlContext +): HtmlNode | undefined { // `sourceCodeLocation` will be undefined if the element was implicitly created by the parser. - if (getSourceLocation(p5Node) == null) return undefined; + if (p5Node.sourceCodeLocation == null) return undefined; const htmlNodeBase: IHtmlNodeBase = { tagName: p5Node.tagName.toLowerCase(), @@ -75,19 +78,19 @@ export function parseHtmlNode(p5Node: IP5TagNode, parent: HtmlNode | undefined, * @param p5Node * @param context */ -function makeHtmlNodeLocation(p5Node: IP5TagNode, context: ParseHtmlContext): IHtmlNodeSourceCodeLocation { - const loc = getSourceLocation(p5Node)!; +function makeHtmlNodeLocation(p5Node: DefaultTreeAdapterTypes.Element, context: ParseHtmlContext): IHtmlNodeSourceCodeLocation { + const loc = p5Node.sourceCodeLocation!; return { start: loc.startOffset, end: loc.endOffset, name: { - start: loc.startTag.startOffset + 1, // take '<' into account - end: loc.startTag.startOffset + 1 + p5Node.tagName.length + start: loc.startTag!.startOffset + 1, // take '<' into account + end: loc.startTag!.startOffset + 1 + p5Node.tagName.length }, startTag: { - start: loc.startTag.startOffset, - end: loc.startTag.endOffset + start: loc.startTag!.startOffset, + end: loc.startTag!.endOffset }, endTag: loc.endTag == null diff --git a/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-p5/parse-html-types.ts b/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-p5/parse-html-types.ts deleted file mode 100644 index f64ada19..00000000 --- a/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-p5/parse-html-types.ts +++ /dev/null @@ -1,65 +0,0 @@ -export interface IP5BaseSourceCodeLocation { - startLine: number; - startCol: number; - startOffset: number; - endLine: number; - endCol: number; - endOffset: number; - attrs?: Record; -} - -export interface IP5NodeAttr { - name: string; - value: string; - prefix?: string; -} - -export interface IP5NodeBase { - nodeName: string; - namespaceURI: string; -} - -export interface IP5DocumentFragmentNode extends IP5NodeBase { - nodeName: "#document-fragment"; - childNodes: P5Node[]; -} - -export interface IP5TextNode extends IP5NodeBase { - nodeName: "#text"; - value: string; - parentNode: P5Node; -} - -export interface IP5CommentNode extends IP5NodeBase { - nodeName: "#comment"; - value: string; - data?: string; - parentNode: P5Node; -} - -export interface IP5TagNode extends IP5NodeBase { - nodeName: string; - tagName: string; - attrs: IP5NodeAttr[]; - namespaceURI: string; - childNodes?: []; - parentNodes: P5Node; -} - -export interface IP5NodeSourceLocation extends IP5BaseSourceCodeLocation { - startTag: IP5BaseSourceCodeLocation; - endTag?: IP5BaseSourceCodeLocation; -} - -export type P5Node = IP5TextNode | IP5TagNode | IP5CommentNode; - -export function getSourceLocation(node: IP5TagNode): IP5NodeSourceLocation | null; -export function getSourceLocation(node: P5Node): IP5BaseSourceCodeLocation | null; -export function getSourceLocation(node: P5Node): IP5BaseSourceCodeLocation | null { - interface NodeWithSourceLocations extends IP5NodeBase { - sourceCodeLocation: IP5BaseSourceCodeLocation | null; - __location: IP5BaseSourceCodeLocation | null; - } - const nodeWithLocation = node as unknown as NodeWithSourceLocations; - return nodeWithLocation.sourceCodeLocation || nodeWithLocation.__location; -} diff --git a/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-p5/parse-html.ts b/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-p5/parse-html.ts index 18c36dd1..ed24a1f3 100644 --- a/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-p5/parse-html.ts +++ b/packages/lit-analyzer/src/lib/analyze/parse/document/text-document/html-document/parse-html-p5/parse-html.ts @@ -1,12 +1,11 @@ -import type { IP5CommentNode, IP5DocumentFragmentNode, IP5NodeBase, IP5TagNode, IP5TextNode, P5Node } from "./parse-html-types.js"; - -const { parseFragment } = require("parse5"); +import type { DefaultTreeAdapterTypes } from "parse5"; +import { parseFragment } from "parse5"; /** * Returns if a p5Node is a tag node. * @param node */ -export function isTagNode(node: P5Node): node is IP5TagNode { +export function isTagNode(node: DefaultTreeAdapterTypes.Node): node is DefaultTreeAdapterTypes.Element { return !node.nodeName.includes("#"); } @@ -14,7 +13,7 @@ export function isTagNode(node: P5Node): node is IP5TagNode { * Returns if a p5Node is a document fragment. * @param node */ -export function isDocumentFragmentNode(node: IP5NodeBase): node is IP5DocumentFragmentNode { +export function isDocumentFragmentNode(node: DefaultTreeAdapterTypes.Node): node is DefaultTreeAdapterTypes.DocumentFragment { return node.nodeName === "#document-fragment"; } @@ -22,7 +21,7 @@ export function isDocumentFragmentNode(node: IP5NodeBase): node is IP5DocumentFr * Returns if a p5Node is a text node. * @param node */ -export function isTextNode(node: P5Node): node is IP5TextNode { +export function isTextNode(node: DefaultTreeAdapterTypes.Node): node is DefaultTreeAdapterTypes.TextNode { return node.nodeName === "#text"; } @@ -30,7 +29,7 @@ export function isTextNode(node: P5Node): node is IP5TextNode { * Returns if a p5Node is a comment node. * @param node */ -export function isCommentNode(node: P5Node): node is IP5CommentNode { +export function isCommentNode(node: DefaultTreeAdapterTypes.Node): node is DefaultTreeAdapterTypes.CommentNode { return node.nodeName === "#comment"; } @@ -38,6 +37,6 @@ export function isCommentNode(node: P5Node): node is IP5CommentNode { * Parse a html string into p5Nodes. * @param html */ -export function parseHtml(html: string): IP5DocumentFragmentNode { - return parseFragment(html, { sourceCodeLocationInfo: true, locationInfo: true }); +export function parseHtml(html: string): DefaultTreeAdapterTypes.DocumentFragment { + return parseFragment(html, { sourceCodeLocationInfo: true }); }