import * as vscode from 'vscode' import { FormatErr, HtmlParseErr, ErrFromWingedCli } from '../type' import { ERROR_SOURCE, ERROR_KIND } from '../consts' export class Diagnostic { private collection: vscode.DiagnosticCollection constructor() { this.collection = vscode.languages.createDiagnosticCollection('winged') } /** * 统一管理 document 的语言 id,确保诊断发生在html中 * @param document vscode.TextDocument * @param arr vscode.Diagnostic[] */ private updateDiagnostics(document: vscode.TextDocument, arr: vscode.Diagnostic[]) { if (document && document.languageId === 'html') { this.collection.set(document.uri, arr) } else { this.clearErr() } } /** * 清除诊断集合 */ public clearErr() { this.collection.clear() } /** * 对外暴露的错误处理接口,处理 format 命令格式化抛出来错误,生成诊断信息 * @param document vscode.TextDocument, * @param err FormatErr */ public handleFormatErr(document: vscode.TextDocument, err: FormatErr) { const arr: vscode.Diagnostic[] = [] const range = err.range const severity = vscode.DiagnosticSeverity.Error const source = ERROR_SOURCE let message = `${err.error}\n` switch (err.kind) { case ERROR_KIND.DATA_POINT: message = `数据绑定点语法错误:\n${message}` break case ERROR_KIND.COND: message = `COND表达式语法错误:\n${message}` break case ERROR_KIND.EVENT_BINDER: message = `事件处理器声明错误:\n${message}` break } arr.push({ range, severity, source, message }) this.updateDiagnostics(document, arr) } public handleHtmlComplierErr(document: vscode.TextDocument, err: HtmlParseErr) { const arr: vscode.Diagnostic[] = [] const range = err.range const severity = vscode.DiagnosticSeverity.Error const source = ERROR_SOURCE const message = err.message arr.push({ range, severity, source, message }) this.updateDiagnostics(document, arr) } public handleErrFromCli(content: ErrFromWingedCli) { if (content.type === 'success') { this.clearErr() return } const document = vscode.window.activeTextEditor?.document if (document) { const arr: vscode.Diagnostic[] = [] const severity = vscode.DiagnosticSeverity.Error const source = ERROR_SOURCE const messageArr: string[] = [] if (content.title) { messageArr.push(content.title) } if (content.detail) { messageArr.push(content.detail) } const message = messageArr.join('\n') const start = content.range.start const end = content.range.end const range = new vscode.Range( new vscode.Position(start.line - 1, start.col), new vscode.Position(end.line - 1, end.col) ) if (range) { arr.push({ range, severity, source, message }) this.updateDiagnostics(document, arr) } } } public checkCollection(document: vscode.TextDocument) { return this.collection.has(document.uri) } }