From 3d81ad780eda6a1ce975fa1b59b6fafeaea49be5 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 12 May 2023 17:23:37 +0200 Subject: [PATCH] Convert src/compiler/compile/nodes/shared/get_const_tags.ts to JavaScript --- .../compile/nodes/shared/Expression.js | 9 +- .../compile/nodes/shared/get_const_tags.ts | 186 +++++++++--------- 2 files changed, 99 insertions(+), 96 deletions(-) diff --git a/src/compiler/compile/nodes/shared/Expression.js b/src/compiler/compile/nodes/shared/Expression.js index c3cdb9c0eb..d617b0b1a7 100644 --- a/src/compiler/compile/nodes/shared/Expression.js +++ b/src/compiler/compile/nodes/shared/Expression.js @@ -12,7 +12,9 @@ import replace_object from '../../utils/replace_object.js'; import is_contextual from './is_contextual.js'; import { clone } from '../../../utils/clone.js'; import compiler_errors from '../../compiler_errors.js'; + const regex_contains_term_function_expression = /FunctionExpression/; + export default class Expression { /** @type {'Expression'} */ type = 'Expression'; @@ -20,7 +22,7 @@ export default class Expression { /** @type {import('../../Component.js').default} */ component; - /** @type {Owner} */ + /** @type {import('../interfaces.js').INode} */ owner; /** @type {import('estree').Node} */ @@ -54,7 +56,7 @@ export default class Expression { /** * @param {import('../../Component.js').default} component * - * @param {Owner} owner * + * @param {import('../interfaces.js').INode} owner * * @param {import('./TemplateScope.js').default} template_scope * * @param {import('estree').Node} info * * @param {boolean} [lazy] undefined @@ -362,6 +364,7 @@ export default class Expression { // we need a combo block/init recipe const { deps, func_declaration } = extract_functions(); if (owner.type === 'Attribute' && owner.parent.name === 'slot') { + /** @type {Set} */ const dep_scopes = new Set( deps.map(/** @param {any} name */ (name) => template_scope.get_owner(name)) ); @@ -480,5 +483,3 @@ function get_function_name(_node, parent) { } return 'func'; } - -/** @typedef {INode} Owner */ diff --git a/src/compiler/compile/nodes/shared/get_const_tags.ts b/src/compiler/compile/nodes/shared/get_const_tags.ts index ca4cbe7884..17ffc82a64 100644 --- a/src/compiler/compile/nodes/shared/get_const_tags.ts +++ b/src/compiler/compile/nodes/shared/get_const_tags.ts @@ -1,98 +1,100 @@ -import { TemplateNode, ConstTag as ConstTagType } from '../../../interfaces'; -import Component from '../../Component'; -import ConstTag from '../ConstTag'; -import map_children from './map_children'; -import { INodeAllowConstTag, INode } from '../interfaces'; -import check_graph_for_cycles from '../../utils/check_graph_for_cycles'; -import compiler_errors from '../../compiler_errors'; - -export default function get_const_tags( - children: TemplateNode[], - component: Component, - node: INodeAllowConstTag, - parent: INode -): [ConstTag[], Array>] { - const const_tags: ConstTagType[] = []; - const others: Array> = []; - - for (const child of children) { - if (child.type === 'ConstTag') { - const_tags.push(child as ConstTagType); - } else { - others.push(child); - } - } - - const consts_nodes = const_tags.map((tag) => new ConstTag(component, node, node.scope, tag)); - const sorted_consts_nodes = sort_consts_nodes(consts_nodes, component); - sorted_consts_nodes.forEach((node) => node.parse_expression()); - - const children_nodes = map_children(component, parent, node.scope, others); - - return [sorted_consts_nodes, children_nodes as Array>]; +import ConstTag from '../ConstTag.js'; +import map_children from './map_children.js'; +import check_graph_for_cycles from '../../utils/check_graph_for_cycles.js'; +import compiler_errors from '../../compiler_errors.js'; + +/** + * @param {import('../../../interfaces.js').TemplateNode[]} children + * @param {import('../../Component.js').default} component + * @param {import('../interfaces.js').INodeAllowConstTag} node + * @param {import('../interfaces.js').INode} parent + * @returns {[import('../../../interfaces.js').ConstTag[], never[]]} + */ +export default function get_const_tags(children, component, node, parent) { + + /** @type {ConstTagType[]} */ + const const_tags = []; + + /** @type {Array>} */ + const others = []; + for (const child of children) { + if (child.type === 'ConstTag') { + const_tags.push(/** @type {ConstTagType} */ (child)); + } + else { + others.push(child); + } + } + const consts_nodes = const_tags.map(/** @param {any} tag */ (tag) => new ConstTag(component, node, node.scope, tag)); + const sorted_consts_nodes = sort_consts_nodes(consts_nodes, component); + sorted_consts_nodes.forEach(/** @param {any} node */ (node) => node.parse_expression()); + const children_nodes = map_children(component, parent, node.scope, others); + return [sorted_consts_nodes, /** @type {Array>} */ (children_nodes)]; } -function sort_consts_nodes(consts_nodes: ConstTag[], component: Component) { - type ConstNode = { - assignees: Set; - dependencies: Set; - node: ConstTag; - }; - const sorted_consts_nodes: ConstNode[] = []; - - const unsorted_consts_nodes: ConstNode[] = consts_nodes.map((node) => { - return { - assignees: node.assignees, - dependencies: node.dependencies, - node - }; - }); - - const lookup = new Map(); - - unsorted_consts_nodes.forEach((node) => { - node.assignees.forEach((name) => { - if (!lookup.has(name)) { - lookup.set(name, []); - } - lookup.get(name).push(node); - }); - }); - - const cycle = check_graph_for_cycles( - unsorted_consts_nodes.reduce((acc, node) => { - node.assignees.forEach((v) => { - node.dependencies.forEach((w) => { - if (!node.assignees.has(w)) { - acc.push([v, w]); - } - }); - }); - return acc; - }, []) - ); - - if (cycle && cycle.length) { - const nodeList = lookup.get(cycle[0]); - const node = nodeList[0]; - component.error(node.node, compiler_errors.cyclical_const_tags(cycle)); - } - - const add_node = (node: ConstNode) => { - if (sorted_consts_nodes.includes(node)) return; +/** + * @param {import('../../../interfaces.js').ConstTag[]} consts_nodes + * @param {import('../../Component.js').default} component + */ +function sort_consts_nodes(consts_nodes, component) { + + /** @type {ConstNode[]} */ + const sorted_consts_nodes = []; + + /** @type {ConstNode[]} */ + const unsorted_consts_nodes = consts_nodes.map(/** @param {any} node */ (node) => { + return { + assignees: node.assignees, + dependencies: node.dependencies, + node + }; + }); + const lookup = new Map(); + unsorted_consts_nodes.forEach(/** @param {any} node */ (node) => { + node.assignees.forEach(/** @param {any} name */ (name) => { + if (!lookup.has(name)) { + lookup.set(name, []); + } + lookup.get(name).push(node); + }); + }); + const cycle = check_graph_for_cycles(unsorted_consts_nodes.reduce(/** + * @param {any} acc + * @param {any} node + */ (acc, node) => { + node.assignees.forEach(/** @param {any} v */ (v) => { + node.dependencies.forEach(/** @param {any} w */ (w) => { + if (!node.assignees.has(w)) { + acc.push([v, w]); + } + }); + }); + return acc; + }, [])); + if (cycle && cycle.length) { + const nodeList = lookup.get(cycle[0]); + const node = nodeList[0]; + component.error(node.node, compiler_errors.cyclical_const_tags(cycle)); + } + + /** @param {ConstNode} node */ + const add_node = (node) => { + if (sorted_consts_nodes.includes(node)) + return; + node.dependencies.forEach(/** @param {any} name */ (name) => { + if (node.assignees.has(name)) + return; + const earlier_nodes = lookup.get(name); + if (earlier_nodes) { + earlier_nodes.forEach(add_node); + } + }); + sorted_consts_nodes.push(node); + }; + unsorted_consts_nodes.forEach(add_node); + return sorted_consts_nodes.map(/** @param {any} node */ (node) => node.node); +} - node.dependencies.forEach((name) => { - if (node.assignees.has(name)) return; - const earlier_nodes = lookup.get(name); - if (earlier_nodes) { - earlier_nodes.forEach(add_node); - } - }); - sorted_consts_nodes.push(node); - }; - unsorted_consts_nodes.forEach(add_node); - return sorted_consts_nodes.map((node) => node.node); -}