Builder::LintReport refactoring - not yet finished!
authorJan Vrany <jan.vrany@fit.cvut.cz>
Fri, 01 Mar 2013 19:12:32 +0100
changeset 118 7e93ef8c5417
parent 117 d7f87303b984
child 119 318a202597cc
Builder::LintReport refactoring - not yet finished!
reports/Builder__LintReport.st
--- a/reports/Builder__LintReport.st	Fri Mar 01 10:42:50 2013 +0100
+++ b/reports/Builder__LintReport.st	Fri Mar 01 19:12:32 2013 +0100
@@ -9,6 +9,20 @@
 	category:'Builder-Reports'
 !
 
+Object subclass:#SourceInfo
+	instanceVariableNames:'klass filename offsets lineEnds'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:LintReport
+!
+
+Stream subclass:#LineCountingStream
+	instanceVariableNames:'position lineEnds'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:LintReport::SourceInfo
+!
+
 
 !LintReport class methodsFor:'class initialization'!
 
@@ -64,72 +78,66 @@
 !LintReport methodsFor:'generating'!
 
 generateClass: aClass
-        | sourceStream sourceName |
-        sourceStream := WriteStream on: String new.
+        | sourceInfo sourceName |
+        sourceInfo := SourceInfo for: aClass.
         sourceName := self encodeFilename: (self sourceFilenameFor: aClass).
 
         format writeFile: sourceName with: [
-            self generateClass: aClass source: sourceStream.
-            self generateClass: aClass class source: sourceStream.
+            self generateClass: aClass source: sourceInfo.
+            self generateClass: aClass class source: sourceInfo.
         ].
 
-        format writeSource: sourceStream contents to: sourceName
+        format writeSource: sourceInfo contents to: sourceName
 
     "Created: / 06-10-2011 / 23:54:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 01-03-2013 / 17:59:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-generateClass: aClass selector: aSelector source: sourceStream
-        | offset source matching |
-        offset := self
-                lineAndColumn: sourceStream contents
-                at: sourceStream position.
-        sourceStream
-                nextPutAll: (source := self convert: (aClass sourceCodeAt: aSelector));
-                nextPut: Character lf; nextPut: Character lf.
+generateClass: aClass selector: aSelector source: sourceInfo
+        | matching |
         matching := rules select: [ :each | 
                 (self isSelectorEnvironment: each result)
                         and: [ each result includesSelector: aSelector in: aClass ] ].
-        self generateViolations: matching class: aClass selector: aSelector source: source offset: offset
+        self generateViolations: matching class: aClass selector: aSelector source: sourceInfo
 
     "Created: / 07-10-2011 / 11:04:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 01-03-2013 / 18:10:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-generateClass: aClass source: sourceStream 
+generateClass: aClass source: sourceInfo 
 
-        | offset source matching |
-        offset := self
-                lineAndColumn: sourceStream contents
-                at: sourceStream position.
-        sourceStream
-                nextPutAll: (source := self convert: aClass definition);
-                nextPut: Character lf; nextPut: Character lf.
+        | matching |
         (environment definesClass: aClass) ifTrue: [
                 matching := rules select: [ :rule |
                         (self isClassEnvironment: rule result)
                                 and: [ rule result includesClass: aClass ] ].
-                self generateViolations: matching class: aClass selector: nil  source: source offset: offset ].
+                self generateViolations: matching class: aClass selector: nil  source: sourceInfo].
         (environment selectorsForClass: aClass) asSortedCollection
-                do: [ :selector | self generateClass: aClass selector: selector source: sourceStream]
+                do: [ :selector | self generateClass: aClass selector: selector source: sourceInfo]
 
     "Created: / 07-10-2011 / 10:29:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 01-03-2013 / 18:11:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-generateViolations: aCollection class: aClass selector: aSelector source: aString offset: aPoint
+generateViolations: aCollection class: aClass selector: aSelector source: sourceInfo
+    | method offset  |
 
+    method := aClass compiledMethodAt: aSelector.
+    offset := sourceInfo offsetOfMethod: method.
     aCollection do: [ :rule |
         | interval start stop |
     
-        interval := (rule result selectionIntervalFor: aString) ifNil: [ 1 to: aString size ].
-        start := self lineAndColumn: aString at: interval first.
-        stop  := self lineAndColumn: aString at: interval last.
+        interval := (rule result selectionIntervalFor: method source) isNil ifTrue: [ 1 to: method source size ].
+        start := sourceInfo lineAndColumnOfOffset: offset + interval first - 1.
+        stop  := sourceInfo lineAndColumnOfOffset: offset + interval last - 1.
 
         format writeViolation: rule
                    class: aClass selector: aSelector
-               startLine: aPoint x + start x column: aPoint y + start y - 1
-                stopLine: aPoint x + stop x  column: aPoint y + stop  y - 1.
+               startLine: start x column: start y
+                stopLine: stop x  column: stop  y.
     ]
 
-    "Created: / 25-11-2011 / 22:23:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Created: / 01-03-2013 / 18:05:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !LintReport methodsFor:'initialization'!
@@ -182,10 +190,11 @@
 
 sourceFilenameFor: aClass
 
-    | fn |
+    | fn cls |
 
-    fn := aClass package asString replaceAll:$: with:$_;replaceAll:$/ with:$_.
-    fn := fn , '_' , (aClass asString copyReplaceAll:$: with: $_), '.' , aClass programmingLanguage sourceFileSuffix.
+    cls := aClass theNonMetaclass.
+    fn := cls package asString replaceAll:$: with:$_;replaceAll:$/ with:$_.
+    fn := fn , '_' , (cls asString copyReplaceAll:$: with: $_), '.' , cls programmingLanguage sourceFileSuffix.
     
     ^self encodeFilename: fn.
 
@@ -198,6 +207,7 @@
     "
 
     "Created: / 07-10-2011 / 09:06:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 01-03-2013 / 18:00:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !LintReport methodsFor:'running'!
@@ -255,6 +265,170 @@
 	^ #(SelectorEnvironment ParseTreeEnvironment VariableEnvironment) includes: anEnvironment class name
 ! !
 
+!LintReport::SourceInfo class methodsFor:'instance creation'!
+
+for: aClass
+    ^self new setClass: aClass
+
+    "Created: / 01-03-2013 / 17:50:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!LintReport::SourceInfo methodsFor:'initialization'!
+
+setClass: aClass
+    klass := aClass theNonMetaclass.
+    self setup.
+
+    "Created: / 01-03-2013 / 17:49:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+setup
+    "To be called after class is set"
+
+    | stream |
+
+    stream := LineCountingStream new.
+    offsets := Dictionary new.
+
+    [
+        self fileOutOn: stream.
+    ] on: AbstractSourceFileWriter methodSourceRewriteQuery do:[:rewriteQuery |
+        | m |
+
+        m := rewriteQuery method.
+        offsets at: m put: stream position + 1.
+        rewriteQuery proceed.
+    ].
+    lineEnds := stream lineEnds
+
+    "
+        SourceInfo for: Builder::ReportRunner
+    "
+
+    "Created: / 01-03-2013 / 17:30:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!LintReport::SourceInfo methodsFor:'utilities'!
+
+fileOutOn:aStream
+    klass fileOutOn: aStream withTimeStamp:false
+
+    "Created: / 01-03-2013 / 17:51:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!LintReport::SourceInfo::LineCountingStream class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
+!LintReport::SourceInfo::LineCountingStream methodsFor:'accessing'!
+
+contents
+    "return the entire contents of the stream.
+     For a readStream, that is the rest (i.e. upToEnd),
+     for a writeStream, that is the collected data. As we do not know here,
+     what we are, this is the responsibility of a subclass..."
+
+    ^ self shouldNotImplement
+
+    "Modified: / 01-03-2013 / 17:36:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+lineEnds
+    ^ lineEnds
+!
+
+position
+    ^ position
+! !
+
+!LintReport::SourceInfo::LineCountingStream methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    "/ please change as required (and remove this comment)
+    position := 0.
+    lineEnds := OrderedCollection new.
+
+    "/ super initialize.   -- commented since inherited method does nothing
+
+    "Modified: / 01-03-2013 / 17:39:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!LintReport::SourceInfo::LineCountingStream methodsFor:'queries'!
+
+isReadable
+    "return true, if reading is supported by the recevier.
+     This has to be redefined in concrete subclasses."
+
+    ^ false
+
+    "Modified: / 01-03-2013 / 17:36:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isWritable
+    "return true, if writing is supported by the recevier.
+     This has to be redefined in concrete subclasses."
+
+    ^ true
+
+    "Modified: / 01-03-2013 / 17:37:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+size
+    "return the number of elements in the streamed collection."
+
+    ^ self shouldImplement
+! !
+
+!LintReport::SourceInfo::LineCountingStream methodsFor:'reading'!
+
+next
+    "return the next element of the stream
+     - we do not know here how to do it, it must be redefined in subclass"
+
+    ^ self shouldNotImplement
+
+    "Modified: / 01-03-2013 / 17:37:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!LintReport::SourceInfo::LineCountingStream methodsFor:'testing'!
+
+atEnd
+    "return true if the end of the stream has been reached;
+     - we do not know here how to do it, it must be redefined in subclass"
+
+    ^ false
+
+    "Modified: / 01-03-2013 / 17:37:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isEmpty
+    "return true, if the contents of the stream is empty"
+
+    ^ self shouldNotImplement
+
+    "Modified: / 01-03-2013 / 17:37:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!LintReport::SourceInfo::LineCountingStream methodsFor:'writing'!
+
+nextPut:aCharacter
+    "put the argument, anObject onto the receiver
+     - we do not know here how to do it, it must be redefined in subclass"
+
+     position := position + 1.
+    aCharacter == Character cr ifTrue:[
+        lineEnds add: position
+    ].
+
+    "Modified: / 01-03-2013 / 17:39:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !LintReport class methodsFor:'documentation'!
 
 version