Skip to content
Snippets Groups Projects
Commit 0326a091 authored by SeeBasTStick's avatar SeeBasTStick
Browse files

added new way to deal with errors

parent 1a17cf82
Branches
Tags
No related merge requests found
...@@ -2206,9 +2206,9 @@ ...@@ -2206,9 +2206,9 @@
} }
}, },
"vscode-uri": { "vscode-uri": {
"version": "2.1.1", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.1.tgz", "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz",
"integrity": "sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A==" "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A=="
}, },
"which": { "which": {
"version": "2.0.2", "version": "2.0.2",
......
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
"stream-to-array": "^2.3.0", "stream-to-array": "^2.3.0",
"ts-xor": "^1.0.8", "ts-xor": "^1.0.8",
"vscode-api": "0.0.0", "vscode-api": "0.0.0",
"vscode-uri": "^2.1.1", "vscode-uri": "^2.1.2",
"without": "^1.2.3" "without": "^1.2.3"
} }
} }
import { Diagnostic, DiagnosticSeverity } from 'vscode-languageserver'
import { TextDocument, Position } from 'vscode-languageserver-textdocument'
import * as fs from 'fs';
import * as readline from 'readline'
import { Uri } from 'vscode';
export class ErrorMatcher {
/**
* 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
*/
async readErrors(errorPath : string) : Promise<Map<Uri, Set<Error | Warning | Information>>> {
let result : Map<Uri, Set<Error | Warning | Information>> = new Map()
var stream = fs.createReadStream(errorPath)
const rl = readline.createInterface({
input: stream,
crlfDelay: Infinity
});
type ErrorInfromationWarning = Error | Information | Warning
for await (const line of rl) {
let obj: ErrorInfromationWarning = JSON.parse(line)
let serveity: DiagnosticSeverity
let content: JBody
let path : Uri
if (isError(obj)) {
path = Uri.parse(obj.error.file)
}
else {
if (isWarning(obj)) {
path = Uri.parse(obj.warning.file)
} else {
path = Uri.parse(obj.information.file)
}
}
if(!result.has(path)){
result.set(path, new Set())
}
result.get(path)!.add(obj)
}
return result
}
matchErrors(infos : Set<Error | Information | Warning>) : Set<Diagnostic>{
let result : Set<Diagnostic>
type ErrorInfromationWarning = Error | Information | Warning
for (let info : ErrorInfromationWarning in infos){
let serveity : DiagnosticSeverity
if(isError(info)){
serveity = DiagnosticSeverity.Error
}else{
if(isWarning(info)){
serveity = DiagnosticSeverity.Warning
}else{
serveity = DiagnosticSeverity.Warning
}}
let diagnostic = {
severity: serveity,
range: {
start:
{
character: in.start.col,
line: content.start.line - 1
},
end: {
character: content.end.col,
line: content.end.line - 1
}
},
message: content.message,
source: 'prob_prolog',
};
diagnostics.add(diagnostic)
}
)
}
async matchError(target: TextDocument, errorPath: string): Promise<Set<Diagnostic>> {
var diagnostics: Set<Diagnostic> = new Set()
var stream = fs.createReadStream(errorPath)
const rl = readline.createInterface({
input: stream,
crlfDelay: Infinity
});
for await (const line of rl) {
try {
let obj: XOR3<Error, Warning, Information> = JSON.parse(line)
let diagnostic: Diagnostic
let serveity: DiagnosticSeverity
let content: JBody
if (obj.error) {
content = obj.error
serveity = DiagnosticSeverity.Error
}
else {
if (obj.warning) {
content = obj.warning
serveity = DiagnosticSeverity.Warning
} else {
content = obj.information
serveity = DiagnosticSeverity.Information
}
}
if(content.start.line == -1 && content.start.col == -1 && content.end.line == -1 && content.end.col == -1){
console.log("Error without position")
let targetLine = getFirstOccurence(target).line
console.log("new pos is: " + targetLine)
content.start = {line : targetLine , col: 0 }
content.end = {line : targetLine , col: Number.MAX_VALUE }
}
diagnostic = {
severity: serveity,
range: {
start:
{
character: content.start.col,
line: content.start.line - 1
},
end: {
character: content.end.col,
line: content.end.line - 1
}
},
message: content.message,
source: 'prob_prolog',
};
diagnostics.add(diagnostic)
}
catch (e) {
throw new Error("unexpected syntax while parsing _error.json")
}
}
return diagnostics
}
}
export declare type XOR3<T, U, V> = (T | U | V) extends object ? ((Without<T, U> & U) & (Without<V, U> & U)) |
((Without<V, T> & T) & (Without<U, T> & T)) |
((Without<T, V> & V) & (Without<U, V> & V)) : T | U | V;
export declare type Without<T, U> = {
[P in Exclude<keyof T, keyof U>]?: never;
};
export interface CommonInfo{}
export interface Information extends CommonInfo {
information : JBody
}
export interface Error extends CommonInfo {
error: JBody;
}
export interface Warning extends CommonInfo{
warning: JBody
}
export interface JBody {
message: string;
type: string;
file: string;
start: StartOrEnd;
end: StartOrEnd;
}
export interface StartOrEnd {
line: number;
col: number;
}
function getFirstOccurence(textdocument : TextDocument) : Position {
let counter : number = textdocument.getText().search(/\S|$/)
let pos : Position = textdocument.positionAt(counter)
pos.line = pos.line + 1
return pos
}
function isError (potential : CommonInfo) : potential is Error{
if((potential as Error).error){
return true
}else{
return false
}
}
function isWarning (potential : CommonInfo) : potential is Warning{
if((potential as Warning).warning){
return true
}else{
return false
}
}
function isInformation (potential : CommonInfo) : potential is Information{
if((potential as Information).information){
return true
}else{
return false
}
}
\ No newline at end of file
import { Diagnostic, DiagnosticSeverity } from 'vscode-languageserver'
import { TextDocument, Position } from 'vscode-languageserver-textdocument'
import * as fs from 'fs';
import * as readline from 'readline'
import { Uri } from 'vscode';
/**
* 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()
var stream = fs.createReadStream(errorPath)
const rl = readline.createInterface({
input: stream,
crlfDelay: Infinity
});
for await (const line of rl) {
let obj: NDJSON = JSON.parse(line)
let path: string = obj.details.file
if (!result.has(path)) {
result.set(path, new Set())
}
result.get(path)!.add(obj)
}
return result
}
/**
* Builds diagnostics for a given Set of infos
* @param infos the set of infos to build diagnostics with
*/
export function matchErrors(infos: Set<NDJSON>, file?: TextDocument | undefined): Array<Diagnostic> {
let result: Array<Diagnostic> = new Array()
for (var info of infos) {
let serveity: DiagnosticSeverity = DiagnosticSeverity.Error
if (info.type == "error") {
serveity = DiagnosticSeverity.Error
}
if (info.type == "warning") {
serveity = DiagnosticSeverity.Warning
}
if (info.type == "information") {
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 (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 }
} else {
//Fallback if an error occurs on differnt document
content.start = { line: 1, col: 0 }
content.end = { line: 1, col: Number.MAX_VALUE }
}
}
let diagnostic = {
severity: serveity,
range: {
start:
{
character: content.start.col,
line: content.start.line - 1
},
end: {
character: content.end.col,
line: content.end.line - 1
}
},
message: content.message,
source: 'prob_prolog',
};
result.push(diagnostic)
}
return result
}
////////////// Representation of the NDJSON File
export interface NDJSON {
type: string
details: JBody
}
export interface JBody {
message: string;
type: string;
file: string;
start: StartOrEnd;
end: StartOrEnd;
}
export interface StartOrEnd {
line: number;
col: number;
}
///////////////////
/**
* Returns the exakt positiion of the first occurence of an non whitespace token
* @param textdocument the Textdocument to analzie
*/
function getFirstOccurence(textdocument: TextDocument): Position {
let counter: number = textdocument.getText().search(/\S|$/)
let pos: Position = textdocument.positionAt(counter)
pos.line = pos.line + 1
return pos
}
...@@ -9,7 +9,6 @@ import { ...@@ -9,7 +9,6 @@ import {
TextDocumentPositionParams, TextDocumentPositionParams,
TextDocumentSyncKind, TextDocumentSyncKind,
InitializeResult, InitializeResult,
TextDocumentItem,
} from 'vscode-languageserver'; } from 'vscode-languageserver';
...@@ -18,14 +17,9 @@ import { ...@@ -18,14 +17,9 @@ import {
} from 'vscode-languageserver-textdocument'; } from 'vscode-languageserver-textdocument';
import {Proposed} from 'vscode-languageserver-protocol'
import { URI } from 'vscode-uri'; import { URI } from 'vscode-uri';
import * as fs from 'fs'; import * as fs from 'fs';
import {ErrorMatcher} from './ErrorMatcher'; import { NDJSON, readErrors, matchErrors } from './errorHandler';
import * as wordComplition from './wordCompletion' import * as wordComplition from './wordCompletion'
import * as path from 'path'; import * as path from 'path';
...@@ -34,7 +28,6 @@ import * as path from 'path'; ...@@ -34,7 +28,6 @@ import * as path from 'path';
// Create a connection for the server. The connection uses Node's IPC as a transport. // Create a connection for the server. The connection uses Node's IPC as a transport.
// Also include all preview / proposed LSP features. // Also include all preview / proposed LSP features.
let connection = createConnection(ProposedFeatures.all); let connection = createConnection(ProposedFeatures.all);
let test = createConnection(ProposedFeatures.all)
// Create a simple text document manager. The text document manager // Create a simple text document manager. The text document manager
// supports full document sync only // supports full document sync only
...@@ -171,7 +164,6 @@ documents.onDidSave(change => { ...@@ -171,7 +164,6 @@ documents.onDidSave(change => {
async function validateTextDocument(textDocument: TextDocument): Promise<void> { async function validateTextDocument(textDocument: TextDocument): Promise<void> {
let settings = await getDocumentSettings(textDocument.uri) // Waiting for correct setting; otherwise allways default let settings = await getDocumentSettings(textDocument.uri) // Waiting for correct setting; otherwise allways default
let documentPath: path.ParsedPath = path.parse(URI.parse(textDocument.uri).path); let documentPath: path.ParsedPath = path.parse(URI.parse(textDocument.uri).path);
let errorPath: string = documentPath.dir + '/_error.json' let errorPath: string = documentPath.dir + '/_error.json'
...@@ -182,32 +174,39 @@ async function validateTextDocument(textDocument: TextDocument): Promise<void> { ...@@ -182,32 +174,39 @@ async function validateTextDocument(textDocument: TextDocument): Promise<void> {
let command: string = getCommand(URI.parse(textDocument.uri).path, errorPath, settings) 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 diagnostics: Array<Diagnostic> = new Array() let diagnostics: Array<Diagnostic> = new Array()
let diagnosticsPromise : Promise<Set<Diagnostic>>
console.log(command) for (let entry of result) {
if(correctPath(settings.probHome)) if (entry[0] == textDocument.uri) {
{ diagnostics = matchErrors(entry[1], textDocument)
exec(command, (err:string, stdout:string, stderr:string) => { } else {
let bla = new ErrorMatcher() diagnostics = matchErrors(entry[1])
diagnosticsPromise = bla.matchError(textDocument, errorPath) }
console.log("sending to " + entry[0])
connection.sendDiagnostics({ uri: entry[0], diagnostics });
}
diagnosticsPromise.then(function(result:Set<Diagnostic>){
diagnostics = Array.from(result)
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics});
}, function (err) { }, function (err) {
connection.sendNotification("parse_error_prob", "there are things wrong with the parse results " + err) connection.sendNotification("parse_error_prob", "there are things wrong with the parse results " + err)
})
}); });
})
} }
} }
function getCommand(documentPath: string, errorPath: string, settings: Settings): string { function getCommand(documentPath: string, errorPath: string, settings: Settings): string {
let wdCmd = "" let wdCmd = ""
let strict = "" let strict = ""
let perf = "" let perf = ""
console.log(documentPath) // console.log(documentPath)
//PYTHONVAR //PYTHONVAR
if (settings.wdChecks == true) { if (settings.wdChecks == true) {
......
{ {
"compilerOptions": { "compilerOptions": {
"esModuleInterop": true,
"module": "commonjs", "module": "commonjs",
"target": "es6", "target": "es6",
"outDir": "out", "outDir": "out",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment