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