@@ -109,6 +109,15 @@ class GccTreeDecoder: public AbstractTreeDecoder {
109
109
const GccPostProcessor postProc;
110
110
};
111
111
112
+ // / tree decoder of the JSON format produced by ShellCheck
113
+ class ShellCheckTreeDecoder : public AbstractTreeDecoder {
114
+ public:
115
+ bool readNode (Defect *def, pt::ptree::const_iterator defIter) override ;
116
+
117
+ private:
118
+ const GccPostProcessor postProc;
119
+ };
120
+
112
121
struct JsonParser ::Private {
113
122
InStream &input;
114
123
AbstractTreeDecoder *decoder = nullptr ;
@@ -168,7 +177,11 @@ JsonParser::JsonParser(InStream &input):
168
177
else if (findChildOf (&node, d->root , " runs" ))
169
178
// SARIF format
170
179
d->decoder = new SarifTreeDecoder;
180
+ else if (findChildOf (&node, d->root , " comments" ))
181
+ // ShellCheck JSON format
182
+ d->decoder = new ShellCheckTreeDecoder;
171
183
else if (first.not_found () != first.find (" kind" ))
184
+ // GCC JSON format
172
185
d->decoder = new GccTreeDecoder;
173
186
else
174
187
throw pt::ptree_error (" unknown JSON format" );
@@ -781,3 +794,49 @@ bool GccTreeDecoder::readNode(Defect *def, pt::ptree::const_iterator defIter)
781
794
782
795
return true ;
783
796
}
797
+
798
+ static bool scReadEvent (DefEvent *pEvt, const pt::ptree &evtNode)
799
+ {
800
+ using std::string;
801
+
802
+ // read level (error, warning, note)
803
+ string &evtName = pEvt->event ;
804
+ evtName = valueOf<string>(evtNode, " level" , " " );
805
+ if (evtName.empty ())
806
+ return false ;
807
+
808
+ // read location
809
+ pEvt->fileName = valueOf<string>(evtNode, " file" , " <unknown>" );
810
+ pEvt->line = valueOf<int > (evtNode, " line" , 0 );
811
+ pEvt->column = valueOf<int > (evtNode, " byte-column" , 0 );
812
+
813
+ // read message
814
+ pEvt->msg = valueOf<string>(evtNode, " message" , " <unknown>" );
815
+
816
+ // append [SC...] if available
817
+ const string code = valueOf<string>(evtNode, " code" , " " );
818
+ if (!code.empty ())
819
+ pEvt->msg += " [SC" + code + " ]" ;
820
+
821
+ return true ;
822
+ }
823
+
824
+ bool ShellCheckTreeDecoder::readNode (
825
+ Defect *def,
826
+ pt::ptree::const_iterator defIter)
827
+ {
828
+ *def = Defect (" SHELLCHECK_WARNING" );
829
+ const pt::ptree &defNode = defIter->second ;
830
+
831
+ // read key event
832
+ def->events .push_back (DefEvent ());
833
+ if (!scReadEvent (&def->events .back (), defNode))
834
+ return false ;
835
+
836
+ // TODO: go through fix/replacements nodes
837
+
838
+ // apply post-processing rules
839
+ this ->postProc .apply (def);
840
+
841
+ return true ;
842
+ }
0 commit comments