"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const error_1 = require("../error");
/**
* GonzalesPe Adapter
* @extends Adapter
*/
class GonzalesPeAdapter {
// get node source
getSource(node, options) {
const column = this.getIndent(node);
return " ".repeat(column) + node.toString();
}
/**
* Get the source code of current file.
* @returns {string} source code of current file.
*/
fileContent(node) {
return fs_1.default.readFileSync(node.sourceFile, "utf-8");
}
/**
* Get the source range of child node.
* @param {Node} node - The node.
* @param {string} childName - The name to find child node.
* @returns {Object} The range of the child node, e.g. { start: 0, end: 10 }
* @throws {NotSupportedError} if we can't get the range.
* @example
* const node = gonzales.parse("a { color: red }")
* childNodeRange(node, "{{block.declaration.value}}") // { start: "a { color: ".length, end: "a { color: red".length }
*/
childNodeRange(node, childName) {
if (node.type === "block" && childName === "leftCurlyBracket") {
return { start: this.getStart(node), end: this.getStart(node) + 1 };
}
if (node.type === "block" && childName === "rightCurlyBracket") {
return { start: this.getEnd(node) - 1, end: this.getEnd(node) };
}
const [directChildName, ...nestedChildName] = childName.split(".");
const childNode = node[directChildName];
if (childNode) {
if (Array.isArray(childNode)) {
const [childDirectChildName, ...childNestedChildName] = nestedChildName;
if (childNestedChildName.length > 0) {
return this.childNodeRange(childNode[childDirectChildName], childNestedChildName.join("."));
}
if (!Number.isNaN(childDirectChildName)) {
const childChildNode = childNode.at(Number.parseInt(childDirectChildName));
if (childChildNode) {
return { start: this.getStart(childChildNode), end: this.getEnd(childChildNode) };
}
else {
return { start: this.getEnd(node) - 1, end: this.getEnd(node) - 1 };
}
}
else {
throw new error_1.NotSupportedError(`${childName} is not supported for ${this.getSource(node)}`);
}
}
if (nestedChildName.length > 0) {
return this.childNodeRange(childNode, nestedChildName.join("."));
}
if (childNode) {
return { start: this.getStart(childNode), end: this.getEnd(childNode) };
}
}
throw new error_1.NotSupportedError(`${childName} is not supported for ${this.getSource(node)}`);
}
/**
* Get the value of child node.
* @param {Node} node - The node to evaluate.
* @param {string} childName - The name to find child node.
* @returns {any} The value of child node, it can be a node, an array, a string or a number.
* @example
* const code = `
* nav {
* a {
* color: red;
* }
* }
* `;
* const node = gonzales.parse(code, { syntax: "scs" });
* childNodeValue(node, "ruleset.block.ruleset") // node["ruleset"]["block"]["ruleset"]
*/
childNodeValue(node, childName) {
return this.actualValue(node, childName.split("."));
}
getStart(node, childName) {
if (childName) {
node = this.childNodeValue(node, childName);
}
if (node.start.line === 1) {
return node.start.column - 1;
}
return this.lineCharsCount(this.fileContent(node), node.start.line - 1) + node.start.column - 1;
}
getEnd(node, childName) {
if (childName) {
node = this.childNodeValue(node, childName);
}
if (node.end.line === 1) {
return node.end.column;
}
return this.lineCharsCount(this.fileContent(node), node.end.line - 1) + node.end.column;
}
getStartLoc(node, childName) {
if (childName) {
node = this.childNodeValue(node, childName);
}
return { line: node.start.line, column: node.start.column - 1 };
}
getEndLoc(node, childName) {
if (childName) {
node = this.childNodeValue(node, childName);
}
return { line: node.end.line, column: node.end.column };
}
getIndent(node) {
return node.start.column - 1;
}
actualValue(node, multiKeys) {
let childNode = node;
multiKeys.forEach((key) => {
if (!childNode)
return;
if (childNode[key]) {
childNode = childNode[key];
}
else if (Array.isArray(childNode) && /-?\d+/.test(key)) {
childNode = childNode.at(Number.parseInt(key));
}
else {
throw `${key} is not supported for ${this.getSource(childNode)}`;
}
});
return childNode;
}
// Get the char count of lines of code.
// @param code {String} source code.
// @param lines {Number} lines of code.
// @return {Number} char count of lines of code.
lineCharsCount(code, lines) {
return code.split("\n").slice(0, lines).join("\n").length + 1;
}
}
exports.default = GonzalesPeAdapter;