From d7a5adb668e18b18732deb31fa3634c87f0b72d0 Mon Sep 17 00:00:00 2001 From: Noah Santschi-Cooney Date: Mon, 2 Jul 2018 18:56:17 +0100 Subject: [PATCH] Recursive includes works 90%!!!!! Wrong line numbers are given because its basing the line numbers off the root file --- .vscode/launch.json | 2 +- server/src/linter.ts | 80 +++++++++++++++++++++++--------------------- server/src/server.ts | 36 +++++++++----------- 3 files changed, 58 insertions(+), 60 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 133a149..74b815f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "stopOnEntry": false, "sourceMaps": true, "outFiles": ["${workspaceRoot}/client/out/**/*.js"], - "preLaunchTask": "watch" + "preLaunchTask": "watch", }, { "type": "node", diff --git a/server/src/linter.ts b/server/src/linter.ts index 78c1853..1f2c4e8 100644 --- a/server/src/linter.ts +++ b/server/src/linter.ts @@ -1,7 +1,7 @@ -import { conf, connection, documents, checkBinary } from './server' +import { conf, connection, documents } from './server' import './global' import { TextDocument, Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver' -import { exec } from 'child_process' +import { execSync } from 'child_process' import * as path from 'path' import { readFileSync } from 'fs' @@ -52,9 +52,8 @@ const tokens: {[key: string]: string} = { 'RIGHT_BRACE': '}' } -export function preprocess(document: TextDocument, topLevel: boolean, incStack: string[]) { - const lines = document.getText().split('\n') - const docURI = formatURI(document.uri) +// TODO exclude exts not in ext +export function preprocess(lines: string[], docURI: string, topLevel: boolean, incStack: string[]) { if (topLevel) { let inComment = false for (let i = 0; i < lines.length; i++) { @@ -84,13 +83,20 @@ export function preprocess(document: TextDocument, topLevel: boolean, incStack: lines.splice(inc.lineNum + 1 + addedLines + i, 0, ...dataLines) addedLines += dataLines.length lines.splice(inc.lineNum + 1 + addedLines + i, 0, `#line ${inc.lineNum} "${docURI}"`) + preprocess(lines, incPath, false, incStack) }) } - console.log(lines.join('\n')) - lint(docURI, lines, includes) + + if (!topLevel) return + + //console.log(lines.join('\n')) + try { + lint(docURI, lines, includes) + } catch (e) { + } } -const formatURI = (uri: string) => uri.replace(/^file:\/\//, '') +export const formatURI = (uri: string) => uri.replace(/^file:\/\//, '') //TODO not include in comments const getIncludes = (lines: string[]) => lines @@ -107,45 +113,43 @@ function absPath(currFile: string, includeFile: string): string { if (includeFile.charAt(0) === '/') { const shaderPath = currFile.replace(conf.shaderpacksPath, '').split('/').slice(0, 3).join('/') return path.join(conf.shaderpacksPath, shaderPath, includeFile) - } else { - const shaderPath = path.dirname(currFile) - return path.join(shaderPath, includeFile) } + return path.join(path.dirname(currFile), includeFile) } function lint(uri: string, lines: string[], includes: {lineNum: number, match: RegExpMatchArray}[]) { - checkBinary( - () => { - const child = exec(`${conf.glslangPath} --stdin -S ${ext[path.extname(uri)]}`, (error, out) => { - const diagnostics: {[uri: string]: Diagnostic[]} = {} - diagnostics[uri] = [] - includes.forEach(obj => { - diagnostics[absPath(uri, obj.match[1])] = [] - }) + console.log(lines.join('\n')) + let out: string = '' + try { + execSync(`${conf.glslangPath} --stdin -S ${ext[path.extname(uri)]}`, {input: lines.join('\n')}) + } catch (e) { + out = e.stdout.toString() + } - const matches = filterMatches(out) as RegExpMatchArray[] - matches.forEach((match) => { - const [whole, type, file, line, msg] = match - const diag = { - severity: type === 'ERROR' ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning, - range: calcRange(parseInt(line) - 1, uri), - message: replaceWord(msg), - source: 'mc-glsl' - } - diagnostics[file].push(diag) - }) + const diagnostics: {[uri: string]: Diagnostic[]} = {} + diagnostics[uri] = [] + includes.forEach(obj => { + diagnostics[absPath(uri, obj.match[1])] = [] + }) - daigsArray(diagnostics).forEach(d => { - connection.sendDiagnostics({uri: 'file://' + d.uri, diagnostics: d.diag}) - }) - }) - lines.forEach(line => child.stdin.write(line)) - child.stdin.end() + const matches = filterMatches(out) + matches.forEach((match) => { + const [whole, type, file, line, msg] = match + const diag = { + severity: type === 'ERROR' ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning, + range: calcRange(parseInt(line) - 1, uri), + message: replaceWord(msg), + source: 'mc-glsl' } - ) + diagnostics[file ? uri : file].push(diag) + }) + + daigsArray(diagnostics).forEach(d => { + connection.sendDiagnostics({uri: d.uri, diagnostics: d.diag}) + }) } -const daigsArray = (diags: {[uri: string]: Diagnostic[]}) => Object.keys(diags).map(uri => ({uri, diag: diags[uri]})) +const daigsArray = (diags: {[uri: string]: Diagnostic[]}) => Object.keys(diags).map(uri => ({uri: 'file://' + uri, diag: diags[uri]})) const filterMatches = (output: string) => output .split('\n') diff --git a/server/src/server.ts b/server/src/server.ts index 6ea74e0..51a2afe 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -1,9 +1,9 @@ import * as vsclang from 'vscode-languageserver' -import { TextDocumentChangeEvent } from 'vscode-languageserver-protocol' +import { TextDocumentChangeEvent, TextDocument } from 'vscode-languageserver-protocol' import { Config } from './config' import { completions } from './completionProvider' -import { preprocess, ext } from './linter' -import { exec } from 'child_process' +import { preprocess, ext, formatURI } from './linter' +import { exec, execSync } from 'child_process' import { extname } from 'path' export const connection = vsclang.createConnection(new vsclang.IPCMessageReader(process), new vsclang.IPCMessageWriter(process)) @@ -26,33 +26,27 @@ connection.onInitialize((params): vsclang.InitializeResult => { connection.onExit(() => {}) -documents.onDidOpen(onEvent) +documents.onDidOpen((event) => onEvent(event.document)) -documents.onDidSave(onEvent) +documents.onDidSave((event) => onEvent(event.document)) //documents.onDidChangeContent(onEvent) -function onEvent(event: TextDocumentChangeEvent) { - preprocess(event.document, true, [event.document.uri.replace(/^file:\/\//, '')]) -} - -export function checkBinary(ok: () => void, fail?: () => any) { - exec(conf.glslangPath, (error) => { - if (error['code'] !== 1) { - if (fail) fail() - return - } - ok() - }) +function onEvent(document: TextDocument) { + preprocess(document.getText().split('\n'), formatURI(document.uri), true, [document.uri.replace(/^file:\/\//, '')]) } connection.onDidChangeConfiguration((change) => { const temp = change.settings.mcglsl as Config conf = new Config(temp['shaderpacksPath'], temp['glslangValidatorPath']) - checkBinary( - () => {documents.all().forEach(document => preprocess(document, true, [document.uri.replace(/^file:\/\//, '')]))}, - () => {connection.window.showErrorMessage(`[mc-glsl] glslangValidator not found at: ${conf.glslangPath}`)} - ) + try { + execSync(conf.glslangPath) + documents.all().forEach(document => onEvent(document)) + } catch (e) { + if (e.status !== 1) { + connection.window.showErrorMessage(`[mc-glsl] glslangValidator not found at: '${conf.glslangPath}' or returned non-0 code`) + } + } }) connection.onCompletion((textDocumentPosition: vsclang.TextDocumentPositionParams) => completions)