blob: 801d07c479c706e208660bb9ff0a22557896c7fc [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import type {TSESTree} from '@typescript-eslint/utils';
/**
* @param node a TaggedTemplateExpression node from the AST of the parsed code.
* @returns - `true` if the code matches Lit.html`` or html``, and false otherwise.
*/
export function isLitHtmlTemplateCall(node: TSESTree.Node): node is TSESTree.TaggedTemplateExpression {
if (node.type !== 'TaggedTemplateExpression') {
return false;
}
// Match Lit.html``
const {tag} = node;
if (!tag) {
return false;
}
// Match Lit.html``
if (tag.type === 'MemberExpression' && tag.object.type === 'Identifier' && tag.property.type === 'Identifier') {
return tag.object.name === 'Lit' && tag.property.name === 'html';
}
// Match html`` (and guess that it's Lit)
if (tag.type === 'Identifier') {
return tag.type === 'Identifier' && tag.name === 'html';
}
return false;
}
/**
* @param node a CallExpression node from the AST of the parsed code.
* @returns - `true` if the code matches Lit.render() or render(), and false otherwise.
*/
export function isLitHtmlRenderCall(node: TSESTree.Node): node is TSESTree.CallExpression {
if (node.type !== 'CallExpression') {
return false;
}
const {callee} = node;
if (callee.type === 'Identifier' && callee.name === 'render') {
return true;
}
if (callee.type !== 'MemberExpression' || callee.object.type !== 'Identifier' ||
callee.property.type !== 'Identifier') {
return false;
}
return callee.object.name === 'Lit' && callee.property.name === 'render';
}
/**
* Determines if a given AST function node matches the "view function" signature.
* A view function is expected to have three parameters, with names conventionally
* ending in 'input', 'output', and 'target'.
* @param node The function-like AST node to inspect.
* @returns True if the node is a view function, false otherwise.
*/
export function isViewFunction(node: TSESTree.Node): boolean {
if (!['FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression'].includes(node.type)) {
return false;
}
const functionNode =
node as TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.ArrowFunctionExpression;
const paramNames =
functionNode.params.filter((p): p is TSESTree.Identifier => p.type === 'Identifier').map(param => param.name);
return paramNames.length === 3 && paramNames[0].toLowerCase().endsWith('input') &&
paramNames[1].toLowerCase().endsWith('output') && paramNames[2].toLowerCase().endsWith('target');
}