--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/reports/Builder__ReportSourceInfo.st Tue Jun 25 20:28:28 2013 +0200
@@ -0,0 +1,243 @@
+"{ Package: 'stx:goodies/builder/reports' }"
+
+"{ NameSpace: Builder }"
+
+Object subclass:#ReportSourceInfo
+ instanceVariableNames:'klass filename offsets lineEnds'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Builder-Reports-Utils'
+!
+
+Stream subclass:#LineCountingStream
+ instanceVariableNames:'position lineEnds'
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:ReportSourceInfo
+!
+
+!ReportSourceInfo class methodsFor:'documentation'!
+
+documentation
+"
+ Utility class to map line numbers in methods to global
+ line number in source file (in chunk-formatted .st file)
+
+ [author:]
+ Jan Vrany <jan.vrany@fit.cvut.cz>
+
+ [instance variables:]
+
+ [class variables:]
+
+ [see also:]
+
+"
+! !
+
+!ReportSourceInfo class methodsFor:'instance creation'!
+
+for: aClass
+ ^self new setClass: aClass
+
+ "Created: / 01-03-2013 / 17:50:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ReportSourceInfo 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>"
+ "Modified: / 03-03-2013 / 11:09:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ReportSourceInfo methodsFor:'queries'!
+
+lineAndColumnOfOffset: offset
+ | low high middle element line col |
+
+ low := 1.
+ high := lineEnds size.
+ [low > high] whileFalse:[
+ middle := (low + high) // 2.
+ element := lineEnds at:middle.
+ element < offset ifTrue:[
+ "middleelement is smaller than object"
+ low := middle + 1
+ ] ifFalse:[
+ high := middle - 1
+ ]
+ ].
+
+ line := low.
+ col := offset - (line > 1 ifTrue:[lineEnds at: line - 1] ifFalse:[0]).
+ ^line @ col.
+
+ "Created: / 03-03-2013 / 10:50:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+offsetOfMethod: aMethod
+ ^offsets at: aMethod
+
+ "Created: / 03-03-2013 / 10:49:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ReportSourceInfo methodsFor:'utilities'!
+
+fileOutOn:aStream
+ klass fileOutOn: aStream withTimeStamp:false
+
+ "Created: / 01-03-2013 / 17:51:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ReportSourceInfo::LineCountingStream class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ ^ self basicNew initialize.
+! !
+
+!ReportSourceInfo::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
+! !
+
+!ReportSourceInfo::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>"
+! !
+
+!ReportSourceInfo::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
+! !
+
+!ReportSourceInfo::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>"
+! !
+
+!ReportSourceInfo::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>"
+! !
+
+!ReportSourceInfo::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>"
+! !
+
+!ReportSourceInfo class methodsFor:'documentation'!
+
+version
+ ^ '$Header$'
+!
+
+version_CVS
+ ^ '$Header$'
+! !
+