reports/Builder__LintReport.st
author Claus Gittinger <cg@exept.de>
Thu, 28 Mar 2019 13:54:38 +0100
changeset 542 aa25a71be62a
parent 267 9f55d8893118
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/reports' }"
     2 
     3 "{ NameSpace: Builder }"
     4 
     5 Report subclass:#LintReport
     6 	instanceVariableNames:'environment rules'
     7 	classVariableNames:''
     8 	poolDictionaries:''
     9 	category:'Builder-Reports'
    10 !
    11 
    12 
    13 !LintReport methodsFor:'accessing - defaults'!
    14 
    15 defaultFileSuffix
    16 
    17     ^ 'Lint'
    18 
    19     "Modified: / 08-10-2011 / 10:49:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    20 !
    21 
    22 defaultFormat
    23     "raise an error: must be redefined in concrete subclass(es)"
    24 
    25     ^ LintReportFormat::PMD new
    26 
    27     "Modified: / 25-11-2011 / 22:06:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    28 !
    29 
    30 defaultName
    31 
    32     environment isNil ifTrue:[^super defaultName].
    33     ^environment label
    34 
    35     "Modified: / 25-11-2011 / 22:06:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    36     "Created: / 13-01-2012 / 12:43:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    37 ! !
    38 
    39 !LintReport methodsFor:'command line options'!
    40 
    41 cmdlineOptionRuleset
    42 
    43     ^CmdLineOption new
    44         short: $s;
    45         long: 'ruleset';
    46         description: 'defines set of rules to check against.';
    47         action:[:option |
    48             self setupRulesFrom: option.
    49         ];
    50         yourself
    51 
    52     "Created: / 28-02-2013 / 23:13:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    53     "Modified: / 27-05-2014 / 16:54:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    54 ! !
    55 
    56 !LintReport methodsFor:'generating'!
    57 
    58 generateClass:class inPackage:package 
    59     | sourceInfo |
    60 
    61     sourceInfo := ReportSourceInfo forClass:class inPackage:package.
    62     format writeFile:(sourceInfo pathNameAbsolute: true)
    63         with:[
    64             self generateClass:class source:sourceInfo inPackage: package.
    65             self generateClass:class class source:sourceInfo inPackage: package.
    66         ].
    67 
    68     "Created: / 15-12-2014 / 10:46:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    69     "Modified: / 16-12-2014 / 10:38:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    70 !
    71 
    72 generateClass: aClass selector: aSelector source: sourceInfo
    73         | matching |
    74         matching := rules select: [ :each | 
    75                 (self isSelectorEnvironment: each result)
    76                         and: [ each result includesSelector: aSelector in: aClass ] ].
    77         self generateViolations: matching class: aClass selector: aSelector source: sourceInfo
    78 
    79     "Created: / 07-10-2011 / 11:04:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    80     "Modified: / 01-03-2013 / 18:10:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    81 !
    82 
    83 generateClass: aClass selector: aSelector source: sourceInfo inPackage: package
    84         | matching |
    85         matching := rules select: [ :each | 
    86                 (self isSelectorEnvironment: each result)
    87                         and: [ each result includesSelector: aSelector in: aClass ] ].
    88         self generateViolations: matching class: aClass selector: aSelector source: sourceInfo
    89 
    90     "Created: / 15-12-2014 / 11:04:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    91 !
    92 
    93 generateClass: aClass source: sourceInfo inPackage: package 
    94 
    95     | matching |
    96     (environment definesClass: aClass) ifTrue: [
    97         matching := rules select: [ :rule | (self isClassEnvironment: rule result) and: [ rule result includesClass: aClass ] ].
    98         self generateViolations: matching class: aClass source: sourceInfo
    99     ].
   100     (environment selectorsForClass: aClass) asSortedCollection do: [ :selector | 
   101         self generateClass: aClass selector: selector source: sourceInfo inPackage: package
   102     ]
   103 
   104     "Created: / 15-12-2014 / 11:05:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   105 !
   106 
   107 generateClassesInPackage:package 
   108     (ProjectDefinition searchForClassesWithProject:package) do:[:cls | 
   109         self generateClass:cls inPackage:package
   110     ].
   111 
   112     "Created: / 15-12-2014 / 10:52:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   113 !
   114 
   115 generateExtensionsInPackage:package 
   116     | sourceInfo |
   117 
   118     sourceInfo := ReportSourceInfo forExtensionsInPackage:package.
   119     format writeFile:(sourceInfo pathNameAbsolute: true)
   120         with:[
   121             (ProjectDefinition searchForExtensionsWithProject:package) do:[:method | 
   122                 self 
   123                     generateClass:method mclass
   124                     selector:method selector
   125                     source:sourceInfo
   126                     inPackage: package.
   127             ].
   128         ].
   129 
   130     "Created: / 15-12-2014 / 10:50:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   131     "Modified: / 16-12-2014 / 10:38:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   132 !
   133 
   134 generatePackage: package
   135     self generateClassesInPackage:package.  
   136     self generateExtensionsInPackage:package.
   137 
   138     "Created: / 15-12-2014 / 10:42:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   139 !
   140 
   141 generateViolations: aCollection class: aClass selector: aSelector source: sourceInfo
   142     | method offset  |
   143 
   144     (AbstractSourceCodeManager isVersionMethodSelector: aSelector) ifTrue:[ ^ self ].
   145     (AbstractSourceCodeManager isExtensionsVersionMethodSelector: aSelector) ifTrue:[ ^ self ].
   146 
   147 
   148     method := aClass compiledMethodAt: aSelector.
   149     offset := sourceInfo offsetOfMethod: method.
   150     aCollection do: [ :rule |
   151         | tree |
   152 
   153         tree := RBParser parseMethod: method source.
   154         rule result selectionIntervalsForSource: method source tree: tree in: method mclass do:[:intervalOrNil | 
   155             | interval start stop |
   156 
   157             interval := interval isNil ifTrue: [ 1 to: method source size ].
   158             start := sourceInfo lineAndColumnOfOffset: offset + interval first - 1.
   159             stop  := sourceInfo lineAndColumnOfOffset: offset + interval last - 1.
   160 
   161             format writeViolation: rule
   162                        class: aClass selector: aSelector
   163                    startLine: start x column: start y
   164                     stopLine: stop x  column: stop  y.
   165         ]
   166     ]
   167 
   168     "Created: / 01-03-2013 / 18:05:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   169     "Modified: / 15-12-2014 / 11:32:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   170 !
   171 
   172 generateViolations: aCollection class: aClass source: sourceInfo
   173     | method offset start stop |
   174 
   175     start := sourceInfo lineAndColumnOfOffset: 1.
   176     stop  := sourceInfo lineAndColumnOfOffset: SmallInteger maxVal.
   177     aCollection do: [ :rule |
   178         | interval  |
   179 
   180         format writeViolation: rule
   181                    class: aClass selector: nil
   182                startLine: start x column: start y
   183                 stopLine: stop x  column: stop  y.
   184     ]
   185 
   186     "Created: / 15-12-2014 / 11:13:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   187 ! !
   188 
   189 !LintReport methodsFor:'initialization'!
   190 
   191 setupForClasses: classes
   192 
   193     environment := BrowserEnvironment new forClasses: classes.
   194     environment label: name
   195 
   196     "Created: / 04-08-2011 / 14:40:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   197 !
   198 
   199 setupForPackages: pkgs
   200     pkgs isEmpty ifTrue:[^self].
   201     environment := PackageEnvironment 
   202                     onEnvironment: BrowserEnvironment new
   203                     packageNames: pkgs.
   204     name isNil ifTrue:[
   205         pkgs size > 1 ifTrue:[
   206             name :=  pkgs size printString , ' packages'.
   207         ] ifFalse:[
   208             name :=  pkgs anElement
   209         ]
   210     ].
   211 
   212     environment label: name.
   213 
   214     "
   215         LintReport runPackage:'stx:goodies/monticello'.
   216         LintReport runPackage:'stx:libjava'
   217     "
   218 
   219     "Created: / 04-08-2011 / 14:40:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   220     "Modified: / 15-12-2014 / 10:52:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   221 ! !
   222 
   223 !LintReport methodsFor:'private'!
   224 
   225 lineAndColumn: aString at: anInteger
   226 	| line last stream |
   227 	line := 1.
   228 	last := 0.
   229 	stream := aString readStream.
   230 	[ (stream nextLine isNil or: [ anInteger <= stream position ])
   231 		ifTrue: [ ^ line @ (anInteger - last) ].
   232 	last := stream position.
   233 	line := line + 1 ]
   234 		repeat
   235 !
   236 
   237 sourceFilenameForClass:class package: package 
   238     | fn  cls |
   239 
   240     cls := class theNonMetaclass.
   241     fn := package copy
   242             replaceAll:$: with:$_;
   243             replaceAll:$/ with:$_;
   244             yourself.
   245     fn := fn , '_' , (cls asString copyReplaceAll:$: with:$_) , '.' 
   246             , cls programmingLanguage sourceFileSuffix.
   247     ^ self encodeFilename:fn.
   248 
   249     "
   250         Builder::LintReportFormat::CheckStyle basicNew
   251             sourceFilenameFor: Class
   252 
   253         Builder::LintReportFormat::CheckStyle basicNew
   254             sourceFilenameFor: Builder::LintReportFormat"
   255 
   256     "Created: / 15-12-2014 / 10:46:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   257 !
   258 
   259 sourceFilenameForExtensionsInPackage: package 
   260     | fn |
   261 
   262     fn := package copy
   263             replaceAll:$: with:$_;
   264             replaceAll:$/ with:$_;
   265             yourself.
   266     fn := fn , '_' , 'extensions.st'.
   267     ^ self encodeFilename:fn.
   268 
   269     "
   270         Builder::LintReportFormat::CheckStyle basicNew
   271             sourceFilenameFor: Class
   272 
   273         Builder::LintReportFormat::CheckStyle basicNew
   274             sourceFilenameFor: Builder::LintReportFormat"
   275 
   276     "Created: / 15-12-2014 / 10:50:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   277 ! !
   278 
   279 !LintReport methodsFor:'running'!
   280 
   281 runReport
   282     | wasTryLocalSources |
   283 
   284     [
   285         wasTryLocalSources := Class tryLocalSourceFirst.
   286         Class tryLocalSourceFirst: true.
   287         SmalllintChecker 
   288             runRule: (RBCompositeLintRule rules: rules)
   289             onEnvironment: environment.
   290         environment packageNames do:[:packageName | 
   291             self generatePackage: packageName  
   292         ].
   293     ] ensure:[
   294         Class tryLocalSourceFirst: wasTryLocalSources 
   295     ]
   296 
   297     "Modified: / 15-12-2014 / 11:06:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   298 !
   299 
   300 setUp
   301 
   302     super setUp.
   303     rules isNil ifTrue:[
   304         rules := RBBuiltinRuleSet rulesetBuiltinDefault flatten   
   305     ].
   306 
   307     "Created: / 04-08-2011 / 14:35:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   308     "Modified: / 15-12-2014 / 11:35:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   309 !
   310 
   311 setupRulesFrom: filename
   312     | file |    
   313     file := filename asFilename.
   314     file readingFileDo:[:s|
   315         | spec |
   316         spec := Parser parseLiteralArray: s.
   317         rules := spec decodeAsLiteralArray rules.
   318     ]
   319 
   320     "Created: / 28-02-2013 / 23:17:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   321 ! !
   322 
   323 !LintReport methodsFor:'testing'!
   324 
   325 isClassEnvironment: anEnvironment
   326 	^ #(CategoryEnvironment ClassEnvironment VariableEnvironment) includes: anEnvironment class name
   327 !
   328 
   329 isSelectorEnvironment: anEnvironment
   330 	^ #(SelectorEnvironment ParseTreeEnvironment VariableEnvironment) includes: anEnvironment class name
   331 ! !
   332 
   333 !LintReport class methodsFor:'documentation'!
   334 
   335 version
   336     ^ '$Header$'
   337 !
   338 
   339 version_CVS
   340     ^ '$Header$'
   341 !
   342 
   343 version_SVN
   344     ^ '$Id$'
   345 ! !
   346