diff --git a/server/src/errorHandler.ts b/server/src/errorHandler.ts index 10af895c81446f51ac391dd3332806b0aa300d01..a4a357ae283095e41ef6d2097535e7363e9040b9 100644 --- a/server/src/errorHandler.ts +++ b/server/src/errorHandler.ts @@ -5,12 +5,9 @@ import * as readline from 'readline' -/** - * Reads the error file, casts the errors to a readable form, sorts them by origin - * @param errorPath the path to the file where the ndjson errors are stored - */ -export async function readErrors(errorPath: string): Promise<Map<string, Set<NDJSON>>> { - let result: Map<string, Set<NDJSON>> = new Map() +export async function readErrors(errorPath: string) : Promise<Array<string>>{ + + let lines : Array<string> = new Array() var stream = fs.createReadStream(errorPath) @@ -19,9 +16,23 @@ export async function readErrors(errorPath: string): Promise<Map<string, Set<NDJ crlfDelay: Infinity }); + for await(const line of rl){ + lines.push(line) + } + + return lines +} - let i : number = 1 - for await (const line of rl) { + +/** + * Reads the error file, casts the errors to a readable form, sorts them by origin + * @param errorLines an array containing all errors + */ +export function buildErrors(errorLines : Array<string> ): Map<string, Set<NDJSON>> { + let result: Map<string, Set<NDJSON>> = new Map() + + let i : number = 2 + for (const line of errorLines) { let obj: NDJSON @@ -31,13 +42,14 @@ export async function readErrors(errorPath: string): Promise<Map<string, Set<NDJ throw Error(e.message + " at line " + line) } i++ - let path: string = obj.details.file + let path = obj.file - if (!result.has(path)) { + + if(!result.has(path)){ result.set(path, new Set()) } - + result.get(path)!.add(obj) } @@ -50,10 +62,10 @@ export async function readErrors(errorPath: string): Promise<Map<string, Set<NDJ */ export function matchErrors(infos: Set<NDJSON>, file?: TextDocument | undefined): Array<Diagnostic> { let result: Array<Diagnostic> = new Array() - + console.log("infos " + infos) for (var info of infos) { - + console.log("type" + info.type) let serveity: DiagnosticSeverity = DiagnosticSeverity.Error if (info.type == "error") { @@ -68,37 +80,37 @@ export function matchErrors(infos: Set<NDJSON>, file?: TextDocument | undefined) serveity = DiagnosticSeverity.Information } - let content: JBody = info.details // Managing case we get conent with no error massage - if (content.start.line == -1 && content.start.col == -1 && content.end.line == -1 && content.end.col == -1) { + if (info.start.line == -1 && info.start.col == -1 && info.end.line == -1 && info.end.col == -1) { if (file != undefined) { //Due to server architecture we only have the most actual document let targetLine = getFirstOccurence(file).line - content.start = { line: targetLine, col: 0 } - content.end = { line: targetLine, col: Number.MAX_VALUE } + info.start = { line: targetLine, col: 0 } + info.end = { line: targetLine, col: Number.MAX_VALUE } } else { //Fallback if an error occurs on differnt document - content.start = { line: 1, col: 0 } - content.end = { line: 1, col: Number.MAX_VALUE } + info.start = { line: 1, col: 0 } + info.end = { line: 1, col: Number.MAX_VALUE } } } - let diagnostic = { + let diagnostic : Diagnostic = { severity: serveity, range: { start: { - character: content.start.col, - line: content.start.line - 1 + character: info.start.col, + line: info.start.line - 1 }, end: { - character: content.end.col, - line: content.end.line - 1 + character: info.end.col, + line: info.end.line - 1 } }, - message: content.message, - source: content.file, + message: info.message, + source: info.file, + code : "probcli v." + info.prob_version }; @@ -113,22 +125,27 @@ export function matchErrors(infos: Set<NDJSON>, file?: TextDocument | undefined) ////////////// Representation of the NDJSON File export interface NDJSON { type: string - details: JBody + message: string + reason: string + file: string + start: StartOrEnd + end: StartOrEnd + prob_version : string +// main_file : string +// dependencies : Array<string> } -export interface JBody { - message: string; - type: string; - file: string; - start: StartOrEnd; - end: StartOrEnd; -} + + export interface StartOrEnd { line: number; col: number; } + + + /////////////////// diff --git a/server/src/server.ts b/server/src/server.ts index 89ad54f06f9404cbb631dacb3deeb45cf32e81dd..d8494d2f6d7e9114617282ea05b42303e4ae2356 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -19,7 +19,7 @@ import { import { URI } from 'vscode-uri'; import * as fs from 'fs'; -import { NDJSON, readErrors, matchErrors } from './errorHandler'; +import { NDJSON, readErrors, matchErrors, buildErrors } from './errorHandler'; import * as wordComplition from './wordCompletion' import * as path from 'path'; import * as URL from 'url' @@ -167,7 +167,7 @@ documents.onDidChangeContent(change => { }); - +let issueTracker : Map<string, Array<string>> = new Map() async function validateTextDocument(textDocument: TextDocument): Promise<void> { @@ -178,7 +178,7 @@ async function validateTextDocument(textDocument: TextDocument): Promise<void> { let errorDic : string = documentPath.dir + '/tmp' let errorPath: string = errorDic + '/_error.json' - + const { exec } = require('child_process'); if (!fs.existsSync(errorDic)){ @@ -186,55 +186,56 @@ async function validateTextDocument(textDocument: TextDocument): Promise<void> { } - fs.writeFile(errorPath, "", () => { }) //Insure a clean error file - //fs.writeFileSync(errorPath,"",{encoding:'utf8',flag:'w'}) + if(!issueTracker.has(textDocument.uri)){ //ensure that position is always initalised + issueTracker.set(textDocument.uri, new Array()) + } + + fs.writeFileSync(errorPath,"",{encoding:'utf8',flag:'w'}) let command: string = getCommand(URI.parse(textDocument.uri).path, errorPath, settings) -// console.log(command) + + if (correctPath(settings.probHome)) { exec(command, (err: string, stdout: string, stderr: string) => { - let errorMap: Promise<Map<string, Set<NDJSON>>> = readErrors(errorPath) - errorMap.then(function (result: Map<string, Set<NDJSON>>) { + let errorLines : Promise<Array<string>> = readErrors(errorPath) - let diagnostics: Array<Diagnostic> = new Array() - if(result.size != 0) - { - let mainFileWritten : boolean = false; - for (let entry of result) { - if (entry[0] == textDocument.uri) { - diagnostics = matchErrors(entry[1], textDocument) - } else { - diagnostics = matchErrors(entry[1]) - } - - connection.sendDiagnostics({ uri: entry[0], diagnostics }); - - /** - * TL;DR we need to cast here to clean the main file - * - * This is a little bit of a mess here: Problem the paths in the _error.json a system relevant - * and system centered e.g. /home/sebastian... - * - * The URI from the textdocument is domain centered e.g. file///home/sebastian in order to deal - * with remote files like serverXYZ///home/michael - * - * However the extension.ts can deal with system centric paths and uris, but we need a comparision - * so we have to cast here... - */ - if(URI.parse(entry[0]).toString() == textDocument.uri){ - mainFileWritten = true - } - } + errorLines.then(function (result: Array<string>) { + + let allFilesAndCorrespondingErrors : Map<string, Set<NDJSON>> = buildErrors(result); + let filesWithProblemms : Array<string> = Array.from(allFilesAndCorrespondingErrors.keys()) - if(mainFileWritten == false){ - // The main file has no errors, we need to reset it... - diagnostics = new Array() - connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); + for(let dependency of allFilesAndCorrespondingErrors.keys()) + { + console.log(dependency) + console.log(documentPath.dir+documentPath.name+documentPath.ext) + if(dependency == (documentPath.dir+documentPath.name+documentPath.ext)){ + console.log("is:main") + let errors : Set<NDJSON> = allFilesAndCorrespondingErrors.get(dependency)!! + console.log("errors " + errors) + let diagnostics = matchErrors(errors, textDocument) + connection.sendDiagnostics({ uri: dependency, diagnostics }); + }else{ + console.log("is:dep") + let errors : Set<NDJSON> = allFilesAndCorrespondingErrors.get(dependency)!! + let diagnostics = matchErrors(errors) + console.log("errors " + errors) + connection.sendDiagnostics({ uri: dependency, diagnostics }); } } - else{ - connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); + + let filesToReset : Array<string> = issueTracker.get(textDocument.uri)!.filter(function(obj) { return filesWithProblemms.indexOf(obj) == -1; }); + + for(let dependency of filesToReset) + { + console.log("reset:errrors") + let diagnostics : Array<Diagnostic> = new Array() + connection.sendDiagnostics({ uri: dependency, diagnostics }); } + + issueTracker.set(textDocument.uri, Array.from(allFilesAndCorrespondingErrors.keys())) + + + }, function (err) { connection.sendNotification("parse_error_prob", "there are things wrong with the parse results " + err) });