2 using System
.Collections
.Generic
;
3 using System
.Diagnostics
;
7 using CA
= MonoDevelop
.CodeAnalysis
;
9 namespace MonoDevelop
.CodeAnalysis
.Smokey
{
11 internal static class SmokeyParser
{
12 private const string RuleErrorMessage
= "A rule has failed to run.";
14 public static IEnumerable
<IViolation
> ParseOutput (StreamReader sr
, IEnumerable
<CA
.IRule
> ruleSet
)
16 List
<IViolation
> found
= new List
<IViolation
> ();
18 // FIXME: instead of checking each defect if its rule is in "set"
19 // we should think on making use of Smokey "ignore" feature
21 // we should only return violations with rules id in this list
22 List
<string> ruleIds
= new List
<string> ();
23 foreach (CA
.IRule rule
in ruleSet
)
24 ruleIds
.Add (rule
.Id
);
26 // if assembly is big, Gendarme outputs progress bar using dots
27 // before actual xml, so we might want to need to move forward
28 while (sr
.Peek () != '<')
32 using (XmlTextReader reader
= new XmlTextReader (sr
)) {
33 reader
.WhitespaceHandling
= WhitespaceHandling
.None
;
34 string file
= string.Empty
;
37 while (reader
.Read ()) {
38 if (reader
.NodeType
!= XmlNodeType
.Element
)
41 if("Location" == reader
.Name
) {
42 file
= reader
.GetAttribute("file");
43 if(null == file
){ file = string.Empty; }
44 if(!int.TryParse(reader
.GetAttribute("line"), out line
)){ line = 0; }
47 if (reader
.Name
!= "Violation")
52 string ruleId
= reader
.GetAttribute ("checkID");
53 // if we don't need to check for this rule, let it go
54 if (!ruleIds
.Contains (ruleId
))
57 // parse severity (or try to)
58 CA
.Severity severity
= ParseSeverity (reader
.GetAttribute ("severity"));
60 // parse solution and problem
61 string problem
= null;
62 string solution
= null;
63 while (reader
.Read ()) {
64 if (reader
.NodeType
!= XmlNodeType
.Element
)
67 if (reader
.Name
== "Cause")
68 problem
= reader
.ReadString ();
69 else if (reader
.Name
== "Fix")
70 solution
= reader
.ReadString ();
71 else if (problem
!= null && solution
!= null)
75 // sometimes Smokey rules throw an exception
76 // we shouldn't return "dead" violations
77 if (IsErrorMessage (problem
))
81 found
.Add (new SmokeyViolation (ruleId
, problem
, solution
, severity
, file
, line
));
87 private static CA
.Severity
ParseSeverity (string value)
90 return CA
.Severity
.High
; // FIXME: or Critical?
91 else if (value == "Warning")
92 return CA
.Severity
.Medium
;
93 else if (value == "Nitpick")
94 return CA
.Severity
.Low
;
96 return CA
.Severity
.Medium
; // by default?
99 private static bool IsErrorMessage (string cause
)
101 return cause
== RuleErrorMessage
;