@@ -4,10 +4,11 @@ import { execSync } from 'child_process'
44import * as path from 'path'
55import { readFileSync , existsSync , statSync , Stats } from 'fs'
66import { conf } from './config'
7- import { postError , formatURI , getDocumentContents } from './utils'
7+ import { postError , formatURI , getDocumentContents , trimPath } from './utils'
88import { platform } from 'os'
99import { Graph } from './graph'
1010import { Comment } from './comment'
11+ import { linterLog } from './logging'
1112
1213const reDiag = / ^ ( E R R O R | W A R N I N G ) : ( [ ^ ? < > * | " ] + ?) : ( \d + ) : (?: ' .* ?' : ) ? ( .+ ) \r ? /
1314const reVersion = / # v e r s i o n [ \d ] { 3 } /
@@ -25,8 +26,6 @@ const filters = [
2526
2627export const includeGraph = new Graph ( )
2728
28- export const allFiles = new Set < string > ( )
29-
3029type IncludeObj = {
3130 lineNum : number ,
3231 lineNumTopLevel : number ,
@@ -83,41 +82,51 @@ const tokens = new Map([
8382] )
8483
8584export function preprocess ( lines : string [ ] , docURI : string ) {
86- let hasDirective = true
87- // wish there was an ignore keyword like Go
88- if ( lines . find ( ( value : string , _ , __ ) : boolean => reIncludeExt . test ( value ) ) == undefined ) {
89- hasDirective = false
90- for ( let i = 0 ; i < lines . length ; i ++ ) {
91- const line = lines [ i ]
92- if ( reVersion . test ( line ) ) {
93- lines . splice ( i + 1 , 0 , include )
94- break
95- }
96- if ( i === lines . length - 1 ) {
97- lines . splice ( 0 , 0 , include )
98- break
99- }
100- }
101- }
85+ const hasDirective = includeDirective ( lines , docURI )
10286
103- const allIncludes : IncludeObj [ ] = [ ]
87+ const allIncludes = new Set < IncludeObj > ( )
10488 const diagnostics = new Map < string , Diagnostic [ ] > ( )
10589
10690 processIncludes ( lines , [ docURI ] , allIncludes , diagnostics , hasDirective )
10791
108- allIncludes . forEach ( inc => allFiles . add ( inc . path ) )
109-
110- const includeMap = new Map < string , IncludeObj > ( allIncludes . map ( obj => [ obj . path , obj ] ) as [ string , IncludeObj ] [ ] )
92+ const includeMap = new Map < string , IncludeObj > ( Array . from ( allIncludes ) . map ( obj => [ obj . path , obj ] ) as [ string , IncludeObj ] [ ] )
11193
11294 lint ( docURI , lines , includeMap , diagnostics )
11395}
11496
97+ function includeDirective ( lines : string [ ] , docURI : string ) : boolean {
98+ if ( lines . findIndex ( x => reIncludeExt . test ( x ) ) > - 1 ) {
99+ linterLog . info ( ( ) => 'include directive found' )
100+ return true
101+ }
102+
103+ let hasDirective = true
104+ linterLog . info ( ( ) => 'include directive not found' )
105+ hasDirective = false
106+ for ( let i = 0 ; i < lines . length ; i ++ ) {
107+ const line = lines [ i ]
108+ if ( reVersion . test ( line ) ) {
109+ linterLog . info ( ( ) => 'found version on line ' + ( i + 1 ) )
110+ lines . splice ( i + 1 , 0 , include )
111+ break
112+ }
113+
114+ if ( i === lines . length - 1 ) {
115+ linterLog . warn ( ( ) => `no version found for ${ docURI } . inserting at top` )
116+ lines . splice ( 0 , 0 , include )
117+ break
118+ }
119+ }
120+ return hasDirective
121+ }
122+
115123const buildIncludeGraph = ( inc : IncludeObj ) => includeGraph . setParent ( inc . path , inc . parent , inc . lineNum )
116124
117- function processIncludes ( lines : string [ ] , incStack : string [ ] , allIncludes : IncludeObj [ ] , diagnostics : Map < string , Diagnostic [ ] > , hasDirective : boolean ) {
125+ function processIncludes ( lines : string [ ] , incStack : string [ ] , allIncludes : Set < IncludeObj > , diagnostics : Map < string , Diagnostic [ ] > , hasDirective : boolean ) {
118126 const includes = getIncludes ( incStack [ 0 ] , lines )
119- allIncludes . push ( ... includes )
127+ includes . forEach ( i => allIncludes . add ( i ) )
120128 if ( includes . length > 0 ) {
129+ linterLog . info ( ( ) => `${ trimPath ( incStack [ 0 ] ) } has ${ includes . length } include(s). [${ includes . map ( i => '\n\t\t' + trimPath ( i . path ) ) } \n\t]` )
121130 includes . reverse ( ) . forEach ( inc => {
122131 buildIncludeGraph ( inc )
123132 mergeInclude ( inc , lines , incStack , diagnostics , hasDirective )
@@ -144,12 +153,17 @@ export function getIncludes(uri: string, lines: string[]) {
144153function processLine ( includes : IncludeObj [ ] , line : string , lines : string [ ] , i : number , linesInfo : LinesProcessingInfo ) : IncludeObj [ ] {
145154 const updated = Comment . update ( line , linesInfo . comment )
146155 linesInfo . comment = updated [ 0 ]
156+
157+ if ( updated [ 1 ] !== line ) linterLog . debug ( ( ) => `change:\n\t'${ line } '\n\t'${ updated [ 1 ] } '` )
158+
147159 line = updated [ 1 ]
148160 lines [ i ] = line
149161
150162 linesInfo . count [ linesInfo . count . length - 1 ] ++
151163 linesInfo . total ++
164+
152165 if ( linesInfo . comment ) return includes
166+
153167 if ( line . startsWith ( '#line' ) ) {
154168 const inc = line . slice ( line . indexOf ( '"' ) + 1 , line . lastIndexOf ( '"' ) )
155169
@@ -178,11 +192,15 @@ function processLine(includes: IncludeObj[], line: string, lines: string[], i: n
178192}
179193
180194function ifInvalidFile ( inc : IncludeObj , lines : string [ ] , incStack : string [ ] , diagnostics : Map < string , Diagnostic [ ] > ) {
195+ const msg = `${ trimPath ( inc . path ) } is missing or an invalid file.`
196+
197+ linterLog . error ( msg , null )
198+
181199 const file = incStack [ incStack . length - 1 ]
182200 const diag : Diagnostic = {
183201 severity : DiagnosticSeverity . Error ,
184- range : calcRange ( inc . lineNum - ( win ? 1 : 0 ) , file ) ,
185- message : ` ${ inc . path . replace ( conf . shaderpacksPath , '' ) } is missing or an invalid file.` ,
202+ range : calcRange ( inc . lineNum , file ) ,
203+ message : msg ,
186204 source : 'mc-glsl'
187205 }
188206
@@ -192,8 +210,7 @@ function ifInvalidFile(inc: IncludeObj, lines: string[], incStack: string[], dia
192210 const error : ErrorMatch = {
193211 type : DiagnosticSeverity . Error ,
194212 line : inc . lineNum ,
195- msg : `${ inc . path . replace ( conf . shaderpacksPath , '' ) } is missing or an invalid file.` ,
196- file,
213+ msg, file,
197214 }
198215 propogateDiagnostic ( error , diagnostics )
199216}
@@ -232,7 +249,6 @@ function mergeInclude(inc: IncludeObj, lines: string[], incStack: string[], diag
232249}
233250
234251function lint ( docURI : string , lines : string [ ] , includes : Map < string , IncludeObj > , diagnostics : Map < string , Diagnostic [ ] > ) {
235- console . log ( lines . join ( '\n' ) )
236252 let out : string = ''
237253 try {
238254 execSync ( `${ conf . glslangPath } --stdin -S ${ ext . get ( path . extname ( docURI ) ) } ` , { input : lines . join ( '\n' ) } )
@@ -241,8 +257,8 @@ function lint(docURI: string, lines: string[], includes: Map<string, IncludeObj>
241257 }
242258
243259 if ( ! diagnostics . has ( docURI ) ) diagnostics . set ( docURI , [ ] )
244- includes . forEach ( obj => {
245- if ( ! diagnostics . has ( obj . path ) ) diagnostics . set ( obj . path , [ ] )
260+ includeGraph . nodes . forEach ( ( node , key ) => {
261+ if ( ! diagnostics . has ( key ) ) diagnostics . set ( key , [ ] )
246262 } )
247263
248264 processErrors ( out , docURI , diagnostics )
@@ -280,11 +296,10 @@ function processErrors(out: string, docURI: string, diagnostics: Map<string, Dia
280296//errorFile: string, type: DiagnosticSeverity, line: number, msg: string
281297function propogateDiagnostic ( error : ErrorMatch , diagnostics : Map < string , Diagnostic [ ] > , parentURI ?: string ) {
282298 includeGraph . get ( parentURI || error . file ) . parents . forEach ( ( pair , parURI ) => {
283- console . log ( 'parent' , parURI , 'child' , error . file )
284299 const diag : Diagnostic = {
285300 severity : error . type ,
286- range : calcRange ( pair . first , parURI ) ,
287- message : `Line ${ error . line } ${ error . file . replace ( conf . shaderpacksPath , '' ) } ${ replaceWords ( error . msg ) } ` ,
301+ range : calcRange ( pair . first - 1 , parURI ) ,
302+ message : `Line ${ error . line } ${ trimPath ( error . file ) } ${ replaceWords ( error . msg ) } ` ,
288303 source : 'mc-glsl'
289304 }
290305
@@ -326,7 +341,7 @@ export function absPath(currFile: string, includeFile: string): string {
326341
327342 // TODO add explanation comment
328343 if ( includeFile . charAt ( 0 ) === '/' ) {
329- const shaderPath = currFile . replace ( conf . shaderpacksPath , '' ) . split ( '/' ) . slice ( 0 , 3 ) . join ( '/' )
344+ const shaderPath = trimPath ( currFile ) . split ( '/' ) . slice ( 0 , 3 ) . join ( '/' )
330345 return path . join ( conf . shaderpacksPath , shaderPath , includeFile )
331346 }
332347 return path . join ( path . dirname ( currFile ) , includeFile )
0 commit comments