@@ -171,9 +171,6 @@ export default class Linter {
171171 const currentProcedure = globalScope . procedures . find ( proc => proc . position . path === data . uri && lineNumber >= proc . range . start && lineNumber <= proc . range . end ) ;
172172 const currentScope = globalScope . merge ( inProcedure && currentProcedure ? currentProcedure . scope : undefined ) ;
173173
174- // Only fetch the names if we have a rule that requires it. It might be slow.
175- const definedNames = ( rules . IncorrectVariableCase || rules . SQLHostVarCheck ? currentScope . getNames ( ) : [ ] ) ;
176-
177174 let value ;
178175 let isEmbeddedSQL = false ;
179176
@@ -699,7 +696,7 @@ export default class Linter {
699696
700697 if ( rules . SQLHostVarCheck ) {
701698 statement . forEach ( ( part , index ) => {
702- if ( part . type === `word` && definedNames . some ( name => name . toUpperCase ( ) === part . value . toUpperCase ( ) ) ) {
699+ if ( part . type === `word` && currentScope . findDefinition ( lineNumber , part . value ) ) {
703700 const prior = statement [ index - 1 ] ;
704701 if ( prior && ! [ `dot` , `seperator` ] . includes ( prior . type ) ) {
705702 errors . push ( {
@@ -821,24 +818,6 @@ export default class Linter {
821818
822819 const isDeclare = [ `declare` , `end` ] . includes ( statement [ 0 ] . type ) ;
823820
824- if ( rules . IncorrectVariableCase ) {
825- // Check the casing of the reference matches the definition
826- if ( ( isEmbeddedSQL === false || ( isEmbeddedSQL && statement [ i - 1 ] && statement [ i - 1 ] . type === `seperator` ) ) ) {
827- const possibleKeyword = ( isDeclare || inPrototype || inStruct . length > 0 ) && i >= 0 && statement [ i + 1 ] && statement [ i + 1 ] . type === `openbracket` ;
828-
829- if ( ! possibleKeyword && ! isDirective ) {
830- const definedName = definedNames . find ( defName => defName . toUpperCase ( ) === upperName ) ;
831- if ( definedName && definedName !== part . value ) {
832- errors . push ( {
833- offset : part . range ,
834- type : `IncorrectVariableCase` ,
835- newValue : definedName
836- } ) ;
837- }
838- }
839- }
840- }
841-
842821 if ( ( isDeclare && i >= 2 ) || ! isDeclare ) {
843822 if ( rules . RequiresParameter && ! inPrototype && ! isDeclare ) {
844823 // Check the procedure reference has a block following it
@@ -1026,102 +1005,112 @@ export default class Linter {
10261005 } ) ;
10271006 }
10281007
1029- if ( rules . NoUnreferenced ) {
1008+ if ( rules . NoUnreferenced || rules . IncorrectVariableCase ) {
1009+ const noRefCheck = ( def : Declaration ) => {
1010+ if ( def . name !== undefined && def . name . toUpperCase ( ) !== NO_NAME && def . position . path === data . uri ) {
1011+ if ( def . references . length <= 1 ) {
1012+ const possibleStatement = doc . getStatementByLine ( def . position . range . line ) ;
1013+ if ( possibleStatement ) {
1014+ errors . push ( {
1015+ type : `NoUnreferenced` ,
1016+ offset : { start : possibleStatement . range . start , end : possibleStatement . range . end }
1017+ } ) ;
1018+ }
1019+ }
1020+ }
1021+ }
1022+ const casingCheck = ( def : Declaration ) => {
1023+ if ( def . name !== undefined && def . name . toUpperCase ( ) !== NO_NAME ) {
1024+ def . references . forEach ( ref => {
1025+ if ( ref . uri === data . uri ) { // We're only checking the active file
1026+ if ( ! errors . some ( e => e . offset . start === ref . offset . start ) ) { //This is required because LIKEDS shares subfields
1027+ const contentPosition = data . content . substring ( ref . offset . start , ref . offset . end ) ;
1028+ if ( contentPosition !== def . name ) {
1029+ errors . push ( {
1030+ type : `IncorrectVariableCase` ,
1031+ offset : { start : ref . offset . start , end : ref . offset . end } ,
1032+ newValue : def . name
1033+ } ) ;
1034+ }
1035+ }
1036+ }
1037+ } ) ;
1038+ }
1039+ }
1040+
10301041 [
10311042 globalScope ,
10321043 ...globalScope . procedures . filter ( proc => proc . scope !== undefined ) . map ( proc => proc . scope )
10331044 ] . forEach ( dec => {
10341045 [ ...dec . constants , ...dec . variables ]
1035- . filter ( def => def . position . path === data . uri )
10361046 . forEach ( def => {
1037- if ( def . references . length <= 1 ) {
1038- // Add an error to def
1039- const possibleStatement = doc . getStatementByLine ( def . position . range . line ) ;
1040- if ( possibleStatement ) {
1041- errors . push ( {
1042- type : `NoUnreferenced` ,
1043- offset : { start : possibleStatement . range . start , end : possibleStatement . range . end }
1044- } ) ;
1045- }
1047+ if ( rules . NoUnreferenced ) {
1048+ noRefCheck ( def ) ;
1049+ }
1050+
1051+ if ( rules . IncorrectVariableCase ) {
1052+ casingCheck ( def ) ;
10461053 }
10471054 } ) ;
10481055
10491056 dec . subroutines
1050- . filter ( def => def . position . path === data . uri && def . name && ! [ `*INZSR` , `*PSSR` ] . includes ( def . name . toUpperCase ( ) ) )
1057+ . filter ( def => def . name && ! [ `*INZSR` , `*PSSR` ] . includes ( def . name . toUpperCase ( ) ) )
10511058 . forEach ( def => {
1052- if ( def . references . length <= 1 ) {
1053- // Add an error to def
1054- const possibleStatement = doc . getStatementByLine ( def . position . range . line ) ;
1055- if ( possibleStatement ) {
1056- errors . push ( {
1057- type : `NoUnreferenced` ,
1058- offset : { start : possibleStatement . range . start , end : possibleStatement . range . end }
1059- } ) ;
1060- }
1059+ if ( rules . NoUnreferenced ) {
1060+ noRefCheck ( def ) ;
1061+ }
1062+
1063+ if ( rules . IncorrectVariableCase ) {
1064+ casingCheck ( def ) ;
10611065 }
10621066 } ) ;
10631067
10641068 dec . procedures
1065- . filter ( struct => struct . position . path === data . uri )
10661069 . forEach ( proc => {
10671070 if ( ! proc . keyword [ `EXPORT` ] ) {
1068- if ( proc . references . length <= 1 ) {
1069- // Add an error to proc
1070- const possibleStatement = doc . getStatementByLine ( proc . position . range . line ) ;
1071- if ( possibleStatement ) {
1072- errors . push ( {
1073- type : `NoUnreferenced` ,
1074- offset : { start : possibleStatement . range . start , end : possibleStatement . range . end }
1075- } ) ;
1076- }
1071+ if ( rules . NoUnreferenced ) {
1072+ noRefCheck ( proc ) ;
1073+ }
1074+
1075+ if ( rules . IncorrectVariableCase ) {
1076+ casingCheck ( proc ) ;
10771077 }
10781078
10791079 if ( ! proc . keyword [ `EXTPGM` ] && ! proc . keyword [ `EXTPROC` ] ) {
10801080 proc . subItems . forEach ( parm => {
1081- if ( parm . references . length <= 1 ) {
1082- const possibleStatement = doc . getStatementByLine ( parm . position . range . line ) ;
1083- if ( possibleStatement ) {
1084- errors . push ( {
1085- type : `NoUnreferenced` ,
1086- offset : { start : possibleStatement . range . start , end : possibleStatement . range . end }
1087- } ) ;
1088- }
1081+ if ( rules . NoUnreferenced ) {
1082+ noRefCheck ( parm ) ;
1083+ }
1084+
1085+ if ( rules . IncorrectVariableCase ) {
1086+ casingCheck ( parm ) ;
10891087 }
10901088 } ) ;
10911089 }
10921090 }
10931091 } ) ;
10941092
10951093 dec . structs
1096- . filter ( struct => struct . position . path === data . uri )
10971094 . forEach ( struct => {
1098- const subFieldIsUsed = struct . subItems . some ( subf => subf . references . length > 1 ) ;
10991095
1100- if ( struct . references . length <= 1 ) {
1096+ struct . subItems . forEach ( subf => {
11011097 // We only check the subfields if the parent is never references.
1098+ if ( rules . NoUnreferenced && struct . references . length <= 1 ) {
1099+ noRefCheck ( subf ) ;
1100+ }
11021101
1103- struct . subItems . forEach ( subf => {
1104- if ( subf . name !== NO_NAME && subf . references . length <= 1 ) {
1105- // Add an error to subf
1106- const possibleStatement = doc . getStatementByLine ( subf . position . range . line ) ;
1107- if ( possibleStatement ) {
1108- errors . push ( {
1109- type : `NoUnreferenced` ,
1110- offset : { start : possibleStatement . range . start , end : possibleStatement . range . end }
1111- } ) ;
1112- }
1113- }
1114- } ) ;
1115-
1116- if ( subFieldIsUsed === false ) {
1117- const possibleStatement = doc . getStatementByLine ( struct . position . range . line ) ;
1118- if ( possibleStatement ) {
1119- errors . push ( {
1120- type : `NoUnreferenced` ,
1121- offset : { start : possibleStatement . range . start , end : possibleStatement . range . end }
1122- } ) ;
1123- }
1102+ if ( rules . IncorrectVariableCase ) {
1103+ casingCheck ( subf ) ;
11241104 }
1105+ } ) ;
1106+
1107+ const subFieldIsUsed = struct . subItems . some ( subf => subf . references . length > 1 ) ;
1108+ if ( rules . NoUnreferenced && subFieldIsUsed === false ) {
1109+ noRefCheck ( struct ) ;
1110+ }
1111+
1112+ if ( rules . IncorrectVariableCase ) {
1113+ casingCheck ( struct ) ;
11251114 }
11261115 } ) ;
11271116 } ) ;
0 commit comments