From 1cec184e041c2e23fd7dc7e2aeb6f8239f28bbcb Mon Sep 17 00:00:00 2001 From: Noah Santschi-Cooney Date: Fri, 20 Jul 2018 22:05:59 +0100 Subject: [PATCH] Added postError function for short error notifications. Using existsSync to check if binary exists. Seperated onConfigChange into different functions. lineNum -2 for windows instead of -1 for linux, such a pain. --- server/src/config.ts | 97 +++++++++++++++++++++++--------------------- server/src/linter.ts | 16 +++++--- server/src/server.ts | 7 +--- server/src/utils.ts | 6 +++ 4 files changed, 69 insertions(+), 57 deletions(-) create mode 100644 server/src/utils.ts diff --git a/server/src/config.ts b/server/src/config.ts index d942f7a..95e66fa 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -1,10 +1,9 @@ import { connection, documents, onEvent } from './server' -import { exec, execSync } from 'child_process' -import { extname } from 'path' import fetch from 'node-fetch' import { platform } from 'os' -import { createWriteStream, chmodSync, createReadStream, unlinkSync } from 'fs' +import { createWriteStream, chmodSync, createReadStream, unlinkSync, existsSync } from 'fs' import * as unzip from 'unzip' +import { postError } from './utils' const url = { 'win32': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-windows-x64-Release.zip', @@ -17,55 +16,61 @@ export interface Config { readonly glslangPath: string } -export let conf: Partial = {} +export let conf: Config = {shaderpacksPath: '', glslangPath: ''} export const onConfigChange = async (change) => { const temp = change.settings.mcglsl as Config conf = {shaderpacksPath: temp['shaderpacksPath'], glslangPath: temp['glslangValidatorPath']} + + if (existsSync(conf.glslangPath)) { + documents.all().forEach(onEvent) + } else { + promptDownloadGlslang() + } +} + +async function promptDownloadGlslang() { + const chosen = await connection.window.showErrorMessage( + `[mc-glsl] glslangValidator not found at: '${conf.glslangPath}'.`, + {title: 'Download'}, + {title: 'Cancel'} + ) + + if (!chosen || chosen.title !== 'Download') return + + if (conf.shaderpacksPath === '') { + connection.window.showErrorMessage('Please set mcglsl.shaderpacksPath as this is where glslangValidator will be saved to.') + return + } + + downloadGlslang() +} + +async function downloadGlslang() { + const res = await fetch(url[platform()]) + try { - execSync(conf.glslangPath) - documents.all().forEach(document => onEvent) - } catch (e) { - if (e.status !== 1) { - const chosen = await connection.window.showErrorMessage( - `[mc-glsl] glslangValidator not found at: '${conf.glslangPath}' or returned non-0 code`, - {title: 'Download'}, - {title: 'Cancel'} - ) + const zip = createWriteStream(conf.shaderpacksPath + '/glslangValidator.zip') + res.body.pipe(zip) - if (!chosen || chosen.title !== 'Download') return - - if (conf.shaderpacksPath === '') { - connection.window.showErrorMessage('Please set mcglsl.shaderpacksPath') - return - } - - const res = await fetch(url[platform()]) - - try { - const zip = createWriteStream(conf.shaderpacksPath + '/glslangValidator.zip') - res.body.pipe(zip) - - zip.on('finish', async () => { - createReadStream(conf.shaderpacksPath + '/glslangValidator.zip') - .pipe(unzip.Parse()) - .on('entry', (entry) => { - if (entry.path === 'bin/glslangValidator') { - entry.pipe(createWriteStream(conf.shaderpacksPath + '/glslangValidator')) - return - } - entry.autodrain() - }) - .on('close', () => { - chmodSync(conf.shaderpacksPath + '/glslangValidator', 0o775) - unlinkSync(conf.shaderpacksPath + '/glslangValidator.zip') - connection.sendNotification('update-config', conf.shaderpacksPath + '/glslangValidator') - connection.window.showInformationMessage('glslangValidator has been downloaded to ' + conf.shaderpacksPath + '/glslangValidator') - }) + zip.on('finish', async () => { + createReadStream(conf.shaderpacksPath + '/glslangValidator.zip') + .pipe(unzip.Parse()) + .on('entry', entry => { + if (entry.path === 'bin/glslangValidator') { + entry.pipe(createWriteStream(conf.shaderpacksPath + '/glslangValidator')) + return + } + entry.autodrain() }) - } catch (e) { - connection.window.showErrorMessage(e.message) - } - } + .on('close', () => { + chmodSync(conf.shaderpacksPath + '/glslangValidator', 0o775) + unlinkSync(conf.shaderpacksPath + '/glslangValidator.zip') + connection.sendNotification('update-config', conf.shaderpacksPath + '/glslangValidator') + connection.window.showInformationMessage('glslangValidator has been downloaded to ' + conf.shaderpacksPath + '/glslangValidator') + }) + }) + } catch (e) { + postError(e) } } \ No newline at end of file diff --git a/server/src/linter.ts b/server/src/linter.ts index b7d835a..d4aec1c 100644 --- a/server/src/linter.ts +++ b/server/src/linter.ts @@ -1,23 +1,27 @@ -import { TextDocument, Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver' +import { Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver' import { connection, documents } from './server' import { execSync } from 'child_process' import * as path from 'path' import { readFileSync, existsSync } from 'fs' import { conf } from './config' +import { postError } from './utils' +import { platform } from 'os' -const reDiag = /^(ERROR|WARNING): ([^?<>:*|"]+?):(\d+): (?:'.*?' : )?(.+)$/ +const reDiag = /^(ERROR|WARNING): ([^?<>:*|"]+?):(\d+): (?:'.*?' : )?(.+)[\r\n|\n]/ const reVersion = /#version [\d]{3}/ const reInclude = /^(?:\s)*?(?:#include) "((?:\/?[^?<>:*|"]+?)+?\.(?:[a-zA-Z]+?))"$/ const reIncludeExt = /#extension GL_GOOGLE_include_directive ?: ?require/ const include = '#extension GL_GOOGLE_include_directive : require' +const win = platform() === 'win32' const filters = [ + /stdin/, /(No code generated)/, /(compilation terminated)/, /Could not process include directive for header name:/ ] -const files = new Map() +const includeToParent = new Map() type IncludeObj = { lineNum: number, @@ -98,7 +102,7 @@ export function preprocess(lines: string[], docURI: string) { try { lint(docURI, lines, includeMap, diagnostics) } catch (e) { - console.log(e) + postError(e) } } @@ -180,6 +184,7 @@ function mergeInclude(inc: IncludeObj, lines: string[], incStack: string[], diag // add #line indicating we are entering a new include block lines[inc.lineNumTopLevel] = `#line 0 "${inc.path}"` // merge the lines of the file into the current document + // TODO do we wanna use a DLL here? lines.splice(inc.lineNumTopLevel + 1, 0, ...dataLines) // add the closing #line indicating we're re-entering a block a level up lines.splice(inc.lineNumTopLevel + 1 + dataLines.length, 0, `#line ${inc.lineNum} "${inc.parent}"`) @@ -205,7 +210,8 @@ function lint(uri: string, lines: string[], includes: Map, d let diag: Diagnostic = { severity: errorType(type), - range: calcRange(parseInt(line) - 1, file.length - 1 ? file : uri), + // had to do - 2 here instead of - 1, windows only perhaps? + range: calcRange(parseInt(line) - (win ? 2 : 1), file.length - 1 ? file : uri), message: replaceWord(msg), source: 'mc-glsl' } diff --git a/server/src/server.ts b/server/src/server.ts index 14a25c6..aa67a69 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -2,17 +2,12 @@ import * as vsclang from 'vscode-languageserver' import * as vsclangproto from 'vscode-languageserver-protocol' import { completions } from './completionProvider' import { preprocess, ext, formatURI } from './linter' -import { exec, execSync } from 'child_process' import { extname } from 'path' -import fetch from 'node-fetch' -import { platform } from 'os' -import { createWriteStream, chmodSync, createReadStream, unlinkSync } from 'fs' -import * as unzip from 'unzip' export let connection: vsclang.IConnection connection = vsclang.createConnection(new vsclang.IPCMessageReader(process), new vsclang.IPCMessageWriter(process)) -import { Config, onConfigChange } from './config' +import { onConfigChange } from './config' export const documents = new vsclang.TextDocuments() documents.listen(connection) diff --git a/server/src/utils.ts b/server/src/utils.ts new file mode 100644 index 0000000..6bc310f --- /dev/null +++ b/server/src/utils.ts @@ -0,0 +1,6 @@ +import { connection } from './server' + +export function postError(e: Error) { + connection.window.showErrorMessage(e.message) + console.log(e) +} \ No newline at end of file