mirror of
https://github.com/Strum355/mcshader-lsp.git
synced 2025-07-22 18:55:29 +00:00
Recursive includes works 90%!!!!! Wrong line numbers are given because its basing the line numbers off the root file
This commit is contained in:
parent
d2e58f475d
commit
d7a5adb668
3 changed files with 58 additions and 60 deletions
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
@ -11,7 +11,7 @@
|
||||||
"stopOnEntry": false,
|
"stopOnEntry": false,
|
||||||
"sourceMaps": true,
|
"sourceMaps": true,
|
||||||
"outFiles": ["${workspaceRoot}/client/out/**/*.js"],
|
"outFiles": ["${workspaceRoot}/client/out/**/*.js"],
|
||||||
"preLaunchTask": "watch"
|
"preLaunchTask": "watch",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { conf, connection, documents, checkBinary } from './server'
|
import { conf, connection, documents } from './server'
|
||||||
import './global'
|
import './global'
|
||||||
import { TextDocument, Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver'
|
import { TextDocument, Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver'
|
||||||
import { exec } from 'child_process'
|
import { execSync } from 'child_process'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import { readFileSync } from 'fs'
|
import { readFileSync } from 'fs'
|
||||||
|
|
||||||
|
@ -52,9 +52,8 @@ const tokens: {[key: string]: string} = {
|
||||||
'RIGHT_BRACE': '}'
|
'RIGHT_BRACE': '}'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function preprocess(document: TextDocument, topLevel: boolean, incStack: string[]) {
|
// TODO exclude exts not in ext
|
||||||
const lines = document.getText().split('\n')
|
export function preprocess(lines: string[], docURI: string, topLevel: boolean, incStack: string[]) {
|
||||||
const docURI = formatURI(document.uri)
|
|
||||||
if (topLevel) {
|
if (topLevel) {
|
||||||
let inComment = false
|
let inComment = false
|
||||||
for (let i = 0; i < lines.length; i++) {
|
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)
|
lines.splice(inc.lineNum + 1 + addedLines + i, 0, ...dataLines)
|
||||||
addedLines += dataLines.length
|
addedLines += dataLines.length
|
||||||
lines.splice(inc.lineNum + 1 + addedLines + i, 0, `#line ${inc.lineNum} "${docURI}"`)
|
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
|
//TODO not include in comments
|
||||||
const getIncludes = (lines: string[]) => lines
|
const getIncludes = (lines: string[]) => lines
|
||||||
|
@ -107,45 +113,43 @@ function absPath(currFile: string, includeFile: string): string {
|
||||||
if (includeFile.charAt(0) === '/') {
|
if (includeFile.charAt(0) === '/') {
|
||||||
const shaderPath = currFile.replace(conf.shaderpacksPath, '').split('/').slice(0, 3).join('/')
|
const shaderPath = currFile.replace(conf.shaderpacksPath, '').split('/').slice(0, 3).join('/')
|
||||||
return path.join(conf.shaderpacksPath, shaderPath, includeFile)
|
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}[]) {
|
function lint(uri: string, lines: string[], includes: {lineNum: number, match: RegExpMatchArray}[]) {
|
||||||
checkBinary(
|
console.log(lines.join('\n'))
|
||||||
() => {
|
let out: string = ''
|
||||||
const child = exec(`${conf.glslangPath} --stdin -S ${ext[path.extname(uri)]}`, (error, out) => {
|
try {
|
||||||
const diagnostics: {[uri: string]: Diagnostic[]} = {}
|
execSync(`${conf.glslangPath} --stdin -S ${ext[path.extname(uri)]}`, {input: lines.join('\n')})
|
||||||
diagnostics[uri] = []
|
} catch (e) {
|
||||||
includes.forEach(obj => {
|
out = e.stdout.toString()
|
||||||
diagnostics[absPath(uri, obj.match[1])] = []
|
}
|
||||||
})
|
|
||||||
|
|
||||||
const matches = filterMatches(out) as RegExpMatchArray[]
|
const diagnostics: {[uri: string]: Diagnostic[]} = {}
|
||||||
matches.forEach((match) => {
|
diagnostics[uri] = []
|
||||||
const [whole, type, file, line, msg] = match
|
includes.forEach(obj => {
|
||||||
const diag = {
|
diagnostics[absPath(uri, obj.match[1])] = []
|
||||||
severity: type === 'ERROR' ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning,
|
})
|
||||||
range: calcRange(parseInt(line) - 1, uri),
|
|
||||||
message: replaceWord(msg),
|
|
||||||
source: 'mc-glsl'
|
|
||||||
}
|
|
||||||
diagnostics[file].push(diag)
|
|
||||||
})
|
|
||||||
|
|
||||||
daigsArray(diagnostics).forEach(d => {
|
const matches = filterMatches(out)
|
||||||
connection.sendDiagnostics({uri: 'file://' + d.uri, diagnostics: d.diag})
|
matches.forEach((match) => {
|
||||||
})
|
const [whole, type, file, line, msg] = match
|
||||||
})
|
const diag = {
|
||||||
lines.forEach(line => child.stdin.write(line))
|
severity: type === 'ERROR' ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning,
|
||||||
child.stdin.end()
|
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
|
const filterMatches = (output: string) => output
|
||||||
.split('\n')
|
.split('\n')
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as vsclang from 'vscode-languageserver'
|
import * as vsclang from 'vscode-languageserver'
|
||||||
import { TextDocumentChangeEvent } from 'vscode-languageserver-protocol'
|
import { TextDocumentChangeEvent, TextDocument } from 'vscode-languageserver-protocol'
|
||||||
import { Config } from './config'
|
import { Config } from './config'
|
||||||
import { completions } from './completionProvider'
|
import { completions } from './completionProvider'
|
||||||
import { preprocess, ext } from './linter'
|
import { preprocess, ext, formatURI } from './linter'
|
||||||
import { exec } from 'child_process'
|
import { exec, execSync } from 'child_process'
|
||||||
import { extname } from 'path'
|
import { extname } from 'path'
|
||||||
|
|
||||||
export const connection = vsclang.createConnection(new vsclang.IPCMessageReader(process), new vsclang.IPCMessageWriter(process))
|
export const connection = vsclang.createConnection(new vsclang.IPCMessageReader(process), new vsclang.IPCMessageWriter(process))
|
||||||
|
@ -26,33 +26,27 @@ connection.onInitialize((params): vsclang.InitializeResult => {
|
||||||
|
|
||||||
connection.onExit(() => {})
|
connection.onExit(() => {})
|
||||||
|
|
||||||
documents.onDidOpen(onEvent)
|
documents.onDidOpen((event) => onEvent(event.document))
|
||||||
|
|
||||||
documents.onDidSave(onEvent)
|
documents.onDidSave((event) => onEvent(event.document))
|
||||||
|
|
||||||
//documents.onDidChangeContent(onEvent)
|
//documents.onDidChangeContent(onEvent)
|
||||||
|
|
||||||
function onEvent(event: TextDocumentChangeEvent) {
|
function onEvent(document: TextDocument) {
|
||||||
preprocess(event.document, true, [event.document.uri.replace(/^file:\/\//, '')])
|
preprocess(document.getText().split('\n'), formatURI(document.uri), true, [document.uri.replace(/^file:\/\//, '')])
|
||||||
}
|
|
||||||
|
|
||||||
export function checkBinary(ok: () => void, fail?: () => any) {
|
|
||||||
exec(conf.glslangPath, (error) => {
|
|
||||||
if (error['code'] !== 1) {
|
|
||||||
if (fail) fail()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ok()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.onDidChangeConfiguration((change) => {
|
connection.onDidChangeConfiguration((change) => {
|
||||||
const temp = change.settings.mcglsl as Config
|
const temp = change.settings.mcglsl as Config
|
||||||
conf = new Config(temp['shaderpacksPath'], temp['glslangValidatorPath'])
|
conf = new Config(temp['shaderpacksPath'], temp['glslangValidatorPath'])
|
||||||
checkBinary(
|
try {
|
||||||
() => {documents.all().forEach(document => preprocess(document, true, [document.uri.replace(/^file:\/\//, '')]))},
|
execSync(conf.glslangPath)
|
||||||
() => {connection.window.showErrorMessage(`[mc-glsl] glslangValidator not found at: ${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)
|
connection.onCompletion((textDocumentPosition: vsclang.TextDocumentPositionParams) => completions)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue