mfuntowicz's picture
mfuntowicz HF Staff
Upload folder using huggingface_hub
04ec17f verified
raw
history blame
2.84 kB
/** @import { TSESTree } from '@typescript-eslint/types' */
/** @import { BaseNode, Command, Visitors } from './types' */
export const margin = 0;
export const newline = 1;
export const indent = 2;
export const dedent = 3;
export const space = 4;
export class Context {
#visitors;
#commands;
#has_newline = false;
multiline = false;
/**
*
* @param {Visitors} visitors
* @param {Command[]} commands
*/
constructor(visitors, commands = []) {
this.#visitors = visitors;
this.#commands = commands;
}
indent() {
this.#commands.push(indent);
}
dedent() {
this.#commands.push(dedent);
}
margin() {
this.#commands.push(margin);
}
newline() {
this.#has_newline = true;
this.#commands.push(newline);
}
space() {
this.#commands.push(space);
}
/**
* @param {Context} context
*/
append(context) {
this.#commands.push(context.#commands);
if (this.#has_newline) {
this.multiline = true;
}
}
/**
*
* @param {string} content
* @param {BaseNode} [node]
*/
write(content, node) {
if (node?.loc) {
this.location(node.loc.start.line, node.loc.start.column);
this.#commands.push(content);
this.location(node.loc.end.line, node.loc.end.column);
} else {
this.#commands.push(content);
}
if (this.#has_newline) {
this.multiline = true;
}
}
/**
*
* @param {number} line
* @param {number} column
*/
location(line, column) {
this.#commands.push({ type: 'Location', line, column });
}
/**
* @param {{ type: string }} node
*/
visit(node) {
const visitor = this.#visitors[node.type];
if (!visitor) {
let message = `Not implemented: ${node.type}`;
if (node.type.includes('TS')) {
message += ` (consider using 'esrap/languages/ts')`;
}
if (node.type.includes('JSX')) {
message += ` (consider using 'esrap/languages/tsx')`;
}
throw new Error(message);
}
if (this.#visitors._) {
// @ts-ignore
this.#visitors._(node, this, (node) => visitor(node, this));
} else {
// @ts-ignore
visitor(node, this);
}
}
empty() {
return !this.#commands.some(has_content);
}
measure() {
return measure(this.#commands);
}
new() {
return new Context(this.#visitors);
}
}
/**
*
* @param {Command[]} commands
* @param {number} [from]
* @param {number} [to]
*/
function measure(commands, from = 0, to = commands.length) {
let total = 0;
for (let i = from; i < to; i += 1) {
const command = commands[i];
if (typeof command === 'string') {
total += command.length;
} else if (Array.isArray(command)) {
total += measure(command);
}
}
return total;
}
/**
* @param {Command} command
*/
function has_content(command) {
if (Array.isArray(command)) {
return command.some(has_content);
}
if (typeof command === 'string') {
return command.length > 0;
}
return false;
}