added:
authorClaus Gittinger <cg@exept.de>
Sun, 07 Aug 2011 13:12:45 +0200
changeset 37 0a356190f3f3
parent 36 2c0987f7230d
child 38 2ce19e2a6095
added: #addClasses: #setupRules: changed: #examples #generateReportOn: #setupRules
codechecker/SmalllintReportGenerator.st
--- a/codechecker/SmalllintReportGenerator.st	Sun Aug 07 11:30:17 2011 +0200
+++ b/codechecker/SmalllintReportGenerator.st	Sun Aug 07 13:12:45 2011 +0200
@@ -21,12 +21,23 @@
 
 examples
 "
+                                                                    [exBegin]
     |checker|
 
     checker := self new.
     checker addPackage:'exept:workflow'.
     checker performChecks.
     checker generateReportAs:'checkstyle.xml'
+                                                                    [exEnd]
+
+                                                                    [exBegin]
+    |checker|
+
+    checker := self new.
+    checker addClasses:(Workflow::Datatype withAllSubclasses).
+    checker performChecks.
+    checker generateReportAs:'checkstyle.xml'
+                                                                    [exEnd]
 "
 ! !
 
@@ -67,38 +78,67 @@
 !
 
 generateReportOn:aStream
-    aStream nextPutLine: '<?xml version="1.0"?>'.
-    aStream nextPutLine: '<pmd>'.
+    |perClass|
+
+    perClass := IdentityDictionary new.
+
     rules do:[:eachRule | 
         eachRule problemCount > 0 ifTrue:[
             eachRule failedMethods do:[:method |
-                |class classFileName s selector fullSource 
-                 charPos lineNumber ruleName rationale|
+                |class perMethodAndClassMethod perMethod|
 
                 class := method mclass.
-                s := class localSourceStreamFor:class theNonMetaclass classFilename.
-                s notNil ifTrue:[
-                    classFileName := s pathName.
-                    s close.
-                ] ifFalse:[
-                    classFileName := class sourceFilename.
+                perMethodAndClassMethod := perClass at:class theNonMetaclass ifAbsentPut:[{ IdentityDictionary new. IdentityDictionary new }].
+                perMethod := perMethodAndClassMethod at:(class isMeta ifTrue:[2] ifFalse:[1]).
+                rules := perMethod at:method ifAbsentPut:[IdentitySet new].
+                rules add:eachRule.
+            ]
+        ]
+    ].
+
+    aStream nextPutLine: '<?xml version="1.0"?>'.
+    aStream nextPutLine: '<pmd>'.
+
+    perClass keysAndValuesDo:[:class :perMethodAndClassMethod |
+        |fullSource sourceStream classFileName|
+
+        fullSource := class source.
+        sourceStream := class localSourceStreamFor:(class classFilename).
+        sourceStream notNil ifTrue:[
+            classFileName := sourceStream pathName.
+            sourceStream close.
+        ] ifFalse:[
+            classFileName := class packageDirectory construct:(class classFilename).
+        ].
+
+        aStream nextPutLine:('  <file name="%1">' bindWith:classFileName asFilename pathName).
+
+        { (perMethodAndClassMethod at:2).
+          (perMethodAndClassMethod at:1) } do:[:perMethod |
+            (perMethod keys copyAsOrderedCollection sort:[:a :b | a selector < b selector]) do:[:eachMethod |
+                |rulesPerMethod charPosOfMethod lineNumberOfMethod|
+
+                rulesPerMethod := perMethod at:eachMethod.
+                
+                charPosOfMethod := eachMethod sourcePosition ? 1.
+                "/ q&d hack - editor knows how to compute line number - should go
+                "/ somewhere else...
+                lineNumberOfMethod := (ListView basicNew setList:fullSource) lineOfCharacterPosition:charPosOfMethod.
+                rulesPerMethod do:[:eachRule |
+                    |ruleName rationale|
+
+                    ruleName := eachRule name.
+                    rationale := eachRule rationale.
+
+                    aStream nextPutLine:('    <violation line="%1" rule="%2">' 
+                                                        bindWith:lineNumberOfMethod with:ruleName).
+                    aStream nextPutLine:('%1' bindWith:rationale).
+                    aStream nextPutLine: '    </violation>'.
+
                 ].
-                fullSource := class source.
-                charPos := method sourcePosition ? 1.
-                "/ q&d hack - editor knows
-                lineNumber := (TextView new contents:fullSource)
-                                lineOfCharacterPosition:charPos.
-                ruleName := eachRule name.
-                rationale := eachRule rationale.
-
-    aStream nextPutLine:('  <file name="%1">' bindWith:classFileName).
-    aStream nextPutLine:('    <violation line="%1" rule="%2">' bindWith:lineNumber with:ruleName).
-    aStream nextPutLine:('%1' bindWith:rationale).
-    aStream nextPutLine: '    </violation>'.
-    aStream nextPutLine: '  </file>'.
-
             ].
-        ]
+        ].
+        aStream nextPutLine: '  </file>'.
     ].
     aStream nextPutLine: '</pmd>'.
 
@@ -113,6 +153,12 @@
     "Created: / 07-08-2011 / 01:11:33 / cg"
 !
 
+addClasses:aCollectionOfClasses
+    aCollectionOfClasses do:[:eachClass | self addClass: eachClass ].
+
+    "Created: / 07-08-2011 / 11:51:52 / cg"
+!
+
 addPackage:aPackage
     Smalltalk loadPackage:aPackage.
     Smalltalk allClassesInPackage:aPackage do:[:cls | self addClass:cls]
@@ -127,15 +173,20 @@
 !
 
 setupRules
-    | allRule checks|
+    self setupRules:(RBCompositeLintRule allRules).
+
+    "Created: / 07-08-2011 / 01:08:56 / cg"
+!
 
-    allRule := RBCompositeLintRule allRules.
-    checks := allRule rules detect:[ :each | each name = 'Lint checks' ].
+setupRules:rulesArg
+    | checks|
+
+    checks := rulesArg rules detect:[ :each | each name = 'Lint checks' ].
     checks rules: (checks rules reject: [ :each | each name = 'Squeak bugs' ]).
 
-    rules := allRule flattened.
+    rules := rulesArg flattened.
 
-    "Created: / 07-08-2011 / 01:08:56 / cg"
+    "Created: / 07-08-2011 / 11:48:30 / cg"
 ! !
 
 !SmalllintReportGenerator class methodsFor:'documentation'!