UNPKG

imdone-core

Version:
127 lines (107 loc) 3.13 kB
import path from 'node:path' import { ReadStreamTaskParser } from './ReadStreamTaskParser.js' import { CodeStyleTaskParser } from '../task/CodeStyleTaskParser.js' import { languages } from '../../../languages.js' import extractComments from 'multilang-extract-comments' import eol from 'eol' import { Readable } from 'node:stream' // TODO Move to readstream parsing for code to improve performance // <!-- // #important // #imdone-1.55.0 // order:-205 // --> export class ReadStreamCodeParser extends ReadStreamTaskParser { constructor(readStream, filePath, lang, lists) { super(readStream) this.lists = lists this.filePath = filePath this.lang = lang this.taskParsers = [new CodeStyleTaskParser()] } async init() { const code = await streamToString(this.readStream) // TODO Getting tokens from lists should be done higher up in the controller // <!-- // order:-10 // --> const tokens = this.lists.filter(list => !list.filter).map(list => list.name) this.cards = this.parseCards(code, tokens) } async readTask() { return this.cards.shift() } parseCards(code, tokens = ['TODO']) { const comments = this.parseComments(code); const cards = []; Object.keys(comments).forEach((comment) => { const { begin, end, content } = comments[comment]; const line = begin; const lastLine = end; // TODO lastLine should not be - 1 // <!-- // order:-140 // --> const lines = content.split('\n'); // Check if the comment contains "TODO" lines.forEach(codeLine => { if (tokens.find((token) => codeLine.includes(token))) { // Get all lines from start to end cards.push({ content, line, lastLine, }); } }); }); return cards; } parseComments(code) { const options = getLanguageOptions(this.filePath); const comments = extractComments(code, options); return comments; } } function getLanguageOptions(filePath) { const extension = path.extname(filePath) const language = languages[extension] const { name, symbol, block, } = language || { name: 'text', symbol: '', block: { start: undefined, end: undefined, ignore: undefined, } }; // Use lang to get comment patterns const { start, ignore: middle, end } = block || {}; return language && { pattern: { name, nameMatchers: extension && [extension] || [], singleLineComment: symbol && [{ start: symbol }] || [], multiLineComment: start && end && [{ start, middle, end }] || [], }, }; } async function streamToString(stream) { const chunks = [] for await (const chunk of stream) { chunks.push(Buffer.from(chunk)) } return Buffer.concat(chunks).toString('utf-8') } function stringToStream(string) { const lines = eol.split(string).map((line) => line + String(eol.auto)) return Readable.from(lines) }