UNPKG

svelte-language-server

Version:
100 lines 3.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isInTag = isInTag; exports.isAttributeName = isAttributeName; exports.isAttributeShorthand = isAttributeShorthand; exports.isEventHandler = isEventHandler; exports.isElseBlockWithElseIf = isElseBlockWithElseIf; exports.hasElseBlock = hasElseBlock; exports.findElseBlockTagStart = findElseBlockTagStart; exports.findIfBlockEndTagStart = findIfBlockEndTagStart; exports.walkSvelteAst = walkSvelteAst; exports.isAwaitBlock = isAwaitBlock; exports.isEachBlock = isEachBlock; const estree_walker_1 = require("estree-walker"); function matchesOnly(type, only) { return (!only || // We hide the detail that body/window are also like elements in the context of this usage (only === 'Element' && ['Element', 'Body', 'Window'].includes(type)) || (only === 'InlineComponent' && type === 'InlineComponent')); } /** * Returns true if given node is a component or html element, or if the offset is at the end of the node * and its parent is a component or html element. */ function isInTag(node, offset) { return (node?.type === 'InlineComponent' || node?.type === 'Element' || (node?.end === offset && (node?.parent?.type === 'InlineComponent' || node?.parent?.type === 'Element'))); } /** * Returns when given node represents an HTML Attribute. * Example: The `class` in `<div class=".."`. * Note: This method returns `false` for shorthands like `<div {foo}`. */ function isAttributeName(node, only) { return !!node && node.type === 'Attribute' && matchesOnly(node.parent?.type, only); } /** * Returns when given node represents an HTML Attribute shorthand or is inside one. * Example: The `{foo}` in `<div {foo}` */ function isAttributeShorthand(node, only) { if (!node) { return false; } do { // We could get the expression, or the shorthand, or the attribute // Be pragmatic and just go upwards until we can't anymore if (isAttributeName(node, only)) { return true; } node = node.parent; } while (node); return false; } /** * Returns when given node represents an HTML Attribute shorthand or is inside one. * Example: The `on:click={foo}` in `<div on:click={foo}` */ function isEventHandler(node, only) { return !!node && node.type === 'EventHandler' && matchesOnly(node.parent?.type, only); } function isElseBlockWithElseIf(node) { return (!!node && node.type === 'ElseBlock' && 'children' in node && Array.isArray(node.children) && node.children.length === 1 && node.children[0].type === 'IfBlock'); } function hasElseBlock(node) { return 'else' in node && !!node.else; } function findElseBlockTagStart(documentText, elseBlock) { return documentText.lastIndexOf('{', documentText.lastIndexOf(':else', elseBlock.start)); } function findIfBlockEndTagStart(documentText, ifBlock) { return documentText.lastIndexOf('{', documentText.lastIndexOf('/if', ifBlock.end)); } // wrap the estree-walker to make it svelte specific // the type casting is necessary because estree-walker is not designed for this // especially in v3 which svelte 4 uses function walkSvelteAst(htmlAst, walker) { (0, estree_walker_1.walk)(htmlAst, { enter(node, parent, key, index) { walker.enter?.call(this, node, parent, key, index); }, leave(node, parent, key, index) { walker.leave?.call(this, node, parent, key, index); } }); } function isAwaitBlock(node) { return node.type === 'AwaitBlock'; } function isEachBlock(node) { return node.type === 'EachBlock'; } //# sourceMappingURL=svelte-ast-utils.js.map