Files
squirrelVsis/dist/utils/beautifyHelper.js
2025-10-22 10:55:24 +08:00

238 lines
8.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSquirrelBeautifyOptions = getSquirrelBeautifyOptions;
exports.beautifyCode = beautifyCode;
exports.isSquirrelCode = isSquirrelCode;
const vscode = __importStar(require("vscode"));
// 由于 js-beautify.js 文件体积较大且复杂,我们将创建专门的存根函数
// 将使用原生的 js-beautify 功能
let _jsBeauifyInstance = null;
/**
* 动态创建 js_beautify 函数
*/
function createJsBeautify() {
if (_jsBeauifyInstance) {
return _jsBeauifyInstance;
}
try {
// 加载原始的 js-beautify.js 文件
const beautifyModule = loadJsBeautify();
_jsBeauifyInstance = beautifyModule;
return _jsBeauifyInstance;
}
catch (error) {
console.error('加载 js-beautify 失败,使用后备实现:', error);
// 调用后备实现
return createBasicJsBeautify();
}
}
/**
* 加载 js-beautify 模块
*/
function loadJsBeautify() {
// 根据环境动态加载
try {
// 尝试 require 原始的 js-beautify.js 文件
// 注意TypeScript 会从 ./dist 目录运行,所以需要从正确的路径加载
const beautifyPath = __dirname + '/../../js-beautify.js';
const Module = require('module');
const vm = require('vm');
const fs = require('fs');
// 读取文件内容
const code = fs.readFileSync(beautifyPath, 'utf8');
// 设置全局环境
const sandbox = {
window: {},
global: {},
console: console,
String: String,
Array: Array,
Object: Object,
Math: Math
};
// 在沙箱中执行代码
const script = new vm.Script(code);
const context = vm.createContext(sandbox);
script.runInContext(context);
// 获取 js_beautify 函数
return context.window.js_beautify || context.js_beautify || sandbox.window.js_beautify;
}
catch (loadError) {
console.error('无法加载原始 js-beautify, 错误:', loadError);
throw loadError;
}
}
/**
* 基础的 js-beautify 实现(后备方案)
*/
function createBasicJsBeautify() {
return function (code, options = {}) {
// 默认选项
const defaultOptions = {
indent_size: 4,
indent_char: ' ',
preserve_newlines: true,
brace_style: 'collapse',
space_before_conditional: true,
space_after_anon_function: false,
wrap_line_length: 0, // 默认禁用自动换行
end_with_newline: false
};
// 合并选项
const opts = { ...defaultOptions, ...options };
// 简化的代码美化实现
let formatted = code;
// 清理缩进
formatted = formatted.replace(/[\r\n]+/g, '\n');
const lines = formatted.split('\n');
const result = [];
let indentLevel = 0;
const indentStr = opts.indent_char.repeat(opts.indent_size);
for (const line of lines) {
const trimmed = line.trim();
// 跳过空行
if (trimmed.length === 0) {
result.push('');
continue;
}
// 处理大括号
if (trimmed.startsWith('}') || trimmed.startsWith(')') || trimmed.startsWith(']')) {
indentLevel = Math.max(0, indentLevel - 1);
}
// 添加缩进
const indentedLine = indentStr.repeat(indentLevel) + trimmed;
result.push(indentedLine);
// 增加缩进
if (trimmed.endsWith('{') || trimmed.endsWith('(') || trimmed.endsWith('[')) {
indentLevel++;
}
// 特殊处理 else、catch 等关键字
if (trimmed.startsWith('else') || trimmed.startsWith('catch') || trimmed.startsWith('elif')) {
// 检查前面一行是否以 } 结尾
if (result.length > 1) {
const prevLine = result[result.length - 2];
const prevTrimmed = prevLine.trim();
if (prevTrimmed.endsWith('}')) {
// 移动到前一行的必要部分
result[result.length - 2] = indentStr.repeat(indentLevel - 1) +
prevTrimmed + ' ' + trimmed;
result.pop(); // 移除当前行
indentLevel--; // 修正缩进级别
}
}
}
}
let finalResult = result.join('\n');
// 处理空格 - 在操作符周围添加空格
finalResult = finalResult
.replace(/([a-zA-Z0-9_$])([=!<>+\-*/%])([a-zA-Z0-9_$])/g, '$1 $2 $3')
.replace(/([a-zA-Z0-9_$])(,)([a-zA-Z0-9_$])/g, '$1$2 $3')
.replace(/\s+/g, ' ') // 将多个空格替换为单个空格
.trim();
return finalResult;
};
}
// 初始化 js_beautify
const jsBeautify = {
js_beautify: createJsBeautify()
};
/**
* Squirrel 语言的 js-beautify 选项配置
*/
function getSquirrelBeautifyOptions(options) {
// 从用户配置中读取换行长度设置
const config = vscode.workspace.getConfiguration('squirrel.formatting');
const wrapLineLength = config.get('wrapLineLength', 0);
return {
indent_size: options.tabSize,
indent_char: options.insertSpaces ? ' ' : '\t',
preserve_newlines: true,
max_preserve_newlines: 2,
jslint_happy: false,
brace_style: "collapse",
space_before_conditional: true,
space_after_anon_function: false,
unescape_strings: false,
wrap_line_length: wrapLineLength,
end_with_newline: false
};
}
/**
* 使用 js-beautify 格式化代码
*/
function beautifyCode(code, options) {
if (!jsBeautify || !jsBeautify.js_beautify) {
console.warn('js-beautify 不可用,返回原始代码');
return code;
}
try {
const beautifyOptions = getSquirrelBeautifyOptions(options);
// 检查代码长度,处理大块代码
const maxChunkSize = 50000; // 50KB 每块
if (code.length > maxChunkSize) {
// 分割代码并分块处理
const chunks = code.split('\n');
const resultChunks = [];
for (const chunk of chunks) {
const formattedChunk = jsBeautify.js_beautify(chunk, beautifyOptions);
resultChunks.push(formattedChunk);
}
return resultChunks.join('\n');
}
// 直接格式化小代码块
return jsBeautify.js_beautify(code, beautifyOptions);
}
catch (error) {
console.error('js-beautify 格式化失败:', error);
// 如果格式化失败,返回原始代码
return code;
}
}
/**
* 检测是否为 Squirrel 代码(用于确定是否应用格式化)
*/
function isSquirrelCode(code) {
// 简单的启发式检测 - Squirrel 特有关键字
const squirrelKeywords = [
'function', 'local', 'if', 'else', 'while', 'for', 'foreach',
'class', 'constructor', 'extends', 'instanceof', 'in',
'try', 'catch', 'throw', 'clone', 'delegate', 'resume', 'yield',
'typeof', 'member', 'rawcall', 'call', 'setdebughook'
];
// 提高检测准确性 - 需要至少匹配到1个关键字
return squirrelKeywords.some(keyword => new RegExp(`\\b${keyword}\\b`).test(code));
}
//# sourceMappingURL=beautifyHelper.js.map