mirror of
https://github.com/Strum355/mcshader-lsp.git
synced 2025-08-02 08:02:58 +00:00
Linting of all currently discovered files that contain the edited include at some depth is pretty much working! Issue #11 highlights the blocking bug
This commit is contained in:
parent
5e6a12c88b
commit
5a06d8ff1b
3 changed files with 58 additions and 30 deletions
|
@ -4,7 +4,7 @@ import { execSync } from 'child_process'
|
|||
import * as path from 'path'
|
||||
import { readFileSync, existsSync } from 'fs'
|
||||
import { conf } from './config'
|
||||
import { postError, formatURI } from './utils'
|
||||
import { postError, formatURI, getDocumentContents } from './utils'
|
||||
import { platform } from 'os'
|
||||
|
||||
const reDiag = /^(ERROR|WARNING): ([^?<>*|"]+?):(\d+): (?:'.*?' : )?(.+)\r?/
|
||||
|
@ -21,7 +21,7 @@ const filters = [
|
|||
/Could not process include directive for header name:/
|
||||
]
|
||||
|
||||
const includeToParent = new Map<string, string[]>()
|
||||
export const includeToParent = new Map<string, Set<string>>()
|
||||
|
||||
type IncludeObj = {
|
||||
lineNum: number,
|
||||
|
@ -79,7 +79,8 @@ export function isInComment(line: string, state: Comment): Comment {
|
|||
}
|
||||
|
||||
export function preprocess(lines: string[], docURI: string) {
|
||||
if (lines.find((value: string, i: number, obj: string[]): boolean => reIncludeExt.test(value)) == undefined) {
|
||||
// wish there was an ignore keyword like Go
|
||||
if (lines.find((value: string, _, __): boolean => reIncludeExt.test(value)) == undefined) {
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i]
|
||||
if (reVersion.test(line)) {
|
||||
|
@ -93,17 +94,19 @@ export function preprocess(lines: string[], docURI: string) {
|
|||
}
|
||||
}
|
||||
|
||||
const incStack = [docURI]
|
||||
const allIncludes: IncludeObj[] = []
|
||||
const diagnostics = new Map<string, Diagnostic[]>()
|
||||
processIncludes(lines, incStack, allIncludes, diagnostics)
|
||||
|
||||
processIncludes(lines, [docURI], allIncludes, diagnostics)
|
||||
|
||||
const includeMap = new Map<string, IncludeObj>(allIncludes.map(obj => [obj.path, obj]) as [string, IncludeObj][])
|
||||
try {
|
||||
|
||||
lint(docURI, lines, includeMap, diagnostics)
|
||||
} catch (e) {
|
||||
postError(e)
|
||||
}
|
||||
}
|
||||
|
||||
function buildIncludeTree(inc: IncludeObj) {
|
||||
if (!includeToParent.has(inc.path)) includeToParent.set(inc.path, new Set([inc.parent]))
|
||||
else includeToParent.get(inc.path).add(inc.parent)
|
||||
}
|
||||
|
||||
function processIncludes(lines: string[], incStack: string[], allIncludes: IncludeObj[], diagnostics: Map<string, Diagnostic[]>) {
|
||||
|
@ -111,6 +114,7 @@ function processIncludes(lines: string[], incStack: string[], allIncludes: Inclu
|
|||
allIncludes.push(...includes)
|
||||
if (includes.length > 0) {
|
||||
includes.reverse().forEach(inc => {
|
||||
buildIncludeTree(inc)
|
||||
mergeInclude(inc, lines, incStack, diagnostics)
|
||||
})
|
||||
// recursively check for more includes to be merged
|
||||
|
@ -223,7 +227,8 @@ function lint(uri: string, lines: string[], includes: Map<string, IncludeObj>, d
|
|||
// TODO what if we dont know the top level parent? Feel like thats a non-issue given that we have uri
|
||||
diag = {
|
||||
severity: errorType(type),
|
||||
range: calcRange(includes.get(nextFile).lineNum - 1, includes.get(nextFile).parent),
|
||||
// TODO put -1 back when #11 is sorted
|
||||
range: calcRange(includes.get(nextFile).lineNum, includes.get(nextFile).parent),
|
||||
message: includes.get(file).path.replace(conf.shaderpacksPath, '') + replaceWords(msg),
|
||||
source: 'mc-glsl'
|
||||
}
|
||||
|
@ -253,14 +258,10 @@ const filterMatches = (output: string) => output
|
|||
.filter(match => match && match.length === 5)
|
||||
|
||||
function calcRange(lineNum: number, uri: string): Range {
|
||||
let lines = []
|
||||
|
||||
// TODO better error handling maybe?
|
||||
if (documents.keys().includes('file://' + uri)) {
|
||||
lines = documents.get('file://' + uri).getText().split('\n')
|
||||
} else {
|
||||
lines = readFileSync(uri).toString().split('\n')
|
||||
}
|
||||
const lines = getDocumentContents(uri).split('\n')
|
||||
console.log(uri, lineNum, lines.length)
|
||||
console.log(lines.slice(Math.max(lineNum - 3, 0), lineNum + 3).join('\n'))
|
||||
|
||||
const line = lines[lineNum]
|
||||
const startOfLine = line.length - line.trimLeft().length
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import * as vsclang from 'vscode-languageserver'
|
||||
import * as vsclangproto from 'vscode-languageserver-protocol'
|
||||
import { completions } from './completionProvider'
|
||||
import { preprocess, ext } from './linter'
|
||||
import { preprocess, ext, includeToParent } from './linter'
|
||||
import { extname } from 'path'
|
||||
|
||||
const reVersion = /#version [\d]{3}/
|
||||
|
||||
export let connection: vsclang.IConnection
|
||||
connection = vsclang.createConnection(new vsclang.IPCMessageReader(process), new vsclang.IPCMessageWriter(process))
|
||||
|
||||
import { onConfigChange } from './config'
|
||||
import { formatURI } from './utils'
|
||||
import { formatURI, postError, getDocumentContents } from './utils'
|
||||
|
||||
export const documents = new vsclang.TextDocuments()
|
||||
documents.listen(connection)
|
||||
|
@ -36,15 +38,34 @@ documents.onDidClose((event) => connection.sendDiagnostics({uri: event.document.
|
|||
//documents.onDidChangeContent(onEvent)
|
||||
|
||||
export function onEvent(document: vsclangproto.TextDocument) {
|
||||
if (!ext.has(extname(document.uri))) return
|
||||
try {
|
||||
console.log(document.uri)
|
||||
console.log(formatURI(document.uri))
|
||||
preprocess(document.getText().split('\n'), formatURI(document.uri))
|
||||
} catch (e) {
|
||||
connection.window.showErrorMessage(`[mc-glsl] ${e.message}`)
|
||||
throw(e)
|
||||
const uri = formatURI(document.uri)
|
||||
if (includeToParent.has(uri)) {
|
||||
lintBubbleDown(uri, document)
|
||||
return
|
||||
}
|
||||
|
||||
if (!ext.has(extname(document.uri))) return
|
||||
|
||||
try {
|
||||
preprocess(document.getText().split('\n'), uri)
|
||||
} catch (e) {
|
||||
postError(e)
|
||||
}
|
||||
}
|
||||
|
||||
function lintBubbleDown(uri: string, document: vsclangproto.TextDocument) {
|
||||
includeToParent.get(uri).forEach(parent => {
|
||||
console.log(`${uri} has parent ${parent}`)
|
||||
if (includeToParent.has(parent)) {
|
||||
lintBubbleDown(parent, document)
|
||||
} else {
|
||||
const lines = getDocumentContents(parent).split('\n')
|
||||
if (lines.filter(l => reVersion.test(l)).length > 0) {
|
||||
console.log(`${parent} is at top, linting down`)
|
||||
preprocess(lines, parent)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
connection.onDidChangeConfiguration(onConfigChange)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { connection } from './server'
|
||||
import { connection, documents } from './server'
|
||||
import { readFileSync } from 'fs'
|
||||
|
||||
export function postError(e: Error) {
|
||||
connection.window.showErrorMessage(e.message)
|
||||
|
@ -6,3 +7,8 @@ export function postError(e: Error) {
|
|||
}
|
||||
|
||||
export const formatURI = (uri: string) => uri.replace(/^file:\/\//, '').replace(/^(?:\/)c%3A/, 'C:').replace(/\\/g, '/')
|
||||
|
||||
export function getDocumentContents(uri: string): string {
|
||||
if (documents.keys().includes('file://' + uri)) return documents.get('file://' + uri).getText()
|
||||
else return readFileSync(uri).toString()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue