UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

87 lines 3.94 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TreeSitterExecutor = exports.DEFAULT_TREE_SITTER_WASM_PATH = exports.DEFAULT_TREE_SITTER_R_WASM_PATH = void 0; const web_tree_sitter_1 = __importDefault(require("web-tree-sitter")); const log_1 = require("../../../util/log"); const fs_1 = __importDefault(require("fs")); exports.DEFAULT_TREE_SITTER_R_WASM_PATH = './node_modules/@eagleoutice/tree-sitter-r/tree-sitter-r.wasm'; exports.DEFAULT_TREE_SITTER_WASM_PATH = './node_modules/web-tree-sitter/tree-sitter.wasm'; const wasmLog = log_1.log.getSubLogger({ name: 'tree-sitter-wasm' }); /** * Synchronous and (way) faster alternative to the {@link RShell} using tree-sitter. */ class TreeSitterExecutor { name = 'tree-sitter'; parser; static language; /** * Initializes the underlying tree-sitter parser. This only needs to be called once globally. * @param config - The configuration for the tree-sitter engine, which can include paths to the wasm files. * @param overrideWasmPath - The path to the tree-sitter-r wasm file, which takes precedence over the config and default paths if set. * @param overrideTreeSitterWasmPath - The path to the tree-sitter wasm file, which takes precedence over the config and default paths if set. */ static async initTreeSitter(config, overrideWasmPath, overrideTreeSitterWasmPath) { const treeSitterWasmPath = overrideTreeSitterWasmPath ?? config?.treeSitterWasmPath ?? exports.DEFAULT_TREE_SITTER_WASM_PATH; // noinspection JSUnusedGlobalSymbols - this is used by emscripten, see https://emscripten.org/docs/api_reference/module.html await web_tree_sitter_1.default.init({ locateFile: treeSitterWasmPath ? (path, prefix) => { // allow setting a custom path for the tree sitter wasm file if (path.endsWith('tree-sitter.wasm')) { return treeSitterWasmPath; } return prefix + path; } : undefined, onAbort: (s) => wasmLog.error(`Tree-sitter wasm aborted: ${s}`), print: (s) => wasmLog.debug(s), printErr: (s) => wasmLog.error(s) }); const wasmPath = overrideWasmPath ?? config?.wasmPath ?? exports.DEFAULT_TREE_SITTER_R_WASM_PATH; TreeSitterExecutor.language = await web_tree_sitter_1.default.Language.load(wasmPath); } constructor() { this.parser = new web_tree_sitter_1.default(); this.parser.setLanguage(TreeSitterExecutor.language); } rVersion() { return Promise.resolve('none'); } information(analyzer) { return { name: 'tree-sitter', grammarVersion: this.treeSitterVersion(), treeSitterQuery: async (source, force) => { return this.query(source, ...(await analyzer.parse(force)).files.map(p => p.parsed)); } }; } treeSitterVersion() { return this.parser.getLanguage().version; } parse(request) { let sourceCode; if (request.request === 'file') { sourceCode = fs_1.default.readFileSync(request.content, 'utf8'); } else { sourceCode = request.content; } return this.parser.parse(sourceCode); } createQuery(source) { return this.parser.getLanguage().query(source); } query(source, ...tree) { const query = typeof source === 'string' ? this.createQuery(source) : source; return tree .flatMap(t => query.matches(t.rootNode)) .flatMap(m => m.captures); } close() { this.parser.delete(); } } exports.TreeSitterExecutor = TreeSitterExecutor; //# sourceMappingURL=tree-sitter-executor.js.map