codechecker/SmalllintReportGenerator.st
author Claus Gittinger <cg@exept.de>
Thu, 28 Mar 2019 13:54:38 +0100
changeset 542 aa25a71be62a
parent 37 0a356190f3f3
permissions -rw-r--r--
#DOCUMENTATION by cg
class: stx_goodies_builder_quickSelfTest
class definition

class: stx_goodies_builder_quickSelfTest class
added:18 methods
     1 "{ Package: 'stx:goodies/builder/codechecker' }"
     2 
     3 Object subclass:#SmalllintReportGenerator
     4 	instanceVariableNames:'rules environment'
     5 	classVariableNames:''
     6 	poolDictionaries:''
     7 	category:'Refactory-Lint'
     8 !
     9 
    10 !SmalllintReportGenerator class methodsFor:'documentation'!
    11 
    12 documentation
    13 "
    14     a standalone smallint runner.
    15     Generates an xml report compatible to pmd, to be processed by hudson.
    16 
    17     [author:]
    18         Claus Gittinger
    19 "
    20 !
    21 
    22 examples
    23 "
    24                                                                     [exBegin]
    25     |checker|
    26 
    27     checker := self new.
    28     checker addPackage:'exept:workflow'.
    29     checker performChecks.
    30     checker generateReportAs:'checkstyle.xml'
    31                                                                     [exEnd]
    32 
    33                                                                     [exBegin]
    34     |checker|
    35 
    36     checker := self new.
    37     checker addClasses:(Workflow::Datatype withAllSubclasses).
    38     checker performChecks.
    39     checker generateReportAs:'checkstyle.xml'
    40                                                                     [exEnd]
    41 "
    42 ! !
    43 
    44 !SmalllintReportGenerator class methodsFor:'instance creation'!
    45 
    46 new
    47     "return an initialized instance"
    48 
    49     ^ self basicNew initialize.
    50 ! !
    51 
    52 !SmalllintReportGenerator methodsFor:'checking'!
    53 
    54 performChecks
    55     rules withIndexDo:[:rule :index|
    56        Stdout showCR:('Checking: ', rule name).
    57        (SmalllintChecker runRule: rule onEnvironment: environment)
    58     ].
    59 
    60     "Created: / 07-08-2011 / 01:10:00 / cg"
    61 ! !
    62 
    63 !SmalllintReportGenerator methodsFor:'initialization'!
    64 
    65 initialize
    66     self setupRules.
    67     self setupEnvironment
    68 
    69     "Modified: / 07-08-2011 / 01:14:51 / cg"
    70 ! !
    71 
    72 !SmalllintReportGenerator methodsFor:'reporting'!
    73 
    74 generateReportAs:aFilename
    75     aFilename asFilename writingFileDo:[:s | self generateReportOn:s].
    76 
    77     "Created: / 07-08-2011 / 01:17:46 / cg"
    78 !
    79 
    80 generateReportOn:aStream
    81     |perClass|
    82 
    83     perClass := IdentityDictionary new.
    84 
    85     rules do:[:eachRule | 
    86         eachRule problemCount > 0 ifTrue:[
    87             eachRule failedMethods do:[:method |
    88                 |class perMethodAndClassMethod perMethod|
    89 
    90                 class := method mclass.
    91                 perMethodAndClassMethod := perClass at:class theNonMetaclass ifAbsentPut:[{ IdentityDictionary new. IdentityDictionary new }].
    92                 perMethod := perMethodAndClassMethod at:(class isMeta ifTrue:[2] ifFalse:[1]).
    93                 rules := perMethod at:method ifAbsentPut:[IdentitySet new].
    94                 rules add:eachRule.
    95             ]
    96         ]
    97     ].
    98 
    99     aStream nextPutLine: '<?xml version="1.0"?>'.
   100     aStream nextPutLine: '<pmd>'.
   101 
   102     perClass keysAndValuesDo:[:class :perMethodAndClassMethod |
   103         |fullSource sourceStream classFileName|
   104 
   105         fullSource := class source.
   106         sourceStream := class localSourceStreamFor:(class classFilename).
   107         sourceStream notNil ifTrue:[
   108             classFileName := sourceStream pathName.
   109             sourceStream close.
   110         ] ifFalse:[
   111             classFileName := class packageDirectory construct:(class classFilename).
   112         ].
   113 
   114         aStream nextPutLine:('  <file name="%1">' bindWith:classFileName asFilename pathName).
   115 
   116         { (perMethodAndClassMethod at:2).
   117           (perMethodAndClassMethod at:1) } do:[:perMethod |
   118             (perMethod keys copyAsOrderedCollection sort:[:a :b | a selector < b selector]) do:[:eachMethod |
   119                 |rulesPerMethod charPosOfMethod lineNumberOfMethod|
   120 
   121                 rulesPerMethod := perMethod at:eachMethod.
   122                 
   123                 charPosOfMethod := eachMethod sourcePosition ? 1.
   124                 "/ q&d hack - editor knows how to compute line number - should go
   125                 "/ somewhere else...
   126                 lineNumberOfMethod := (ListView basicNew setList:fullSource) lineOfCharacterPosition:charPosOfMethod.
   127                 rulesPerMethod do:[:eachRule |
   128                     |ruleName rationale|
   129 
   130                     ruleName := eachRule name.
   131                     rationale := eachRule rationale.
   132 
   133                     aStream nextPutLine:('    <violation line="%1" rule="%2">' 
   134                                                         bindWith:lineNumberOfMethod with:ruleName).
   135                     aStream nextPutLine:('%1' bindWith:rationale).
   136                     aStream nextPutLine: '    </violation>'.
   137 
   138                 ].
   139             ].
   140         ].
   141         aStream nextPutLine: '  </file>'.
   142     ].
   143     aStream nextPutLine: '</pmd>'.
   144 
   145     "Created: / 07-08-2011 / 01:17:00 / cg"
   146 ! !
   147 
   148 !SmalllintReportGenerator methodsFor:'setup'!
   149 
   150 addClass:aClass
   151     environment addClass: aClass.
   152 
   153     "Created: / 07-08-2011 / 01:11:33 / cg"
   154 !
   155 
   156 addClasses:aCollectionOfClasses
   157     aCollectionOfClasses do:[:eachClass | self addClass: eachClass ].
   158 
   159     "Created: / 07-08-2011 / 11:51:52 / cg"
   160 !
   161 
   162 addPackage:aPackage
   163     Smalltalk loadPackage:aPackage.
   164     Smalltalk allClassesInPackage:aPackage do:[:cls | self addClass:cls]
   165 
   166     "Created: / 07-08-2011 / 01:12:31 / cg"
   167 !
   168 
   169 setupEnvironment
   170     environment := ClassEnvironment new.
   171 
   172     "Created: / 07-08-2011 / 01:10:56 / cg"
   173 !
   174 
   175 setupRules
   176     self setupRules:(RBCompositeLintRule allRules).
   177 
   178     "Created: / 07-08-2011 / 01:08:56 / cg"
   179 !
   180 
   181 setupRules:rulesArg
   182     | checks|
   183 
   184     checks := rulesArg rules detect:[ :each | each name = 'Lint checks' ].
   185     checks rules: (checks rules reject: [ :each | each name = 'Squeak bugs' ]).
   186 
   187     rules := rulesArg flattened.
   188 
   189     "Created: / 07-08-2011 / 11:48:30 / cg"
   190 ! !
   191 
   192 !SmalllintReportGenerator class methodsFor:'documentation'!
   193 
   194 version
   195     ^ '$Header$'
   196 !
   197 
   198 version_CVS
   199     ^ '$Header$'
   200 ! !