reports/Builder__ReportSourceInfo.st
author Claus Gittinger <cg@exept.de>
Thu, 28 Mar 2019 13:54:38 +0100
changeset 542 aa25a71be62a
parent 263 44b4bd0b1cd8
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 Object subclass:#ReportSourceInfo
     6 	instanceVariableNames:'offsets lineEnds package'
     7 	classVariableNames:''
     8 	poolDictionaries:''
     9 	category:'Builder-Reports-Utils'
    10 !
    11 
    12 Stream subclass:#LineCountingStream
    13 	instanceVariableNames:'position lineEnds'
    14 	classVariableNames:''
    15 	poolDictionaries:''
    16 	privateIn:ReportSourceInfo
    17 !
    18 
    19 !ReportSourceInfo class methodsFor:'documentation'!
    20 
    21 documentation
    22 "
    23     Utility class to map line numbers in methods to global 
    24     line number in source file (in chunk-formatted .st file)
    25 
    26     [author:]
    27         Jan Vrany <jan.vrany@fit.cvut.cz>
    28 
    29     [instance variables:]
    30 
    31     [class variables:]
    32 
    33     [see also:]
    34 
    35 "
    36 ! !
    37 
    38 !ReportSourceInfo class methodsFor:'instance creation'!
    39 
    40 forClass: class  inPackage: pkg
    41     ^ ReportClassSourceInfo new initializeWithPackage:pkg class:class.
    42 
    43     "Created: / 29-07-2013 / 18:36:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    44 !
    45 
    46 forExtensionsInPackage: pkg
    47     ^ ReportExtensionsSourceInfo new initializeWithPackage: pkg
    48 
    49     "Created: / 29-07-2013 / 18:37:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    50 ! !
    51 
    52 !ReportSourceInfo methodsFor:'accessing'!
    53 
    54 pathNameAbsolute: aBoolean
    55     "Return a path (as String) to file containing the source code. The file points to the
    56      real source file. If `aBoolean` is true, then absolute path is returned, otherwise
    57      realtive path to package root is returned."  
    58 
    59     ^ self subclassResponsibility
    60 
    61     "Created: / 16-12-2014 / 10:25:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    62 ! !
    63 
    64 !ReportSourceInfo methodsFor:'initialization'!
    65 
    66 setup
    67     "To be called after class is set"
    68 
    69     | stream |
    70 
    71     stream := LineCountingStream new.
    72     offsets := Dictionary new.
    73 
    74     [
    75         self fileOutOn: stream.
    76     ] on: AbstractSourceFileWriter methodSourceRewriteQuery do:[:rewriteQuery |
    77         | m p |
    78 
    79         m := rewriteQuery method.
    80         offsets at: m put: stream position.
    81         rewriteQuery proceed.
    82     ].
    83     lineEnds := stream lineEnds.
    84 
    85     "/Now, check if all is correct...
    86 "/    offsets keysAndValuesDo:[:method :offset |
    87 "/        sourceF := method package == klass package 
    88 "/                    ifTrue:[(Smalltalk getPackageDirectoryForPackage: klass package) / ((Smalltalk fileNameForClass: klass) , '.st')]
    89 "/                    ifFalse:[(Smalltalk getPackageDirectoryForPackage: method package) / 'extensions.st'].                       
    90 "/        sourceF readingFileDo:[:sourceS|
    91 "/            | source |
    92 "/
    93 "/            sourceS position: offset.
    94 "/            source := sourceS nextChunk.
    95 "/"/            self assert: method source = source.
    96 "/        ]
    97 "/    ].
    98     self validate.
    99 
   100 
   101 
   102 
   103     "
   104         ReportSourceInfo for: Builder::ReportRunner
   105     "
   106 
   107     "Created: / 01-03-2013 / 17:30:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   108     "Modified: / 29-07-2013 / 18:20:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   109 ! !
   110 
   111 !ReportSourceInfo methodsFor:'queries'!
   112 
   113 lineAndColumnOfOffset: offset
   114     | low high middle element line col |
   115 
   116     low := 1.
   117     high := lineEnds size.
   118     [low > high] whileFalse:[
   119         middle := (low + high) // 2.
   120         element := lineEnds at:middle.
   121         element <= offset ifTrue:[
   122             "middleelement is smaller than object"
   123             low := middle + 1
   124         ] ifFalse:[
   125             high := middle - 1
   126         ]
   127     ].
   128 
   129     line := low.
   130     col := offset - (line > 1 ifTrue:[lineEnds at: line - 1] ifFalse:[0]).
   131     ^line @ col.
   132 
   133     "Created: / 03-03-2013 / 10:50:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   134     "Modified: / 29-07-2013 / 18:21:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   135 !
   136 
   137 offsetOfMethod: aMethod
   138     ^offsets at: aMethod
   139 
   140     "Created: / 03-03-2013 / 10:49:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   141 ! !
   142 
   143 !ReportSourceInfo methodsFor:'utilities'!
   144 
   145 fileOutOn:arg
   146     "raise an error: must be redefined in concrete subclass(es)"
   147 
   148     ^ self subclassResponsibility
   149 !
   150 
   151 validate
   152     ^ self subclassResponsibility
   153 
   154     "Created: / 29-07-2013 / 14:52:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   155 !
   156 
   157 validateAgainstReference: referenceFile
   158 
   159     referenceFile readingFileDo:[:sourceS|
   160         offsets keysAndValuesDo:[:method :offset |
   161             | source |
   162 
   163             sourceS position: offset.
   164             source := sourceS nextChunk.
   165 "/            self assert: method source = source.
   166         ]
   167     ].
   168 
   169     "Created: / 29-07-2013 / 14:52:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   170     "Modified: / 29-07-2013 / 19:20:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   171 ! !
   172 
   173 !ReportSourceInfo::LineCountingStream class methodsFor:'instance creation'!
   174 
   175 new
   176     "return an initialized instance"
   177 
   178     ^ self basicNew initialize.
   179 ! !
   180 
   181 !ReportSourceInfo::LineCountingStream methodsFor:'accessing'!
   182 
   183 contents
   184     "return the entire contents of the stream.
   185      For a readStream, that is the rest (i.e. upToEnd),
   186      for a writeStream, that is the collected data. As we do not know here,
   187      what we are, this is the responsibility of a subclass..."
   188 
   189     ^ self shouldNotImplement
   190 
   191     "Modified: / 01-03-2013 / 17:36:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   192 !
   193 
   194 lineEnds
   195     ^ lineEnds
   196 !
   197 
   198 position
   199     ^ position
   200 ! !
   201 
   202 !ReportSourceInfo::LineCountingStream methodsFor:'initialization'!
   203 
   204 initialize
   205     "Invoked when a new instance is created."
   206 
   207     "/ please change as required (and remove this comment)
   208     position := 0.
   209     lineEnds := OrderedCollection new.
   210 
   211     "/ super initialize.   -- commented since inherited method does nothing
   212 
   213     "Modified: / 01-03-2013 / 17:39:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   214 ! !
   215 
   216 !ReportSourceInfo::LineCountingStream methodsFor:'queries'!
   217 
   218 isReadable
   219     "return true, if reading is supported by the recevier.
   220      This has to be redefined in concrete subclasses."
   221 
   222     ^ false
   223 
   224     "Modified: / 01-03-2013 / 17:36:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   225 !
   226 
   227 isWritable
   228     "return true, if writing is supported by the recevier.
   229      This has to be redefined in concrete subclasses."
   230 
   231     ^ true
   232 
   233     "Modified: / 01-03-2013 / 17:37:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   234 !
   235 
   236 size
   237     "return the number of elements in the streamed collection."
   238 
   239     ^ self shouldImplement
   240 ! !
   241 
   242 !ReportSourceInfo::LineCountingStream methodsFor:'reading'!
   243 
   244 next
   245     "return the next element of the stream
   246      - we do not know here how to do it, it must be redefined in subclass"
   247 
   248     ^ self shouldNotImplement
   249 
   250     "Modified: / 01-03-2013 / 17:37:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   251 ! !
   252 
   253 !ReportSourceInfo::LineCountingStream methodsFor:'testing'!
   254 
   255 atEnd
   256     "return true if the end of the stream has been reached;
   257      - we do not know here how to do it, it must be redefined in subclass"
   258 
   259     ^ false
   260 
   261     "Modified: / 01-03-2013 / 17:37:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   262 !
   263 
   264 isEmpty
   265     "return true, if the contents of the stream is empty"
   266 
   267     ^ self shouldNotImplement
   268 
   269     "Modified: / 01-03-2013 / 17:37:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   270 ! !
   271 
   272 !ReportSourceInfo::LineCountingStream methodsFor:'writing'!
   273 
   274 nextPut:aCharacter
   275     "put the argument, anObject onto the receiver
   276      - we do not know here how to do it, it must be redefined in subclass"
   277 
   278      position := position + 1.
   279     aCharacter == Character cr ifTrue:[
   280         lineEnds add: position
   281     ].
   282 
   283     "Modified: / 01-03-2013 / 17:39:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   284 ! !
   285 
   286 !ReportSourceInfo class methodsFor:'documentation'!
   287 
   288 version
   289     ^ '$Header$'
   290 !
   291 
   292 version_CVS
   293     ^ '$Header$'
   294 ! !
   295