6008 |
6009 |
6009 oldSelection notNil ifTrue:[ |
6010 oldSelection notNil ifTrue:[ |
6010 variableListView selectElement:oldSelection. |
6011 variableListView selectElement:oldSelection. |
6011 self hilightMethodsInMethodCategoryList:true inMethodList:true. |
6012 self hilightMethodsInMethodCategoryList:true inMethodList:true. |
6012 ] |
6013 ] |
|
6014 !! !! |
|
6015 |
|
6016 !!BrowserView class methodsFor:'documentation'!! |
|
6017 |
|
6018 version |
|
6019 ^ '$Header: /cvs/stx/stx/libtool/BrowserView.st,v 1.58 1995-12-07 12:26:14 cg Exp $'!! !! |
|
6020 BrowserView initialize!! |
|
6021 ! |
|
6022 |
|
6023 classPrimitiveFunctions |
|
6024 "show the classes primitiveFunctions in the codeView. |
|
6025 Also, set accept action to change it." |
|
6026 |
|
6027 self classShowFrom:#primitiveFunctionsString |
|
6028 set:#primitiveFunctions: |
|
6029 aspect:#primitiveFunctions |
|
6030 default:'%{ |
|
6031 |
|
6032 /* |
|
6033 * any local C (helper) functions |
|
6034 * come here (please, define as static) |
|
6035 */ |
|
6036 |
|
6037 %}' |
|
6038 !! |
|
6039 |
|
6040 classPrimitiveVariables |
|
6041 "show the classes primitiveVariables in the codeView. |
|
6042 Also, set accept action to change it." |
|
6043 |
|
6044 self classShowFrom:#primitiveVariablesString |
|
6045 set:#primitiveVariables: |
|
6046 aspect:#primitiveVariables |
|
6047 default:'%{ |
|
6048 |
|
6049 /* |
|
6050 * any local C variables |
|
6051 * come here (please, define as static) |
|
6052 */ |
|
6053 |
|
6054 %}' |
|
6055 !! |
|
6056 |
|
6057 classPrintOut |
|
6058 self classPrintOutWith:#printOutOn: |
|
6059 !! |
|
6060 |
|
6061 classPrintOutFullProtocol |
|
6062 self classPrintOutWith:#printOutFullProtocolOn: |
|
6063 !! |
|
6064 |
|
6065 classPrintOutProtocol |
|
6066 self classPrintOutWith:#printOutProtocolOn: |
|
6067 !! |
|
6068 |
|
6069 classPrintOutWith:aSelector |
|
6070 self doClassMenu:[:currentClass | |
|
6071 |printStream| |
|
6072 |
|
6073 printStream := Printer new. |
|
6074 currentClass perform:aSelector with:printStream. |
|
6075 printStream close |
|
6076 ] |
|
6077 !! |
|
6078 |
|
6079 classProtocols |
|
6080 ^ self |
|
6081 !! |
|
6082 |
|
6083 classRefs |
|
6084 self doClassMenu:[:currentClass | |
|
6085 self withSearchCursorDo:[ |
|
6086 SystemBrowser browseReferendsOf:currentClass name asSymbol |
|
6087 ] |
|
6088 ] |
|
6089 |
|
6090 "Created: 23.11.1995 / 14:11:43 / cg" |
|
6091 !! |
|
6092 |
|
6093 classRemove |
|
6094 "user requested remove of current class and all subclasses - |
|
6095 count subclasses and let user confirm removal." |
|
6096 |
|
6097 |count t box| |
|
6098 |
|
6099 currentClass notNil ifTrue:[ |
|
6100 count := currentClass allSubclasses size. |
|
6101 t := 'remove %1'. |
|
6102 count ~~ 0 ifTrue:[ |
|
6103 t := t , '\(with %2 subclass'. |
|
6104 count ~~ 1 ifTrue:[ |
|
6105 t := t , 'es' |
|
6106 ]. |
|
6107 t := (t , ')') |
|
6108 ]. |
|
6109 t := t , ' ?'. |
|
6110 t := (resources string:t with:currentClass name with:count) withCRs. |
|
6111 |
|
6112 box := YesNoBox |
|
6113 title:t |
|
6114 yesText:(resources at:'remove') |
|
6115 noText:(resources at:'abort'). |
|
6116 box confirm ifTrue:[ |
|
6117 "after querying user - do really remove current class |
|
6118 and all subclasses |
|
6119 " |
|
6120 self doClassMenu:[:currentClass | |
|
6121 |didRemove| |
|
6122 |
|
6123 didRemove := false. |
|
6124 |
|
6125 " |
|
6126 query ? |
|
6127 " |
|
6128 currentClass allSubclassesDo:[:aSubClass | |
|
6129 (CheckForInstancesWhenRemovingClasses not |
|
6130 or:[aSubClass hasInstances not |
|
6131 or:[self confirm:(aSubClass name , ' has instances - remove anyway ?')]]) |
|
6132 ifTrue:[ |
|
6133 Smalltalk removeClass:aSubClass |
|
6134 ] |
|
6135 ]. |
|
6136 (CheckForInstancesWhenRemovingClasses not |
|
6137 or:[currentClass hasInstances not |
|
6138 or:[self confirm:(currentClass name , ' has instances - remove anyway ?')]]) |
|
6139 ifTrue:[ |
|
6140 didRemove := true. |
|
6141 Smalltalk removeClass:currentClass. |
|
6142 ]. |
|
6143 |
|
6144 self switchToClass:nil. |
|
6145 Smalltalk changed. |
|
6146 self updateClassList. |
|
6147 |
|
6148 "if it was the last in its category, update class category list" |
|
6149 " |
|
6150 classListView numberOfLines == 0 ifTrue:[ |
|
6151 self updateClassCategoryListWithScroll:false |
|
6152 ]. |
|
6153 " |
|
6154 didRemove ifTrue:[ |
|
6155 methodCategoryListView notNil ifTrue:[methodCategoryListView contents:nil]. |
|
6156 methodListView notNil ifTrue:[methodListView contents:nil]. |
|
6157 codeView contents:nil. |
|
6158 codeView modified:false |
|
6159 ] |
|
6160 ] |
|
6161 ] |
|
6162 ] |
|
6163 !! |
|
6164 |
|
6165 classRename |
|
6166 "launch an enterBox for new name and query user" |
|
6167 |
|
6168 |box| |
|
6169 |
|
6170 self checkClassSelected ifFalse:[^ self]. |
|
6171 box := self enterBoxTitle:(resources string:'rename %1 to:' with:currentClass name) okText:'rename'. |
|
6172 box initialText:(currentClass name). |
|
6173 box action:[:aString | self renameCurrentClassTo:aString]. |
|
6174 box showAtPointer |
|
6175 !! |
|
6176 |
|
6177 classShowFrom:getSelector set:setSelector aspect:aspectSymbol default:default |
|
6178 "common helper for comment, primitive-stuff etc. |
|
6179 show the string returned from the classes getSelector-method, |
|
6180 Set acceptaction to change it via setSelector." |
|
6181 |
|
6182 self doClassMenu:[:currentClass | |
|
6183 |text| |
|
6184 |
|
6185 text := currentClass perform:getSelector. |
|
6186 text isNil ifTrue:[ |
|
6187 text := default |
|
6188 ]. |
|
6189 codeView contents:text. |
|
6190 codeView modified:false. |
|
6191 codeView acceptAction:[:theCode | |
|
6192 Object abortSignal catch:[ |
|
6193 lockUpdates := true. |
|
6194 currentClass perform:setSelector with:theCode asString. |
|
6195 codeView modified:false. |
|
6196 ]. |
|
6197 lockUpdates := false. |
|
6198 ]. |
|
6199 codeView explainAction:nil. |
|
6200 |
|
6201 methodListView notNil ifTrue:[ |
|
6202 methodListView deselect |
|
6203 ]. |
|
6204 aspect := aspectSymbol. |
|
6205 self normalLabel |
|
6206 ] |
|
6207 !! |
|
6208 |
|
6209 classSpawn |
|
6210 "create a new SystemBrowser browsing current class, |
|
6211 or if there is a selection, spawn a browser on the selected class |
|
6212 even a class/selector pair can be specified." |
|
6213 |
|
6214 self doClassMenuWithSelection:[:cls :sel | |
|
6215 |browser| |
|
6216 |
|
6217 cls isMeta ifTrue:[ |
|
6218 Smalltalk allBehaviorsDo:[:aClass | |
|
6219 aClass class == cls ifTrue:[ |
|
6220 browser := SystemBrowser browseClass:aClass. |
|
6221 browser instanceProtocol:false. |
|
6222 sel notNil ifTrue:[ |
|
6223 browser switchToMethodNamed:sel |
|
6224 ]. |
|
6225 ^ self |
|
6226 ]. |
|
6227 ]. |
|
6228 self warn:'oops, no class for this metaclass'. |
|
6229 ^ self |
|
6230 ]. |
|
6231 browser := SystemBrowser browseClass:cls. |
|
6232 cls hasMethods ifFalse:[ |
|
6233 browser instanceProtocol:false. |
|
6234 ]. |
|
6235 sel notNil ifTrue:[ |
|
6236 browser switchToMethodNamed:sel |
|
6237 ]. |
|
6238 ] |
|
6239 |
|
6240 " |
|
6241 select 'Smalltalk allClassesDo:' and use spawn from the class menu |
|
6242 select 'Smalltalk' and use spawn from the class menu |
|
6243 " |
|
6244 !! |
|
6245 |
|
6246 classSpawnFullProtocol |
|
6247 "create a new browser, browsing current classes full protocol" |
|
6248 |
|
6249 self doClassMenuWithSelection:[:cls :sel | |
|
6250 SystemBrowser browseFullClassProtocol:cls |
|
6251 ] |
|
6252 !! |
|
6253 |
|
6254 classSpawnHierarchy |
|
6255 "create a new HierarchyBrowser browsing current class" |
|
6256 |
|
6257 self doClassMenuWithSelection:[:cls :sel | |
|
6258 SystemBrowser browseClassHierarchy:cls |
|
6259 ] |
|
6260 !! |
|
6261 |
|
6262 classSpawnSubclasses |
|
6263 "create a new browser browsing current class's subclasses" |
|
6264 |
|
6265 self doClassMenuWithSelection:[:cls :sel | |
|
6266 |subs| |
|
6267 |
|
6268 subs := cls allSubclasses. |
|
6269 (subs notNil and:[subs size ~~ 0]) ifTrue:[ |
|
6270 SystemBrowser browseClasses:subs title:('subclasses of ' , cls name) |
|
6271 ] |
|
6272 ] |
|
6273 !! |
|
6274 |
|
6275 classUnload |
|
6276 "unload an autoloaded class" |
|
6277 |
|
6278 |nm| |
|
6279 |
|
6280 self checkClassSelected ifFalse:[^ self]. |
|
6281 nm := currentClass name. |
|
6282 currentClass unload. |
|
6283 self switchToClassNamed:nm |
|
6284 !! |
|
6285 |
|
6286 classUses |
|
6287 "a powerful tool, when trying to learn more about where |
|
6288 a class is used. This one searches all uses of a class, |
|
6289 and shows a list of uses - try it and like it" |
|
6290 |
|
6291 self doClassMenu:[:currentClass | |
|
6292 self withSearchCursorDo:[ |
|
6293 SystemBrowser browseUsesOf:currentClass |
|
6294 ] |
|
6295 ] |
|
6296 |
|
6297 "Created: 23.11.1995 / 14:11:47 / cg" |
|
6298 !! |
|
6299 |
|
6300 doClassMenuWithSelection:aBlock |
|
6301 "a helper - if there is a selection, which represents a classes name, |
|
6302 evaluate aBlock, passing that class and optional selector as arguments. |
|
6303 Otherwise, check if a class is selected and evaluate aBlock with the |
|
6304 current class." |
|
6305 |
|
6306 |string words clsName cls sel isMeta| |
|
6307 |
|
6308 string := codeView selection. |
|
6309 string notNil ifTrue:[ |
|
6310 self extractClassAndSelectorFromSelectionInto:[:c :s :m | |
|
6311 clsName := c. |
|
6312 sel := s. |
|
6313 isMeta := m. |
|
6314 ]. |
|
6315 clsName isNil ifTrue:[ |
|
6316 string := string asString withoutSeparators. |
|
6317 words := string asCollectionOfWords. |
|
6318 words notNil ifTrue:[ |
|
6319 clsName := words first. |
|
6320 (clsName endsWith:'class') ifTrue:[ |
|
6321 isMeta := true. |
|
6322 clsName := clsName copyWithoutLast:5 "copyTo:(clsName size - 5)" |
|
6323 ] ifFalse:[ |
|
6324 isMeta := false |
|
6325 ]. |
|
6326 sel := Parser selectorInExpression:string. |
|
6327 ] |
|
6328 ]. |
|
6329 clsName notNil ifTrue:[ |
|
6330 (cls := Smalltalk classNamed:clsName) notNil ifTrue:[ |
|
6331 isMeta ifTrue:[ |
|
6332 cls := cls class |
|
6333 ]. |
|
6334 self withWaitCursorDo:[ |
|
6335 aBlock value:cls value:sel. |
|
6336 ]. |
|
6337 ^ self |
|
6338 ] ifFalse:[ |
|
6339 self warn:'no class named: %1 - spawning current' with:clsName |
|
6340 ] |
|
6341 ]. |
|
6342 ]. |
|
6343 |
|
6344 classMethodListView notNil ifTrue:[ |
|
6345 sel := classMethodListView selectionValue. |
|
6346 sel notNil ifTrue:[ |
|
6347 sel := self selectorFromClassMethodString:sel |
|
6348 ] |
|
6349 ]. |
|
6350 self doClassMenu:[:currentClass | aBlock value:currentClass value:sel] |
|
6351 !! !! |
|
6352 |
|
6353 !!BrowserView methodsFor:'class list source administration'!! |
|
6354 |
|
6355 classCreateSourceContainerFor:aClass |
|
6356 "let user specify the source-repository values for aClass" |
|
6357 |
|
6358 |box |
|
6359 moduleDirectory subDirectory |
|
6360 fileName specialFlags |
|
6361 check y component info fn project| |
|
6362 |
|
6363 moduleDirectory := 'stx' asValue. |
|
6364 subDirectory := '' asValue. |
|
6365 |
|
6366 (Project notNil and:[(project := Project current) notNil]) ifTrue:[ |
|
6367 subDirectory value:(project name) |
|
6368 ]. |
|
6369 |
|
6370 info := SourceCodeManager sourceInfoOfClass:aClass. |
|
6371 info notNil ifTrue:[ |
|
6372 (info includesKey:#module) ifTrue:[ |
|
6373 moduleDirectory value:(info at:#module). |
|
6374 ]. |
|
6375 (info includesKey:#directory) ifTrue:[ |
|
6376 subDirectory value:(info at:#directory). |
|
6377 ]. |
|
6378 (info includesKey:#expectedFileName) ifTrue:[ |
|
6379 fn := (info at:#expectedFileName). |
|
6380 ] ifFalse:[ |
|
6381 (info includesKey:#classFileName) ifTrue:[ |
|
6382 fn := (info at:#classFileName). |
|
6383 ] |
|
6384 ] |
|
6385 ]. |
|
6386 |
|
6387 fn isNil ifTrue:[ |
|
6388 fn := (Smalltalk fileNameForClass:aClass) , '.st'. |
|
6389 ]. |
|
6390 "/ |
|
6391 "/ should check for conflicts ... |
|
6392 "/ |
|
6393 |
|
6394 fileName := fn asValue. |
|
6395 |
|
6396 box := DialogBox new. |
|
6397 box label:(resources string:'Repository information for %1' with:aClass name). |
|
6398 |
|
6399 component := box addTextLabel:(resources string:'CREATE_REPOSITORY' with:currentClass name) withCRs. |
|
6400 component adjust:#left; borderWidth:0. |
|
6401 |
|
6402 y := box yPosition. |
|
6403 component := box addTextLabel:(resources string:'Module:'). |
|
6404 component width:0.5; adjust:#right. |
|
6405 box yPosition:y. |
|
6406 component := box addInputFieldOn:moduleDirectory tabable:true. |
|
6407 component width:0.5; left:0.5; immediateAccept:true; acceptOnLeave:false; cursorMovementWhenUpdating:#beginOfLine. |
|
6408 |
|
6409 box addVerticalSpace. |
|
6410 y := box yPosition. |
|
6411 component := box addTextLabel:'Package:'. |
|
6412 component width:0.5; adjust:#right. |
|
6413 box yPosition:y. |
|
6414 component := box addInputFieldOn:subDirectory tabable:true. |
|
6415 component width:0.5; left:0.5; immediateAccept:true; acceptOnLeave:false; cursorMovementWhenUpdating:#beginOfLine. |
|
6416 |
|
6417 box addVerticalSpace. |
|
6418 y := box yPosition. |
|
6419 component := box addTextLabel:'Filename:'. |
|
6420 component width:0.5; adjust:#right. |
|
6421 box yPosition:y. |
|
6422 component := box addInputFieldOn:fileName tabable:true. |
|
6423 component width:0.5; left:0.5; immediateAccept:true; acceptOnLeave:false; cursorMovementWhenUpdating:#beginOfLine. |
|
6424 |
|
6425 box addVerticalSpace. |
|
6426 box addVerticalSpace. |
|
6427 |
|
6428 box addAbortButton; addOkButton. |
|
6429 |
|
6430 box showAtPointer. |
|
6431 |
|
6432 box accepted ifTrue:[ |
|
6433 self halt. |
|
6434 ] |
|
6435 |
|
6436 "Modified: 25.11.1995 / 18:03:25 / cg" |
|
6437 !! |
|
6438 |
|
6439 classCheckin |
|
6440 "check a class into the source repository" |
|
6441 |
|
6442 self doClassMenu:[:currentClass | |
|
6443 |logMessage info| |
|
6444 |
|
6445 (info := SourceCodeManager sourceInfoOfClass:currentClass) isNil ifTrue:[ |
|
6446 ^ self classCreateSourceContainerFor:currentClass |
|
6447 ]. |
|
6448 |
|
6449 logMessage := Dialog |
|
6450 request:'enter a log message:' |
|
6451 initialAnswer:lastSourceLogMessage |
|
6452 onCancel:nil. |
|
6453 |
|
6454 logMessage notNil ifTrue:[ |
|
6455 lastSourceLogMessage := logMessage. |
|
6456 self busyLabel:'checking in %1' with:currentClass name. |
|
6457 (SourceCodeManager checkinClass:currentClass logMessage:logMessage) ifFalse:[ |
|
6458 self warn:'checkin failed'. |
|
6459 ]. |
|
6460 aspect == #revisionInfo ifTrue:[ |
|
6461 self classListUpdate |
|
6462 ]. |
|
6463 self normalLabel. |
|
6464 ] |
|
6465 ] |
|
6466 |
|
6467 "Created: 23.11.1995 / 11:41:38 / cg" |
|
6468 "Modified: 3.12.1995 / 13:28:30 / cg" |
|
6469 !! |
|
6470 |
|
6471 classCompareWithNewestInRepository |
|
6472 "open a diff-textView comparing the current (in-image) version |
|
6473 with the most recent version found in the repository." |
|
6474 |
|
6475 self doClassMenu:[:currentClass | |
|
6476 |aStream comparedSource currentSource v rev revString| |
|
6477 |
|
6478 rev := Dialog request:'compare to revision: (empty for newest)'. |
|
6479 rev notNil ifTrue:[ |
|
6480 rev withoutSpaces isEmpty ifTrue:[ |
|
6481 self busyLabel:'extracting newest %1' with:currentClass name. |
|
6482 aStream := SourceCodeManager mostRecentSourceStreamForClassNamed:currentClass name. |
|
6483 revString := 'newest' |
|
6484 ] ifFalse:[ |
|
6485 self busyLabel:'extracting previous %1' with:currentClass name. |
|
6486 aStream := SourceCodeManager sourceStreamFor:currentClass revision:rev. |
|
6487 revString := rev |
|
6488 ]. |
|
6489 comparedSource := aStream contents. |
|
6490 aStream close. |
|
6491 |
|
6492 self busyLabel:'generating current source ...' with:nil. |
|
6493 |
|
6494 aStream := '' writeStream. |
|
6495 currentClass fileOutOn:aStream withTimeStamp:false. |
|
6496 currentSource := aStream contents. |
|
6497 aStream close. |
|
6498 |
|
6499 self busyLabel:'comparing ...' with:nil. |
|
6500 v := DiffTextView |
|
6501 openOn:currentSource label:'current (' , currentClass revision , ')' |
|
6502 and:comparedSource label:'repository (' , revString , ')'. |
|
6503 v label:'comparing ' , currentClass name. |
|
6504 self normalLabel. |
|
6505 ] |
|
6506 ] |
|
6507 |
|
6508 "Created: 14.11.1995 / 16:43:15 / cg" |
|
6509 "Modified: 22.11.1995 / 22:17:08 / cg" |
|
6510 !! |
|
6511 |
|
6512 classRevisionInfo |
|
6513 "show current classes revision info in codeView" |
|
6514 |
|
6515 self doClassMenu:[:currentClass | |
|
6516 |aStream info info2 s rv| |
|
6517 |
|
6518 aStream := WriteStream on:(String new:200). |
|
6519 currentClass notNil ifTrue:[ |
|
6520 self busyLabel:'extracting revision info' with:nil. |
|
6521 info := currentClass revisionInfo. |
|
6522 |
|
6523 rv := currentClass binaryRevision. |
|
6524 rv notNil ifTrue:[ |
|
6525 aStream nextPutAll:'**** Loaded classes binary information ****'; cr; cr. |
|
6526 aStream nextPutAll:' Binary based upon : ' , rv; cr. |
|
6527 aStream cr. |
|
6528 ]. |
|
6529 |
|
6530 info notNil ifTrue:[ |
|
6531 aStream nextPutAll:'**** Loaded classes source information ****'; cr; cr. |
|
6532 s := info at:#repositoryPath ifAbsent:nil. |
|
6533 s notNil ifTrue:[ |
|
6534 aStream nextPut:' Source repository : ' , s; cr |
|
6535 ]. |
|
6536 aStream nextPutAll:' Filename ........ : ' , (info at:#fileName ifAbsent:'?'); cr. |
|
6537 aStream nextPutAll:' Revision ........ : ' , (info at:#revision ifAbsent:'?'); cr. |
|
6538 aStream nextPutAll:' Checkin date .... : ' , (info at:#date ifAbsent:'?') , ' ' , (info at:#time ifAbsent:'?'); cr. |
|
6539 aStream nextPutAll:' Checkin user .... : ' , (info at:#user ifAbsent:'?'); cr. |
|
6540 |
|
6541 (info2 := currentClass packageSourceCodeInfo) notNil ifTrue:[ |
|
6542 aStream nextPutAll:' Repository: ..... : ' , (info2 at:#module ifAbsent:'?'); cr. |
|
6543 aStream nextPutAll:' Directory: ...... : ' , (info2 at:#directory ifAbsent:'?'); cr. |
|
6544 ]. |
|
6545 aStream nextPutAll:' Container ....... : ' , (info at:#repositoryPathName ifAbsent:'?'); cr. |
|
6546 aStream cr. |
|
6547 |
|
6548 SourceCodeManager notNil ifTrue:[ |
|
6549 aStream nextPutAll:'**** Repository information ****'; cr; cr. |
|
6550 SourceCodeManager writeRevisionLogOf:currentClass to:aStream. |
|
6551 ] |
|
6552 ] ifFalse:[ |
|
6553 aStream nextPutAll:'No revision info found' |
|
6554 ] |
|
6555 ]. |
|
6556 codeView contents:(aStream contents). |
|
6557 |
|
6558 codeView modified:false. |
|
6559 codeView acceptAction:nil. |
|
6560 codeView explainAction:nil. |
|
6561 methodListView notNil ifTrue:[ |
|
6562 methodListView deselect |
|
6563 ]. |
|
6564 aspect := #revisionInfo. |
|
6565 self normalLabel |
|
6566 ] |
|
6567 |
|
6568 "Created: 14.11.1995 / 16:43:15 / cg" |
|
6569 "Modified: 7.12.1995 / 11:00:56 / cg" |
|
6570 !! |
|
6571 |
|
6572 classLoadRevision |
|
6573 "load a specific revision into the system - especially useful to |
|
6574 upgrade a class to the newest revision" |
|
6575 |
|
6576 self doClassMenu:[:currentClass | |
|
6577 |aStream comparedSource currentSource v rev revString what| |
|
6578 |
|
6579 rev := Dialog request:'load which revision: (empty for newest)'. |
|
6580 rev notNil ifTrue:[ |
|
6581 rev withoutSpaces isEmpty ifTrue:[ |
|
6582 what := currentClass name , '(newest)'. |
|
6583 self busyLabel:'extracting %1' with:what. |
|
6584 aStream := SourceCodeManager mostRecentSourceStreamForClassNamed:currentClass name. |
|
6585 revString := 'newest' |
|
6586 ] ifFalse:[ |
|
6587 what := currentClass name , '(' , rev , ')'. |
|
6588 self busyLabel:'extracting %1' with:what. |
|
6589 aStream := SourceCodeManager sourceStreamFor:currentClass revision:rev. |
|
6590 revString := rev |
|
6591 ]. |
|
6592 self busyLabel:'loading %1' with:what . |
|
6593 |
|
6594 [ |
|
6595 Class withoutUpdatingChangesDo:[ |
|
6596 "/ rename the current class - for backup |
|
6597 Smalltalk renameClass:currentClass to:currentClass name , '_saved'. |
|
6598 aStream fileIn. |
|
6599 ]. |
|
6600 ] valueNowOrOnUnwindDo:[ |
|
6601 aStream close. |
|
6602 self normalLabel. |
|
6603 ]. |
|
6604 ] |
|
6605 ] |
|
6606 |
|
6607 "Created: 14.11.1995 / 16:43:15 / cg" |
|
6608 "Modified: 25.11.1995 / 10:44:38 / cg" |
|
6609 !! !! |
|
6610 |
|
6611 !!BrowserView methodsFor:'class stuff'!! |
|
6612 |
|
6613 checkClassSelected |
|
6614 "warn and return false, if no class is selected" |
|
6615 |
|
6616 currentClass isNil ifTrue:[ |
|
6617 self warn:'select a class first'. |
|
6618 ^ false |
|
6619 ]. |
|
6620 ^ true |
|
6621 !! |
|
6622 |
|
6623 classClassDefinitionTemplateFor:name in:cat |
|
6624 "common helper for newClass and newSubclass |
|
6625 - show a template to define class name in category cat. |
|
6626 Also, set acceptaction to install the class." |
|
6627 |
|
6628 currentMethodCategory := nil. |
|
6629 currentMethod := currentSelector := nil. |
|
6630 |
|
6631 classListView deselect. |
|
6632 |
|
6633 fullClass ifFalse:[ |
|
6634 methodCategoryListView contents:nil. |
|
6635 methodListView contents:nil |
|
6636 ]. |
|
6637 |
|
6638 codeView contents:(self templateFor:name in:cat). |
|
6639 codeView modified:false. |
|
6640 |
|
6641 codeView acceptAction:[:theCode | |
|
6642 codeView cursor:Cursor execute. |
|
6643 Object abortSignal catch:[ |
|
6644 |cls| |
|
6645 |
|
6646 cls := (Compiler evaluate:theCode asString notifying:codeView compile:false). |
|
6647 cls isBehavior ifTrue:[ |
|
6648 codeView modified:false. |
|
6649 self classCategoryUpdate. |
|
6650 self updateClassListWithScroll:false. |
|
6651 self switchToClassNamed:(cls name). |
|
6652 ] |
|
6653 ]. |
|
6654 codeView cursor:(Cursor normal). |
|
6655 ]. |
|
6656 codeView explainAction:nil. |
|
6657 self switchToClass:nil |
|
6658 !! |
|
6659 |
|
6660 classListUpdate |
|
6661 RememberAspect ifTrue:[ |
|
6662 aspect == #hierarchy ifTrue:[ |
|
6663 ^ self classHierarchy |
|
6664 ]. |
|
6665 aspect == #classInstVars ifTrue:[ |
|
6666 ^ self classClassInstVars |
|
6667 ]. |
|
6668 aspect == #comment ifTrue:[ |
|
6669 ^ self classComment |
|
6670 ]. |
|
6671 aspect == #primitiveDefinitions ifTrue:[ |
|
6672 ^ self classPrimitiveDefinitions |
|
6673 ]. |
|
6674 aspect == #primitiveFunctions ifTrue:[ |
|
6675 ^ self classPrimitiveFunctions |
|
6676 ]. |
|
6677 aspect == #primitiveVariables ifTrue:[ |
|
6678 ^ self classPrimitiveVariables |
|
6679 ]. |
|
6680 aspect == #revisionInfo ifTrue:[ |
|
6681 ^ self classRevisionInfo |
|
6682 ]. |
|
6683 ]. |
|
6684 self classDefinition |
|
6685 |
|
6686 "Created: 23.11.1995 / 11:28:58 / cg" |
|
6687 "Modified: 23.11.1995 / 11:36:08 / cg" |
|
6688 !! |
|
6689 |
|
6690 classSelection:lineNr |
|
6691 "user clicked on a class line - show method categories" |
|
6692 |
|
6693 |cls oldSelector| |
|
6694 |
|
6695 (currentClassHierarchy notNil |
|
6696 and:[fullProtocol]) ifTrue:[ |
|
6697 oldSelector := currentSelector. |
|
6698 |
|
6699 self updateMethodCategoryListWithScroll:false. |
|
6700 self updateMethodListWithScroll:false. |
|
6701 self updateVariableList. |
|
6702 ^ self |
|
6703 ]. |
|
6704 |
|
6705 cls := Smalltalk classNamed:classListView selectionValue withoutSpaces. |
|
6706 cls notNil ifTrue:[ |
|
6707 self switchToClass:cls. |
|
6708 self classSelectionChanged |
|
6709 ] |
|
6710 !! |
|
6711 |
|
6712 classSelectionChanged |
|
6713 |oldMethodCategory oldMethod oldSelector| |
|
6714 |
|
6715 self withWaitCursorDo:[ |
|
6716 oldMethodCategory := currentMethodCategory. |
|
6717 oldMethod := currentMethod. |
|
6718 oldSelector := currentSelector. |
|
6719 |
|
6720 showInstance ifTrue:[ |
|
6721 actualClass := acceptClass := currentClass |
|
6722 ] ifFalse:[ |
|
6723 actualClass := acceptClass := currentClass class |
|
6724 ]. |
|
6725 currentMethodCategory := nil. |
|
6726 currentMethod := nil. |
|
6727 currentSelector := nil. |
|
6728 |
|
6729 self updateVariableList. |
|
6730 self updateMethodCategoryList. |
|
6731 |
|
6732 oldMethodCategory notNil ifTrue:[ |
|
6733 methodCategoryListView selectElement:oldMethodCategory. |
|
6734 methodCategoryListView hasSelection ifTrue:[ |
|
6735 currentMethodCategory := oldMethodCategory. |
|
6736 self methodCategorySelectionChanged |
|
6737 ] |
|
6738 ]. |
|
6739 self updateMethodList. |
|
6740 self updateCodeView. |
|
6741 |
|
6742 fullClass ifTrue:[ |
|
6743 codeView acceptAction:[:theCode | |
|
6744 codeView cursor:Cursor execute. |
|
6745 Object abortSignal catch:[ |
|
6746 self compileCode:theCode asString. |
|
6747 codeView modified:false. |
|
6748 ]. |
|
6749 codeView cursor:Cursor normal. |
|
6750 ]. |
|
6751 ] ifFalse:[ |
|
6752 "/ self classDefinition. |
|
6753 self classListUpdate. |
|
6754 codeView acceptAction:[:theCode | |
|
6755 codeView cursor:Cursor execute. |
|
6756 Object abortSignal catch:[ |
|
6757 (Compiler evaluate:theCode asString notifying:codeView compile:false) |
|
6758 isBehavior ifTrue:[ |
|
6759 self classCategoryUpdate. |
|
6760 self updateClassListWithScroll:false. |
|
6761 codeView modified:false. |
|
6762 ]. |
|
6763 ]. |
|
6764 codeView cursor:Cursor normal. |
|
6765 ]. |
|
6766 ]. |
|
6767 codeView explainAction:nil. |
|
6768 |
|
6769 classCategoryListView notNil ifTrue:[ |
|
6770 (currentClassCategory = currentClass category) ifFalse:[ |
|
6771 currentClassCategory := currentClass category. |
|
6772 classCategoryListView selectElement:currentClassCategory |
|
6773 ] |
|
6774 ]. |
|
6775 |
|
6776 self setDoitActionForClass |
|
6777 ] |
|
6778 |
|
6779 "Created: 23.11.1995 / 11:32:03 / cg" |
|
6780 !! |
|
6781 |
|
6782 doClassMenu:aBlock |
|
6783 "a helper - check if class is selected and evaluate aBlock |
|
6784 while showing waitCursor" |
|
6785 |
|
6786 self checkClassSelected ifTrue:[ |
|
6787 self withWaitCursorDo:[aBlock value:currentClass] |
|
6788 ] |
|
6789 !! |
|
6790 |
|
6791 listOfAllClassesInCategory:aCategory |
|
6792 "return a list of all classes in a given category" |
|
6793 |
|
6794 |newList classes searchCategory nm| |
|
6795 |
|
6796 (aCategory = '* hierarchy *') ifTrue:[ |
|
6797 newList := OrderedCollection new. |
|
6798 classes := Set new. |
|
6799 self classHierarchyDo:[:aClass :lvl| |
|
6800 nm := aClass name. |
|
6801 (classes includes:nm) ifFalse:[ |
|
6802 classes add:nm. |
|
6803 newList add:(String new:lvl) , nm |
|
6804 ] |
|
6805 ]. |
|
6806 ^ newList |
|
6807 ]. |
|
6808 |
|
6809 newList := Set new. |
|
6810 |
|
6811 (aCategory = '* all *') ifTrue:[ |
|
6812 Smalltalk allBehaviorsDo:[:aClass | |
|
6813 newList add:aClass name |
|
6814 ] |
|
6815 ] ifFalse:[ |
|
6816 (aCategory = '* no category *') ifTrue:[ |
|
6817 searchCategory := nil |
|
6818 ] ifFalse:[ |
|
6819 searchCategory := aCategory |
|
6820 ]. |
|
6821 Smalltalk allBehaviorsDo:[:aClass | |
|
6822 |thisCategory| |
|
6823 |
|
6824 aClass isMeta ifFalse:[ |
|
6825 thisCategory := aClass category. |
|
6826 ((thisCategory = searchCategory) |
|
6827 or:[thisCategory = aCategory]) ifTrue:[ |
|
6828 newList add:aClass name |
|
6829 ] |
|
6830 ] |
|
6831 ] |
|
6832 ]. |
|
6833 (newList size == 0) ifTrue:[^ nil]. |
|
6834 ^ newList asOrderedCollection sort |
|
6835 !! |
|
6836 |
|
6837 listOfClassHierarchyOf:aClass |
|
6838 "return a hierarchy class-list" |
|
6839 |
|
6840 |startClass classes thisOne| |
|
6841 |
|
6842 showInstance ifTrue:[ |
|
6843 startClass := aClass |
|
6844 ] ifFalse:[ |
|
6845 startClass := aClass class. |
|
6846 ]. |
|
6847 classes := startClass allSuperclasses. |
|
6848 thisOne := Array with:startClass. |
|
6849 |
|
6850 classes notNil ifTrue:[ |
|
6851 classes := classes reverse , thisOne. |
|
6852 ] ifFalse:[ |
|
6853 classes := thisOne |
|
6854 ]. |
|
6855 |
|
6856 fullProtocol ifFalse:[ |
|
6857 classes := classes , startClass allSubclassesInOrder |
|
6858 ]. |
|
6859 ^ classes collect:[:c | c name] |
|
6860 !! |
|
6861 |
|
6862 renameCurrentClassTo:aString |
|
6863 "helper - do the rename" |
|
6864 |
|
6865 self doClassMenu:[:currentClass | |
|
6866 |oldName oldSym newSym cls| |
|
6867 |
|
6868 (cls := Smalltalk classNamed:aString) notNil ifTrue:[ |
|
6869 (self confirm:(resources string:'WARN_RENAME' with:aString with:cls category)) |
|
6870 ifFalse:[^ self] |
|
6871 ]. |
|
6872 |
|
6873 oldName := currentClass name. |
|
6874 oldSym := oldName asSymbol. |
|
6875 " |
|
6876 currentClass setName:aString. |
|
6877 newSym := aString asSymbol. |
|
6878 Smalltalk at:oldSym put:nil. |
|
6879 Smalltalk removeKey:oldSym. |
|
6880 Smalltalk at:newSym put:currentClass. |
|
6881 " |
|
6882 " |
|
6883 currentClass renameTo:aString. |
|
6884 " |
|
6885 Smalltalk renameClass:currentClass to:aString. |
|
6886 |
|
6887 self updateClassList. |
|
6888 self updateMethodCategoryListWithScroll:false. |
|
6889 self updateMethodListWithScroll:false. |
|
6890 self withWaitCursorDo:[ |
|
6891 Transcript showCr:('searching for users of ' , oldSym); endEntry. |
|
6892 SystemBrowser browseReferendsOf:oldSym warnIfNone:false |
|
6893 ] |
|
6894 ] |
|
6895 |
|
6896 "Created: 25.11.1995 / 13:02:53 / cg" |
|
6897 !! |
|
6898 |
|
6899 switchToClass:newClass |
|
6900 "switch to some other class; |
|
6901 keep instance protocol as it was ..." |
|
6902 |
|
6903 |cls meta| |
|
6904 |
|
6905 fullProtocol ifTrue:[^ self]. |
|
6906 |
|
6907 cls := newClass. |
|
6908 (meta := cls isMeta) ifTrue:[ |
|
6909 cls := cls soleInstance |
|
6910 ]. |
|
6911 currentClass notNil ifTrue:[ |
|
6912 currentClass removeDependent:self |
|
6913 ]. |
|
6914 currentClass := cls. |
|
6915 showInstance ifTrue:[ |
|
6916 actualClass := acceptClass := cls. |
|
6917 ] ifFalse:[ |
|
6918 actualClass := acceptClass := cls class. |
|
6919 ]. |
|
6920 |
|
6921 currentClass notNil ifTrue:[ |
|
6922 currentClass addDependent:self. |
|
6923 ]. |
|
6924 self normalLabel. |
|
6925 |
|
6926 "Modified: 1.9.1995 / 01:04:05 / claus" |
|
6927 !! |
|
6928 |
|
6929 switchToClassNameMatching:aMatchString |
|
6930 |classNames thisName box| |
|
6931 |
|
6932 classNames := OrderedCollection new. |
|
6933 Smalltalk allBehaviorsDo:[:aClass | |
|
6934 thisName := aClass name. |
|
6935 (aMatchString match:thisName) ifTrue:[ |
|
6936 classNames add:thisName |
|
6937 ] |
|
6938 ]. |
|
6939 (classNames size == 0) ifTrue:[^ nil]. |
|
6940 (classNames size == 1) ifTrue:[ |
|
6941 ^ self switchToClassNamed:(classNames at:1) |
|
6942 ]. |
|
6943 |
|
6944 box := self listBoxTitle:'select class to switch to:' |
|
6945 okText:'ok' |
|
6946 list:classNames sort. |
|
6947 box action:[:aString | self switchToClassNamed:aString]. |
|
6948 box showAtPointer |
|
6949 !! |
|
6950 |
|
6951 switchToClassNamed:aString |
|
6952 |meta str classSymbol theClass newCat element| |
|
6953 |
|
6954 meta := false. |
|
6955 str := aString. |
|
6956 classSymbol := aString asSymbolIfInterned. |
|
6957 classSymbol isNil ifTrue:[ |
|
6958 (aString endsWith:'class') ifTrue:[ |
|
6959 str := aString copyWithoutLast:5. |
|
6960 classSymbol := str asSymbolIfInterned. |
|
6961 classSymbol isNil ifTrue:[ |
|
6962 ^ self |
|
6963 ]. |
|
6964 meta := true |
|
6965 ]. |
|
6966 ]. |
|
6967 |
|
6968 theClass := Smalltalk at:classSymbol. |
|
6969 (theClass isNil and:[str endsWith:'class']) ifTrue:[ |
|
6970 str := str copyWithoutLast:5. |
|
6971 classSymbol := str asSymbolIfInterned. |
|
6972 classSymbol isNil ifTrue:[ |
|
6973 ^ self |
|
6974 ]. |
|
6975 meta := true. |
|
6976 theClass := Smalltalk at:classSymbol. |
|
6977 ]. |
|
6978 |
|
6979 theClass == currentClass ifTrue:[^ self]. |
|
6980 |
|
6981 theClass isBehavior ifTrue:[ |
|
6982 classCategoryListView notNil ifTrue:[ |
|
6983 currentClassHierarchy isNil ifTrue:[ |
|
6984 ((newCat := theClass category) ~= currentClassCategory) ifTrue:[ |
|
6985 currentClassCategory := newCat. |
|
6986 newCat isNil ifTrue:[ |
|
6987 element := '* no category *' |
|
6988 ] ifFalse:[ |
|
6989 element := newCat. |
|
6990 ]. |
|
6991 classCategoryListView selectElement:element. |
|
6992 "/ classCategoryListView makeSelectionVisible. |
|
6993 ] |
|
6994 ] |
|
6995 ]. |
|
6996 self updateClassList. |
|
6997 self switchToClass:theClass. |
|
6998 |
|
6999 classListView selectElement:str. |
|
7000 self instanceProtocol:meta not. |
|
7001 self classSelectionChanged |
|
7002 ] |
|
7003 |
|
7004 "Modified: 1.9.1995 / 01:41:35 / claus" |
|
7005 !! |
|
7006 |
|
7007 templateFor:className in:cat |
|
7008 "return a class definition template - be smart in what is offered initially" |
|
7009 |
|
7010 |aString name i| |
|
7011 |
|
7012 name := 'NewClass'. |
|
7013 i := 1. |
|
7014 [name knownAsSymbol and:[Smalltalk includesKey:name asSymbol]] whileTrue:[ |
|
7015 i := i + 1. |
|
7016 name := 'NewClass' , i printString |
|
7017 ]. |
|
7018 |
|
7019 aString := className , ' subclass:#' , name , ' |
|
7020 instanceVariableNames: '''' |
|
7021 classVariableNames: '''' |
|
7022 poolDictionaries: '''' |
|
7023 category: '''. |
|
7024 |
|
7025 cat notNil ifTrue:[ |
|
7026 aString := aString , cat |
|
7027 ]. |
|
7028 aString := aString , ''' |
|
7029 |
|
7030 |
|
7031 |
|
7032 |
|
7033 |
|
7034 " |
|
7035 Replace ''' , className , ''', ''', name , ''' and |
|
7036 the empty string arguments by true values. |
|
7037 |
|
7038 Install (or change) the class by ''accepting'', |
|
7039 either via the menu or the keyboard (usually CMD-A). |
|
7040 |
|
7041 To be nice to others (and yourself later), do not forget to |
|
7042 add some documentation; either under the classes documentation |
|
7043 protocol, or as a class comment. |
|
7044 " |
|
7045 '. |
|
7046 ^ aString |
|
7047 !! |
|
7048 |
|
7049 updateClassList |
|
7050 self updateClassListWithScroll:true |
|
7051 !! |
|
7052 |
|
7053 updateClassListWithScroll:scroll |
|
7054 |classes oldClassName| |
|
7055 |
|
7056 classListView notNil ifTrue:[ |
|
7057 " |
|
7058 refetch in case we are not up to date |
|
7059 " |
|
7060 (currentClass notNil and:[fullProtocol not]) ifTrue:[ |
|
7061 oldClassName := currentClass name. |
|
7062 currentClass := Smalltalk at:(oldClassName asSymbol). |
|
7063 ]. |
|
7064 |
|
7065 currentClassCategory notNil ifTrue:[ |
|
7066 classes := self listOfAllClassesInCategory:currentClassCategory |
|
7067 ] ifFalse:[ |
|
7068 currentClassHierarchy notNil ifTrue:[ |
|
7069 classes := self listOfClassHierarchyOf:currentClassHierarchy |
|
7070 ] |
|
7071 ]. |
|
7072 |
|
7073 classListView list = classes ifFalse:[ |
|
7074 scroll ifTrue:[ |
|
7075 classListView contents:classes |
|
7076 ] ifFalse:[ |
|
7077 classListView setContents:classes |
|
7078 ]. |
|
7079 oldClassName notNil ifTrue:[ |
|
7080 classListView setContents:classes. |
|
7081 classListView selectElement:oldClassName |
|
7082 ] ifFalse:[ |
|
7083 variableListView notNil ifTrue:[variableListView contents:nil] |
|
7084 ] |
|
7085 ]. |
|
7086 scroll ifTrue:[ |
|
7087 fullProtocol ifTrue:[ |
|
7088 classListView scrollToBottom |
|
7089 ] |
|
7090 ] |
|
7091 ] |
|
7092 !! !! |
|
7093 |
|
7094 !!BrowserView methodsFor:'class-method list menu'!! |
|
7095 |
|
7096 classMethodFileOutAll |
|
7097 "fileout all methods into one source file" |
|
7098 |
|
7099 |list classString selectorString cls mth outStream fileName append |
|
7100 fileBox| |
|
7101 |
|
7102 append := false. |
|
7103 fileBox := FileSaveBox |
|
7104 title:(resources string:'save methodss in:') |
|
7105 okText:(resources string:'save') |
|
7106 abortText:(resources string:'cancel') |
|
7107 action:[:fName | fileName := fName]. |
|
7108 fileBox appendAction:[:fName | fileName := fName. append := true]. |
|
7109 fileBox initialText:'some_methods.st'. |
|
7110 Project notNil ifTrue:[ |
|
7111 fileBox directory:Project currentProjectDirectory |
|
7112 ]. |
|
7113 fileBox showAtPointer. |
|
7114 |
|
7115 fileName notNil ifTrue:[ |
|
7116 " |
|
7117 if file exists, save original in a .sav file |
|
7118 " |
|
7119 fileName asFilename exists ifTrue:[ |
|
7120 fileName asFilename copyTo:(fileName , '.sav') |
|
7121 ]. |
|
7122 append ifTrue:[ |
|
7123 outStream := FileStream appendingOldFileNamed:fileName |
|
7124 ] ifFalse:[ |
|
7125 outStream := FileStream newFileNamed:fileName. |
|
7126 ]. |
|
7127 outStream isNil ifTrue:[ |
|
7128 ^ self warn:'cannot create: %1' with:fileName |
|
7129 ]. |
|
7130 self withWaitCursorDo:[ |
|
7131 list := classMethodListView list. |
|
7132 list do:[:line | |
|
7133 self busyLabel:'writing: ' with:line. |
|
7134 |
|
7135 classString := self classFromClassMethodString:line. |
|
7136 selectorString := self selectorFromClassMethodString:line. |
|
7137 |
|
7138 ((classString ~= 'Metaclass') and:[classString endsWith:'class']) ifTrue:[ |
|
7139 classString := classString copyWithoutLast:5 "copyTo:(classString size - 5)". |
|
7140 cls := (Smalltalk at:classString asSymbol). |
|
7141 cls := cls class |
|
7142 ] ifFalse:[ |
|
7143 cls := (Smalltalk at:classString asSymbol). |
|
7144 ]. |
|
7145 |
|
7146 cls isNil ifTrue:[ |
|
7147 self warn:'oops class %1 is gone' with:classString |
|
7148 ] ifFalse:[ |
|
7149 mth := cls compiledMethodAt:(selectorString asSymbol). |
|
7150 Class fileOutErrorSignal handle:[:ex | |
|
7151 |box| |
|
7152 box := YesNoBox |
|
7153 title:('fileOut error: ' |
|
7154 , ex errorString |
|
7155 , '\\continue anyway ?') withCRs |
|
7156 yesText:'continue' |
|
7157 noText:'abort'. |
|
7158 box confirm ifTrue:[ |
|
7159 ex proceed |
|
7160 ]. |
|
7161 self normalLabel. |
|
7162 ^ self |
|
7163 ] do:[ |
|
7164 cls fileOutMethod:mth on:outStream. |
|
7165 ] |
|
7166 ] |
|
7167 ]. |
|
7168 outStream close. |
|
7169 self normalLabel. |
|
7170 ] |
|
7171 ] |
|
7172 !! |
|
7173 |
|
7174 classMethodMenu |
|
7175 |labels selectors| |
|
7176 |
|
7177 labels := #( |
|
7178 'fileOut' |
|
7179 'fileOut all' |
|
7180 'printOut' |
|
7181 '-' |
|
7182 'spawn' |
|
7183 'spawn class' |
|
7184 'spawn full protocol' |
|
7185 'spawn hierarchy' |
|
7186 '-' |
|
7187 'senders ...' |
|
7188 'implementors ...' |
|
7189 'globals ...' |
|
7190 "/ '-' |
|
7191 "/ 'breakpoint' |
|
7192 "/ 'trace' |
|
7193 "/ 'trace sender' |
|
7194 '-' |
|
7195 'remove' |
|
7196 ). |
|
7197 |
|
7198 selectors := #( |
|
7199 methodFileOut |
|
7200 classMethodFileOutAll |
|
7201 methodPrintOut |
|
7202 nil |
|
7203 methodSpawn |
|
7204 classSpawn |
|
7205 classSpawnFullProtocol |
|
7206 classSpawnHierarchy |
|
7207 nil |
|
7208 methodSenders |
|
7209 methodImplementors |
|
7210 methodGlobalReferends |
|
7211 "/ nil |
|
7212 "/ methodBreakPoint |
|
7213 "/ methodTrace |
|
7214 "/ methodTraceSender |
|
7215 nil |
|
7216 methodRemove |
|
7217 ). |
|
7218 |
|
7219 ^ PopUpMenu labels:(resources array:labels) |
|
7220 selectors:selectors |
|
7221 !! !! |
|
7222 |
|
7223 !!BrowserView methodsFor:'class-method stuff'!! |
|
7224 |
|
7225 classFromClassMethodString:aString |
|
7226 "helper for classMethod-list - extract class name from the string" |
|
7227 |
|
7228 "/ |pos| |
|
7229 "/ |
|
7230 "/ pos := aString indexOf:(Character space). |
|
7231 "/ ^ aString copyTo:(pos - 1) |
|
7232 |
|
7233 ^ aString upTo:Character space |
|
7234 !! |
|
7235 |
|
7236 classMethodSelection:lineNr |
|
7237 "user clicked on a class/method line - show code" |
|
7238 |
|
7239 |cls string classString selectorString meta| |
|
7240 |
|
7241 string := classMethodListView selectionValue. |
|
7242 classString := self classFromClassMethodString:string. |
|
7243 selectorString := self selectorFromClassMethodString:string. |
|
7244 ((classString ~= 'Metaclass') and:[classString endsWith:'class']) ifTrue:[ |
|
7245 classString := classString copyWithoutLast:5 "copyTo:(classString size - 5)". |
|
7246 meta := true. |
|
7247 ] ifFalse:[ |
|
7248 meta := false. |
|
7249 ]. |
|
7250 self switchToClass:(Smalltalk at:classString asSymbol). |
|
7251 meta ifTrue:[cls := currentClass class] ifFalse:[cls := currentClass]. |
|
7252 actualClass := acceptClass := cls. |
|
7253 |
|
7254 currentClass isNil ifTrue:[ |
|
7255 self warn:'oops class is gone' |
|
7256 ] ifFalse:[ |
|
7257 currentClassCategory := currentClass category. |
|
7258 currentSelector := selectorString asSymbol. |
|
7259 currentMethod := actualClass compiledMethodAt:currentSelector. |
|
7260 currentMethod isNil ifTrue:[ |
|
7261 self warn:'oops method is gone' |
|
7262 ] ifFalse:[ |
|
7263 currentMethodCategory := currentMethod category. |
|
7264 ]. |
|
7265 |
|
7266 self methodSelectionChanged |
|
7267 ]. |
|
7268 |
|
7269 self setDoitActionForClass |
|
7270 |
|
7271 "Modified: 31.8.1995 / 11:56:02 / claus" |
|
7272 !! |
|
7273 |
|
7274 selectorFromClassMethodString:aString |
|
7275 "helper for classMethod-list - extract selector from the string" |
|
7276 |
|
7277 |pos| |
|
7278 |
|
7279 pos := aString indexOf:(Character space). |
|
7280 ^ aString copyFrom:(pos + 1) |
|
7281 !! !! |
|
7282 |
|
7283 !!BrowserView methodsFor:'help'!! |
|
7284 |
|
7285 helpTextFor:aComponent |
|
7286 |s| |
|
7287 |
|
7288 aComponent == classCategoryListView ifTrue:[ |
|
7289 s := 'HELP_CCAT_LIST' |
|
7290 ]. |
|
7291 aComponent == classListView ifTrue:[ |
|
7292 fullProtocol ifTrue:[ |
|
7293 s := 'HELP_PCLASS_LIST' |
|
7294 ] ifFalse:[ |
|
7295 currentClassHierarchy notNil ifTrue:[ |
|
7296 s := 'HELP_HCLASS_LIST' |
|
7297 ] ifFalse:[ |
|
7298 s := 'HELP_CLASS_LIST' |
|
7299 ] |
|
7300 ] |
|
7301 ]. |
|
7302 aComponent == methodCategoryListView ifTrue:[ |
|
7303 s := 'HELP_MCAT_LIST' |
|
7304 ]. |
|
7305 aComponent == methodListView ifTrue:[ |
|
7306 s := 'HELP_METHOD_LIST' |
|
7307 ]. |
|
7308 aComponent == variableListView ifTrue:[ |
|
7309 s := 'HELP_VAR_LIST' |
|
7310 ]. |
|
7311 aComponent == codeView ifTrue:[ |
|
7312 fullClass ifTrue:[ |
|
7313 s := 'HELP_FULLCODE_VIEW' |
|
7314 ] ifFalse:[ |
|
7315 s := 'HELP_CODE_VIEW' |
|
7316 ] |
|
7317 ]. |
|
7318 (aComponent == instanceToggle |
|
7319 or:[aComponent == classToggle]) ifTrue:[ |
|
7320 s := 'HELP_INST_CLASS_TOGGLE' |
|
7321 ]. |
|
7322 aComponent == classMethodListView ifTrue:[ |
|
7323 s := 'HELP_CLSMTHOD_LIST' |
|
7324 ]. |
|
7325 s notNil ifTrue:[ |
|
7326 ^ resources string:s |
|
7327 ]. |
|
7328 ^ nil |
|
7329 |
|
7330 "Modified: 31.8.1995 / 19:11:39 / claus" |
|
7331 !! !! |
|
7332 |
|
7333 !!BrowserView methodsFor:'initialize / release'!! |
|
7334 |
|
7335 autoSearch:aString |
|
7336 "used with class-method list browsing. If true, |
|
7337 selecting an entry from the list will automatically |
|
7338 search for the searchstring in the codeView" |
|
7339 |
|
7340 self setSearchPattern:aString. |
|
7341 autoSearch := aString |
|
7342 !! |
|
7343 |
|
7344 destroy |
|
7345 "relese dependant - destroy popups" |
|
7346 |
|
7347 Smalltalk removeDependent:self. |
|
7348 currentClass notNil ifTrue:[ |
|
7349 currentClass removeDependent:self. |
|
7350 currentClass := nil |
|
7351 ]. |
|
7352 super destroy |
|
7353 !! |
|
7354 |
|
7355 initialize |
|
7356 super initialize. |
|
7357 |
|
7358 showInstance := true. |
|
7359 fullClass := false. |
|
7360 fullProtocol := false. |
|
7361 aspect := nil. |
|
7362 |
|
7363 "inform me, when Smalltalk changes" |
|
7364 Smalltalk addDependent:self |
|
7365 !! |
|
7366 |
|
7367 realize |
|
7368 |v checkBlock| |
|
7369 |
|
7370 super realize. |
|
7371 |
|
7372 checkBlock := [:lineNr | self checkSelectionChangeAllowed]. |
|
7373 |
|
7374 v := classCategoryListView. |
|
7375 v notNil ifTrue:[ |
|
7376 v action:[:lineNr | self classCategorySelection:lineNr]. |
|
7377 v selectConditionBlock:checkBlock. |
|
7378 v ignoreReselect:false. |
|
7379 v contents:(self listOfAllClassCategories). |
|
7380 " |
|
7381 tell classCategoryListView to ask for the menu |
|
7382 " |
|
7383 v menuHolder:self; menuPerformer:self; menuMessage:#classCategoryMenu. |
|
7384 ]. |
|
7385 |
|
7386 v := classListView. |
|
7387 v notNil ifTrue:[ |
|
7388 v action:[:lineNr | self classSelection:lineNr]. |
|
7389 v selectConditionBlock:checkBlock. |
|
7390 v ignoreReselect:false. |
|
7391 " |
|
7392 tell classListView to ask for the menu |
|
7393 " |
|
7394 v menuHolder:self; menuPerformer:self; menuMessage:#classMenu. |
|
7395 ]. |
|
7396 |
|
7397 v := methodCategoryListView. |
|
7398 v notNil ifTrue:[ |
|
7399 v action:[:lineNr | self methodCategorySelection:lineNr]. |
|
7400 v selectConditionBlock:checkBlock. |
|
7401 v ignoreReselect:false. |
|
7402 " |
|
7403 tell methodCategoryListView to ask for the menu |
|
7404 " |
|
7405 v menuHolder:self; menuPerformer:self; menuMessage:#methodCategoryMenu. |
|
7406 ]. |
|
7407 |
|
7408 v := methodListView. |
|
7409 v notNil ifTrue:[ |
|
7410 v action:[:lineNr | self methodSelection:lineNr]. |
|
7411 v selectConditionBlock:checkBlock. |
|
7412 v ignoreReselect:false. |
|
7413 " |
|
7414 tell methodListView to ask for the menu |
|
7415 " |
|
7416 v menuHolder:self; menuPerformer:self; menuMessage:#methodMenu. |
|
7417 ]. |
|
7418 |
|
7419 v := classMethodListView. |
|
7420 v notNil ifTrue:[ |
|
7421 v action:[:lineNr | self classMethodSelection:lineNr]. |
|
7422 v selectConditionBlock:checkBlock. |
|
7423 v ignoreReselect:false. |
|
7424 " |
|
7425 tell classMethodListView to ask for the menu |
|
7426 " |
|
7427 v menuHolder:self; menuPerformer:self; menuMessage:#classMethodMenu. |
|
7428 ]. |
|
7429 |
|
7430 v := variableListView. |
|
7431 v notNil ifTrue:[ |
|
7432 v action:[:lineNr | self variableSelection:lineNr]. |
|
7433 v ignoreReselect:false. |
|
7434 v toggleSelect:true. |
|
7435 v menuHolder:self; menuPerformer:self; menuMessage:#variableListMenu. |
|
7436 ]. |
|
7437 |
|
7438 " |
|
7439 normal browsers show the top at first; |
|
7440 hierarchy and fullProtocol browsers better show the end |
|
7441 initially |
|
7442 " |
|
7443 currentClassHierarchy notNil ifTrue:[ |
|
7444 classListView scrollToBottom. |
|
7445 ] |
|
7446 !! |
|
7447 |
|
7448 terminate |
|
7449 (self checkSelectionChangeAllowed) ifTrue:[ |
|
7450 super terminate |
|
7451 ] |
|
7452 !! |
|
7453 |
|
7454 title:someString |
|
7455 myLabel := someString. |
|
7456 self label:someString. |
|
7457 !! !! |
|
7458 |
|
7459 !!BrowserView methodsFor:'initialize subviews'!! |
|
7460 |
|
7461 createClassListViewIn:frame |
|
7462 "setup the classlist subview, with its toggles" |
|
7463 |
|
7464 |v panel| |
|
7465 |
|
7466 self createTogglesIn:frame. |
|
7467 |
|
7468 " |
|
7469 oldstyle had no variableList ... |
|
7470 " |
|
7471 "/ v := ScrollableView for:SelectionInListView in:frame. |
|
7472 "/ v origin:(0.0 @ 0.0) |
|
7473 "/ extent:[frame width |
|
7474 "/ @ |
|
7475 "/ (frame height |
|
7476 "/ - ViewSpacing |
|
7477 "/ - instanceToggle height |
|
7478 "/ - instanceToggle borderWidth |
|
7479 "/ + v borderWidth)]. |
|
7480 "/ |
|
7481 "/ classListView := v scrolledView |
|
7482 |
|
7483 panel := VariableVerticalPanel |
|
7484 origin:(0.0 @ 0.0) |
|
7485 corner:[frame width |
|
7486 @ |
|
7487 (frame height |
|
7488 - ViewSpacing |
|
7489 - instanceToggle height |
|
7490 "-" "+ instanceToggle borderWidth " |
|
7491 + v borderWidth)] |
|
7492 in:frame. |
|
7493 |
|
7494 v := ScrollableView for:SelectionInListView in:panel. |
|
7495 v origin:(0.0 @ 0.0) corner:(1.0 @ 0.7). |
|
7496 classListView := v scrolledView. |
|
7497 |
|
7498 |
|
7499 v := ScrollableView for:SelectionInListView in:panel. |
|
7500 v origin:(0.0 @ 0.7) corner:(1.0 @ 1.0). |
|
7501 |
|
7502 variableListView := v scrolledView. |
|
7503 !! |
|
7504 |
|
7505 createCodeViewIn:aView |
|
7506 "setup the code view" |
|
7507 |
|
7508 ^ self createCodeViewIn:aView at:0.25 |
|
7509 !! |
|
7510 |
|
7511 createCodeViewIn:aView at:relY |
|
7512 "setup the code view" |
|
7513 |v| |
|
7514 |
|
7515 v := HVScrollableView for:CodeView miniScrollerH:true miniScrollerV:false in:aView. |
|
7516 v origin:(0.0 @ relY) corner:(1.0 @ 1.0). |
|
7517 codeView := v scrolledView |
|
7518 !! |
|
7519 |
|
7520 createTogglesIn:aFrame |
|
7521 "create and setup the class/instance toggles" |
|
7522 |
|
7523 |h halfSpace classAction instanceAction| |
|
7524 |
|
7525 classAction := [self instanceProtocol:false]. |
|
7526 instanceAction := [self instanceProtocol:true]. |
|
7527 |
|
7528 halfSpace := ViewSpacing // 2. |
|
7529 |
|
7530 instanceToggle := Toggle label:(resources at:'instance') in:aFrame. |
|
7531 h := instanceToggle heightIncludingBorder. |
|
7532 instanceToggle origin:(0.0 @ 1.0) corner:(0.5 @ 1.0). |
|
7533 instanceToggle topInset:h negated. |
|
7534 |
|
7535 instanceToggle turnOn. |
|
7536 instanceToggle pressAction:instanceAction. |
|
7537 instanceToggle releaseAction:classAction. |
|
7538 |
|
7539 classToggle := Toggle label:(resources at:'class') in:aFrame. |
|
7540 h := classToggle heightIncludingBorder. |
|
7541 classToggle origin:(0.5 @ 1.0) corner:(1.0 @ 1.0). |
|
7542 classToggle topInset:h negated. |
|
7543 |
|
7544 classToggle turnOff. |
|
7545 classToggle pressAction:classAction. |
|
7546 classToggle releaseAction:instanceAction. |
|
7547 |
|
7548 styleSheet is3D ifTrue:[ |
|
7549 instanceToggle bottomInset:halfSpace. |
|
7550 classToggle bottomInset:halfSpace. |
|
7551 |
|
7552 instanceToggle leftInset:halfSpace. |
|
7553 classToggle leftInset:halfSpace. |
|
7554 instanceToggle rightInset:ViewSpacing - halfSpace. |
|
7555 classToggle rightInset:ViewSpacing - halfSpace. |
|
7556 ]. |
|
7557 !! |
|
7558 |
|
7559 focusSequence |
|
7560 |s| |
|
7561 |
|
7562 s := OrderedCollection new. |
|
7563 |
|
7564 classCategoryListView notNil ifTrue:[ |
|
7565 s add:classCategoryListView |
|
7566 ]. |
|
7567 |
|
7568 classListView notNil ifTrue:[ |
|
7569 s add:classListView |
|
7570 ]. |
|
7571 |
|
7572 "/ variableListView notNil ifTrue:[ |
|
7573 "/ s add:variableListView |
|
7574 "/ ]. |
|
7575 |
|
7576 instanceToggle notNil ifTrue:[ |
|
7577 s add:instanceToggle. |
|
7578 ]. |
|
7579 |
|
7580 methodCategoryListView notNil ifTrue:[ |
|
7581 s add:methodCategoryListView |
|
7582 ]. |
|
7583 |
|
7584 methodListView notNil ifTrue:[ |
|
7585 s add:methodListView |
|
7586 ]. |
|
7587 |
|
7588 classMethodListView notNil ifTrue:[ |
|
7589 s add:classMethodListView |
|
7590 ]. |
|
7591 |
|
7592 s add:codeView. |
|
7593 ^ s |
|
7594 !! |
|
7595 |
|
7596 setupForAll |
|
7597 "create subviews for a full browser" |
|
7598 |
|
7599 |vpanel hpanel frame v| |
|
7600 |
|
7601 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) |
|
7602 in:self. |
|
7603 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
7604 |
|
7605 v := HVScrollableView for:SelectionInListView |
|
7606 miniScrollerH:true miniScrollerV:false |
|
7607 in:hpanel. |
|
7608 v origin:(0.0 @ 0.0) corner:(0.25 @ 1.0). |
|
7609 classCategoryListView := v scrolledView. |
|
7610 |
|
7611 frame := View origin:(0.25 @ 0.0) corner:(0.5 @ 1.0) in:hpanel. |
|
7612 self createClassListViewIn:frame. |
|
7613 |
|
7614 v := HVScrollableView for:SelectionInListView miniScrollerH:true miniScrollerV:false in:hpanel. |
|
7615 v origin:(0.5 @ 0.0) corner:(0.75 @ 1.0). |
|
7616 methodCategoryListView := v scrolledView. |
|
7617 |
|
7618 v := HVScrollableView for:SelectionInListView miniScrollerH:true miniScrollerV:false in:hpanel. |
|
7619 v origin:(0.75 @ 0.0) corner:(1.0 @ 1.0). |
|
7620 methodListView := v scrolledView. |
|
7621 |
|
7622 self createCodeViewIn:vpanel |
|
7623 !! |
|
7624 |
|
7625 setupForClass:aClass |
|
7626 "create subviews for browsing a single class" |
|
7627 |
|
7628 |vpanel hpanel frame v| |
|
7629 |
|
7630 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
7631 corner:(1.0 @ 1.0) |
|
7632 in:self. |
|
7633 |
|
7634 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
7635 frame := View origin:(0.0 @ 0.0) corner:(0.5 @ 1.0)in:hpanel. |
|
7636 |
|
7637 self createTogglesIn:frame. |
|
7638 |
|
7639 v := ScrollableView for:SelectionInListView in:frame. |
|
7640 v origin:(0.0 @ 0.0) |
|
7641 extent:[frame width |
|
7642 @ |
|
7643 (frame height |
|
7644 - ViewSpacing |
|
7645 - instanceToggle height |
|
7646 - instanceToggle borderWidth |
|
7647 + v borderWidth)]. |
|
7648 methodCategoryListView := v scrolledView. |
|
7649 |
|
7650 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7651 v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0). |
|
7652 methodListView := v scrolledView. |
|
7653 |
|
7654 self createCodeViewIn:vpanel. |
|
7655 |
|
7656 self switchToClass:aClass. |
|
7657 actualClass := acceptClass := aClass. |
|
7658 self updateMethodCategoryList. |
|
7659 self updateMethodList. |
|
7660 self updateCodeView. |
|
7661 self classDefinition. |
|
7662 !! |
|
7663 |
|
7664 setupForClass:aClass methodCategory:aMethodCategory |
|
7665 "setup subviews to browse a method category" |
|
7666 |
|
7667 |vpanel v| |
|
7668 |
|
7669 vpanel := VariableVerticalPanel |
|
7670 origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) |
|
7671 in:self. |
|
7672 |
|
7673 v := ScrollableView for:SelectionInListView in:vpanel. |
|
7674 v origin:(0.0 @ 0.0) corner:(1.0 @ 0.25). |
|
7675 methodListView := v scrolledView. |
|
7676 |
|
7677 self createCodeViewIn:vpanel. |
|
7678 |
|
7679 currentClassCategory := aClass category. |
|
7680 self switchToClass:aClass. |
|
7681 actualClass := acceptClass := aClass. |
|
7682 currentMethodCategory := aMethodCategory. |
|
7683 self updateMethodList. |
|
7684 self updateCodeView. |
|
7685 !! |
|
7686 |
|
7687 setupForClass:aClass selector:selector |
|
7688 "setup subviews to browse a single method" |
|
7689 |
|
7690 |v| |
|
7691 |
|
7692 v := ScrollableView for:CodeView in:self. |
|
7693 v origin:(0.0 @ 0.0) corner:(1.0 @ 1.0). |
|
7694 codeView := v scrolledView. |
|
7695 |
|
7696 currentClassCategory := aClass category. |
|
7697 self switchToClass:aClass. |
|
7698 actualClass := acceptClass := aClass. |
|
7699 currentSelector := selector. |
|
7700 currentMethod := currentClass compiledMethodAt:selector. |
|
7701 currentMethodCategory := currentMethod category. |
|
7702 self updateCodeView |
|
7703 !! |
|
7704 |
|
7705 setupForClassCategory:aClassCategory |
|
7706 "setup subviews to browse a class category" |
|
7707 |
|
7708 |vpanel hpanel frame v| |
|
7709 |
|
7710 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
7711 corner:(1.0 @ 1.0) |
|
7712 in:self. |
|
7713 |
|
7714 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
7715 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
7716 |
|
7717 self createClassListViewIn:frame. |
|
7718 |
|
7719 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7720 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
7721 methodCategoryListView := v scrolledView. |
|
7722 |
|
7723 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7724 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
7725 methodListView := v scrolledView. |
|
7726 |
|
7727 self createCodeViewIn:vpanel. |
|
7728 |
|
7729 currentClassCategory := aClassCategory. |
|
7730 self updateClassList. |
|
7731 self updateMethodCategoryList. |
|
7732 self updateMethodList. |
|
7733 self updateCodeView |
|
7734 !! |
|
7735 |
|
7736 setupForClassHierarchy:aClass |
|
7737 "setup subviews to browse a class hierarchy" |
|
7738 |
|
7739 |vpanel hpanel frame v cls| |
|
7740 |
|
7741 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
7742 corner:(1.0 @ 1.0) |
|
7743 in:self. |
|
7744 |
|
7745 " |
|
7746 notice: we use a different ratio here |
|
7747 " |
|
7748 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.4) in:vpanel. |
|
7749 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
7750 |
|
7751 self createClassListViewIn:frame. |
|
7752 |
|
7753 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7754 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
7755 methodCategoryListView := v scrolledView. |
|
7756 |
|
7757 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7758 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
7759 methodListView := v scrolledView. |
|
7760 |
|
7761 self createCodeViewIn:vpanel at:0.4. |
|
7762 |
|
7763 cls := aClass. |
|
7764 cls isMeta ifTrue:[ |
|
7765 cls := cls soleInstance |
|
7766 ]. |
|
7767 currentClassHierarchy := currentClass := actualClass := cls. |
|
7768 self updateClassList. |
|
7769 classListView selectElement:aClass name; makeSelectionVisible. |
|
7770 self updateMethodCategoryList. |
|
7771 self updateMethodList. |
|
7772 self updateCodeView. |
|
7773 |
|
7774 aClass isMeta ifTrue:[ |
|
7775 self instanceProtocol:false |
|
7776 ]. |
|
7777 !! |
|
7778 |
|
7779 setupForClassList:aList |
|
7780 "setup subviews to browse classes from a list" |
|
7781 |
|
7782 |vpanel hpanel frame l v| |
|
7783 |
|
7784 vpanel := VariableVerticalPanel |
|
7785 origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:self. |
|
7786 |
|
7787 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
7788 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
7789 |
|
7790 self createClassListViewIn:frame. |
|
7791 |
|
7792 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7793 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
7794 methodCategoryListView := v scrolledView. |
|
7795 |
|
7796 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7797 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
7798 methodListView := v scrolledView. |
|
7799 |
|
7800 self createCodeViewIn:vpanel. |
|
7801 |
|
7802 l := (aList collect:[:entry | entry name]) asOrderedCollection. |
|
7803 classListView list:(l sort). |
|
7804 |
|
7805 self updateMethodCategoryList. |
|
7806 self updateMethodList. |
|
7807 self updateCodeView |
|
7808 !! |
|
7809 |
|
7810 setupForFullClass |
|
7811 "setup subviews to browse a class as full text" |
|
7812 |
|
7813 |vpanel hpanel v| |
|
7814 |
|
7815 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
7816 corner:(1.0 @ 1.0) |
|
7817 in:self. |
|
7818 |
|
7819 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
7820 |
|
7821 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7822 v origin:(0.0 @ 0.0) corner:(0.5 @ 1.0). |
|
7823 classCategoryListView := v scrolledView. |
|
7824 classCategoryListView contents:(self listOfAllClassCategories). |
|
7825 |
|
7826 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7827 v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0). |
|
7828 classListView := v scrolledView. |
|
7829 |
|
7830 self createCodeViewIn:vpanel. |
|
7831 |
|
7832 fullClass := true. |
|
7833 self updateCodeView |
|
7834 !! |
|
7835 |
|
7836 setupForFullClassProtocol:aClass |
|
7837 "setup subviews to browse a classes full protocol" |
|
7838 |
|
7839 |vpanel hpanel frame v cls| |
|
7840 |
|
7841 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
7842 corner:(1.0 @ 1.0) |
|
7843 in:self. |
|
7844 |
|
7845 " |
|
7846 notice: we use a different ratio here |
|
7847 " |
|
7848 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.4) in:vpanel. |
|
7849 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
7850 |
|
7851 self createClassListViewIn:frame. |
|
7852 classListView multipleSelectOk:true. |
|
7853 classListView toggleSelect:true. |
|
7854 classListView strikeOut:true. |
|
7855 |
|
7856 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7857 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
7858 methodCategoryListView := v scrolledView. |
|
7859 |
|
7860 v := ScrollableView for:SelectionInListView in:hpanel. |
|
7861 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
7862 methodListView := v scrolledView. |
|
7863 |
|
7864 self createCodeViewIn:vpanel at:0.4. |
|
7865 |
|
7866 cls := aClass. |
|
7867 cls isMeta ifTrue:[ |
|
7868 cls := cls soleInstance |
|
7869 ]. |
|
7870 currentClassHierarchy := actualClass := acceptClass := currentClass := cls. |
|
7871 fullProtocol := true. |
|
7872 |
|
7873 self updateClassList. |
|
7874 self updateMethodCategoryList. |
|
7875 self updateMethodList. |
|
7876 self updateCodeView. |
|
7877 self updateVariableList. |
|
7878 aClass isMeta ifTrue:[ |
|
7879 self instanceProtocol:false |
|
7880 ]. |
|
7881 !! |
|
7882 |
|
7883 setupForList:aList |
|
7884 "setup subviews to browse methods from a list" |
|
7885 |
|
7886 |vpanel v| |
|
7887 |
|
7888 vpanel := VariableVerticalPanel |
|
7889 origin:(0.0 @ 0.0) |
|
7890 corner:(1.0 @ 1.0) |
|
7891 in:self. |
|
7892 |
|
7893 v := ScrollableView for:SelectionInListView in:vpanel. |
|
7894 v origin:(0.0 @ 0.0) corner:(1.0 @ 0.25). |
|
7895 classMethodListView := v scrolledView. |
|
7896 classMethodListView contents:aList. |
|
7897 |
|
7898 self createCodeViewIn:vpanel. |
|
7899 aList size == 1 ifTrue:[ |
|
7900 classMethodListView selection:1. |
|
7901 self classMethodSelection:1. |
|
7902 ]. |
|
7903 self updateCodeView |
|
7904 !! !! |
|
7905 |
|
7906 !!BrowserView methodsFor:'method category list menu'!! |
|
7907 |
|
7908 methodCategoryCopyCategory |
|
7909 "show the enter box to copy from an existing method category" |
|
7910 |
|
7911 |title box| |
|
7912 |
|
7913 showInstance ifTrue:[ |
|
7914 title := 'class to copy instance method category from:' |
|
7915 ] ifFalse:[ |
|
7916 title := 'class to copy class method category from:' |
|
7917 ]. |
|
7918 |
|
7919 box := self listBoxTitle:title |
|
7920 okText:'ok' |
|
7921 list:(Smalltalk allClasses collect:[:cls | cls name]) asArray sort. |
|
7922 |
|
7923 box action:[:aString | self copyMethodsFromClass:aString]. |
|
7924 box showAtPointer |
|
7925 !! |
|
7926 |
|
7927 methodCategoryCreateAccessMethods |
|
7928 "create access methods for all instvars" |
|
7929 |
|
7930 self checkClassSelected ifFalse:[^ self]. |
|
7931 |
|
7932 showInstance ifFalse:[ |
|
7933 self warn:'select instance - and try again'. |
|
7934 ^ self. |
|
7935 ]. |
|
7936 |
|
7937 self withWaitCursorDo:[ |
|
7938 |nm names source| |
|
7939 |
|
7940 (variableListView notNil |
|
7941 and:[(nm := variableListView selectionValue) notNil]) ifTrue:[ |
|
7942 names := Array with:nm |
|
7943 ] ifFalse:[ |
|
7944 names := currentClass instVarNames |
|
7945 ]. |
|
7946 names do:[:name | |
|
7947 "check, if method is not already present" |
|
7948 (currentClass implements:(name asSymbol)) ifFalse:[ |
|
7949 source := (name , '\ "return ' , name , '"\\ ^ ' , name) withCRs. |
|
7950 Compiler compile:source forClass:currentClass inCategory:'accessing'. |
|
7951 ] ifTrue:[ |
|
7952 Transcript showCr:'method ''', name , ''' already present' |
|
7953 ]. |
|
7954 (currentClass implements:((name , ':') asSymbol)) ifFalse:[ |
|
7955 source := (name , ':something\ "set ' , name , '"\\ ' , name , ' := something.') withCRs. |
|
7956 Compiler compile:source forClass:currentClass inCategory:'accessing'. |
|
7957 ] ifTrue:[ |
|
7958 Transcript showCr:'method ''', name , ':'' already present' |
|
7959 ]. |
|
7960 ]. |
|
7961 self updateMethodCategoryListWithScroll:false. |
|
7962 self updateMethodListWithScroll:false |
|
7963 ] |
|
7964 !! |
|
7965 |
|
7966 methodCategoryCreateDocumentationMethods |
|
7967 "create empty documentation methods" |
|
7968 |
|
7969 |cls histStream| |
|
7970 |
|
7971 self checkClassSelected ifFalse:[^ self]. |
|
7972 |
|
7973 cls := currentClass class. |
|
7974 |
|
7975 self withWaitCursorDo:[ |
|
7976 |nm names source| |
|
7977 |
|
7978 "/ add version method containing RCS template |
|
7979 "/ but only if not already present. |
|
7980 |
|
7981 (cls implements:#version) ifFalse:[ |
|
7982 Compiler compile: |
|
7983 'version |
|
7984 " |
|
7985 $' , 'Header$ |
|
7986 " |
|
7987 ' forClass:cls |
|
7988 inCategory:'documentation'. |
|
7989 ]. |
|
7990 |
|
7991 "/ add documentation method containing doc template |
|
7992 "/ but only if not already present. |
|
7993 |
|
7994 (cls implements:#documentation) ifFalse:[ |
|
7995 Compiler compile: |
|
7996 'documentation |
|
7997 " |
|
7998 documentation to be added. |
|
7999 " |
|
8000 ' forClass:cls |
|
8001 inCategory:'documentation'. |
|
8002 ]. |
|
8003 |
|
8004 "/ add examples method containing examples template |
|
8005 "/ but only if not already present. |
|
8006 |
|
8007 (cls implements:#examples) ifFalse:[ |
|
8008 Compiler compile: |
|
8009 'examples |
|
8010 " |
|
8011 examples to be added. |
|
8012 " |
|
8013 ' forClass:cls |
|
8014 inCategory:'documentation'. |
|
8015 ]. |
|
8016 |
|
8017 "/ add history method containing created-entry |
|
8018 "/ but only if not already present. |
|
8019 |
|
8020 (cls implements:#history) ifFalse:[ |
|
8021 histStream := ReadWriteStream on: String new. |
|
8022 histStream nextPutAll: 'history'; cr. |
|
8023 HistoryLine isBehavior ifTrue:[ |
|
8024 histStream nextPutAll: (HistoryLine newCreated printString); cr. |
|
8025 ] ifFalse:[ |
|
8026 histStream cr. |
|
8027 ]. |
|
8028 Compiler compile:(histStream contents) |
|
8029 forClass:cls |
|
8030 inCategory:'documentation'. |
|
8031 ]. |
|
8032 |
|
8033 self instanceProtocol:false. |
|
8034 self switchToMethodNamed:#documentation |
|
8035 "/ self updateMethodCategoryListWithScroll:false. |
|
8036 "/ self updateMethodListWithScroll:false |
|
8037 ] |
|
8038 !! |
|
8039 |
|
8040 methodCategoryFileOut |
|
8041 "fileOut all methods in the selected methodcategory of |
|
8042 the current class" |
|
8043 |
|
8044 self checkClassSelected ifFalse:[^ self]. |
|
8045 self whenMethodCategorySelected:[ |
|
8046 self busyLabel:'saving: %1' with:currentClass name , '-' , currentMethodCategory. |
|
8047 Class fileOutErrorSignal handle:[:ex | |
|
8048 self warn:'cannot create: %1' with:ex parameter. |
|
8049 ex return. |
|
8050 ] do:[ |
|
8051 actualClass fileOutCategory:currentMethodCategory. |
|
8052 ]. |
|
8053 self normalLabel. |
|
8054 ] |
|
8055 !! |
|
8056 |
|
8057 methodCategoryFileOutAll |
|
8058 "fileOut all methods in the selected methodcategory of |
|
8059 the current class" |
|
8060 |
|
8061 |
|
8062 self whenMethodCategorySelected:[ |
|
8063 |fileName outStream| |
|
8064 |
|
8065 fileName := currentMethodCategory , '.st'. |
|
8066 fileName replaceAll:Character space by:$_. |
|
8067 " |
|
8068 this test allows a smalltalk to be built without Projects/ChangeSets |
|
8069 " |
|
8070 Project notNil ifTrue:[ |
|
8071 fileName := Project currentProjectDirectory , fileName. |
|
8072 ]. |
|
8073 " |
|
8074 if file exists, save original in a .sav file |
|
8075 " |
|
8076 fileName asFilename exists ifTrue:[ |
|
8077 fileName asFilename copyTo:(fileName , '.sav') |
|
8078 ]. |
|
8079 outStream := FileStream newFileNamed:fileName. |
|
8080 outStream isNil ifTrue:[ |
|
8081 ^ self warn:'cannot create: %1' with:fileName |
|
8082 ]. |
|
8083 |
|
8084 self busyLabel:'saving: ' with:currentMethodCategory. |
|
8085 Class fileOutErrorSignal handle:[:ex | |
|
8086 self warn:'cannot create: %1' with:ex parameter. |
|
8087 ex return |
|
8088 ] do:[ |
|
8089 Smalltalk allBehaviorsDo:[:class | |
|
8090 |hasMethodsInThisCategory| |
|
8091 |
|
8092 hasMethodsInThisCategory := false. |
|
8093 class methodArray do:[:method | |
|
8094 method category = currentMethodCategory ifTrue:[ |
|
8095 hasMethodsInThisCategory := true |
|
8096 ] |
|
8097 ]. |
|
8098 hasMethodsInThisCategory ifTrue:[ |
|
8099 class fileOutCategory:currentMethodCategory on:outStream. |
|
8100 outStream cr |
|
8101 ]. |
|
8102 hasMethodsInThisCategory := false. |
|
8103 class class methodArray do:[:method | |
|
8104 method category = currentMethodCategory ifTrue:[ |
|
8105 hasMethodsInThisCategory := true |
|
8106 ] |
|
8107 ]. |
|
8108 hasMethodsInThisCategory ifTrue:[ |
|
8109 class class fileOutCategory:currentMethodCategory on:outStream. |
|
8110 outStream cr |
|
8111 ] |
|
8112 ]. |
|
8113 ]. |
|
8114 outStream close. |
|
8115 self normalLabel. |
|
8116 ]. |
|
8117 !! |
|
8118 |
|
8119 methodCategoryFindAnyMethod |
|
8120 |box| |
|
8121 |
|
8122 box := self enterBoxForSearchSelectorTitle:'method selector to search for:'. |
|
8123 box action:[:aString | self switchToAnyMethodNamed:aString]. |
|
8124 box showAtPointer |
|
8125 !! |
|
8126 |
|
8127 methodCategoryFindMethod |
|
8128 |box| |
|
8129 |
|
8130 box := self enterBoxForSearchSelectorTitle:'method selector to search for:'. |
|
8131 box action:[:aString | self switchToMethodNamed:aString]. |
|
8132 box showAtPointer |
|
8133 !! |
|
8134 |
|
8135 methodCategoryMenu |
|
8136 |labels selectors i| |
|
8137 |
|
8138 currentClass isNil ifTrue:[ |
|
8139 methodCategoryListView flash. |
|
8140 ^ nil |
|
8141 ]. |
|
8142 currentMethodCategory isNil ifTrue:[ |
|
8143 labels := #( |
|
8144 'find method here ...' |
|
8145 'find method ...' |
|
8146 '-' |
|
8147 'new category ...' |
|
8148 'copy category ...' |
|
8149 'create access methods' |
|
8150 ). |
|
8151 selectors := #( |
|
8152 methodCategoryFindMethod |
|
8153 methodCategoryFindAnyMethod |
|
8154 nil |
|
8155 methodCategoryNewCategory |
|
8156 methodCategoryCopyCategory |
|
8157 methodCategoryCreateAccessMethods |
|
8158 ). |
|
8159 ] ifFalse:[ |
|
8160 labels := #( |
|
8161 'fileOut' |
|
8162 'fileOut all' |
|
8163 'printOut' |
|
8164 '-' |
|
8165 'SPAWN_METHODCATEGORY' |
|
8166 'spawn category' |
|
8167 '-' |
|
8168 'find method here ...' |
|
8169 'find method ...' |
|
8170 '-' |
|
8171 'new category ...' |
|
8172 'copy category ...' |
|
8173 'create access methods' |
|
8174 'rename ...' |
|
8175 'remove' |
|
8176 ). |
|
8177 selectors := #( |
|
8178 methodCategoryFileOut |
|
8179 methodCategoryFileOutAll |
|
8180 methodCategoryPrintOut |
|
8181 nil |
|
8182 methodCategorySpawn |
|
8183 methodCategorySpawnCategory |
|
8184 nil |
|
8185 methodCategoryFindMethod |
|
8186 methodCategoryFindAnyMethod |
|
8187 nil |
|
8188 methodCategoryNewCategory |
|
8189 methodCategoryCopyCategory |
|
8190 methodCategoryCreateAccessMethods |
|
8191 methodCategoryRename |
|
8192 methodCategoryRemove |
|
8193 ). |
|
8194 ]. |
|
8195 |
|
8196 showInstance ifFalse:[ |
|
8197 labels := labels copy. |
|
8198 selectors := selectors copy. |
|
8199 i := labels indexOf:'create access methods'. |
|
8200 labels at:i put:'create documentation stubs'. |
|
8201 selectors at:i put:#methodCategoryCreateDocumentationMethods |
|
8202 ]. |
|
8203 |
|
8204 ^ PopUpMenu labels:(resources array:labels) |
|
8205 selectors:selectors |
|
8206 !! |
|
8207 |
|
8208 methodCategoryNewCategory |
|
8209 "show the enter box to add a new method category. |
|
8210 Offer existing superclass categories in box to help avoiding |
|
8211 useless typing." |
|
8212 |
|
8213 |someCategories existingCategories box| |
|
8214 |
|
8215 actualClass notNil ifTrue:[ |
|
8216 someCategories := actualClass allCategories |
|
8217 ] ifFalse:[ |
|
8218 " |
|
8219 mhmh - offer some typical categories ... |
|
8220 " |
|
8221 showInstance ifTrue:[ |
|
8222 someCategories := #('accessing' |
|
8223 'initialization' |
|
8224 'private' |
|
8225 'printing & storing' |
|
8226 'queries' |
|
8227 'testing' |
|
8228 ) |
|
8229 ] ifFalse:[ |
|
8230 someCategories := #( |
|
8231 'documentation' |
|
8232 'initialization' |
|
8233 'instance creation' |
|
8234 ). |
|
8235 ]. |
|
8236 ]. |
|
8237 someCategories sort. |
|
8238 |
|
8239 " |
|
8240 remove existing categories |
|
8241 " |
|
8242 existingCategories := methodCategoryListView list. |
|
8243 existingCategories notNil ifTrue:[ |
|
8244 someCategories := someCategories select:[:cat | (existingCategories includes:cat) not]. |
|
8245 ]. |
|
8246 |
|
8247 box := self listBoxTitle:'name of new method category:' |
|
8248 okText:'create' |
|
8249 list:someCategories. |
|
8250 box action:[:aString | self newMethodCategory:aString]. |
|
8251 box showAtPointer |
|
8252 |
|
8253 |
|
8254 |
|
8255 !! |
|
8256 |
|
8257 methodCategoryPrintOut |
|
8258 |printStream| |
|
8259 |
|
8260 self checkClassSelected ifFalse:[^ self]. |
|
8261 self whenMethodCategorySelected:[ |
|
8262 printStream := Printer new. |
|
8263 actualClass printOutCategory:currentMethodCategory on:printStream. |
|
8264 printStream close |
|
8265 ] |
|
8266 !! |
|
8267 |
|
8268 methodCategoryRemove |
|
8269 "show number of methods to remove and query user" |
|
8270 |
|
8271 |count t box| |
|
8272 |
|
8273 currentMethodCategory notNil ifTrue:[ |
|
8274 count := 0. |
|
8275 actualClass methodArray do:[:aMethod | |
|
8276 (aMethod category = currentMethodCategory) ifTrue:[ |
|
8277 count := count + 1 |
|
8278 ] |
|
8279 ]. |
|
8280 (count == 0) ifTrue:[ |
|
8281 currentMethodCategory := nil. |
|
8282 currentMethod := currentSelector := nil. |
|
8283 self updateMethodCategoryListWithScroll:false. |
|
8284 self updateMethodList |
|
8285 ] ifFalse:[ |
|
8286 (count == 1) ifTrue:[ |
|
8287 t := 'remove %1\(with 1 method) ?' |
|
8288 ] ifFalse:[ |
|
8289 t := 'remove %1\(with %2 methods) ?' |
|
8290 ]. |
|
8291 t := resources string:t with:currentMethodCategory with:count printString. |
|
8292 t := t withCRs. |
|
8293 |
|
8294 box := YesNoBox |
|
8295 title:t |
|
8296 yesText:(resources at:'remove') |
|
8297 noText:(resources at:'abort'). |
|
8298 box confirm ifTrue:[ |
|
8299 actualClass methodArray do:[:aMethod | |
|
8300 (aMethod category = currentMethodCategory) ifTrue:[ |
|
8301 actualClass |
|
8302 removeSelector:(actualClass selectorAtMethod:aMethod) |
|
8303 ] |
|
8304 ]. |
|
8305 currentMethodCategory := nil. |
|
8306 currentMethod := currentSelector := nil. |
|
8307 self updateMethodCategoryList. |
|
8308 self updateMethodList |
|
8309 ] |
|
8310 ] |
|
8311 ] |
|
8312 !! |
|
8313 |
|
8314 methodCategoryRename |
|
8315 "launch an enterBox to rename current method category" |
|
8316 |
|
8317 |box| |
|
8318 |
|
8319 self checkMethodCategorySelected ifFalse:[^ self]. |
|
8320 |
|
8321 box := self enterBoxTitle:(resources string:'rename method category %1 to:' with:currentMethodCategory) |
|
8322 okText:(resources at:'rename'). |
|
8323 box initialText:currentMethodCategory. |
|
8324 box action:[:aString | |
|
8325 actualClass renameCategory:currentMethodCategory to:aString. |
|
8326 currentMethodCategory := aString. |
|
8327 currentMethod := currentSelector := nil. |
|
8328 self updateMethodCategoryList. |
|
8329 self updateMethodListWithScroll:false |
|
8330 ]. |
|
8331 box showAtPointer |
|
8332 !! |
|
8333 |
|
8334 methodCategorySpawn |
|
8335 "create a new SystemBrowser browsing current method category" |
|
8336 |
|
8337 currentMethodCategory notNil ifTrue:[ |
|
8338 self withWaitCursorDo:[ |
|
8339 SystemBrowser browseClass:actualClass |
|
8340 methodCategory:currentMethodCategory |
|
8341 ] |
|
8342 ] |
|
8343 !! |
|
8344 |
|
8345 methodCategorySpawnCategory |
|
8346 "create a new SystemBrowser browsing all methods from all |
|
8347 classes with same category as current method category" |
|
8348 |
|
8349 self askAndBrowseMethodCategory:'category to browse methods:' |
|
8350 action:[:aString | |
|
8351 SystemBrowser browseMethodCategory:aString |
|
8352 ] |
|
8353 !! !! |
|
8354 |
|
8355 !!BrowserView methodsFor:'method category stuff'!! |
|
8356 |
|
8357 checkMethodCategorySelected |
|
8358 currentMethodCategory isNil ifTrue:[ |
|
8359 self warn:'select a method category first'. |
|
8360 ^ false |
|
8361 ]. |
|
8362 ^ true |
|
8363 !! |
|
8364 |
|
8365 copyMethodsFromClass:aClassName |
|
8366 |class box| |
|
8367 |
|
8368 currentClass notNil ifTrue:[ |
|
8369 class := Smalltalk classNamed:aClassName. |
|
8370 class isBehavior ifFalse:[ |
|
8371 self warn:'no class named %1' with:aClassName. |
|
8372 ^ self |
|
8373 ]. |
|
8374 |
|
8375 showInstance ifFalse:[ |
|
8376 class := class class |
|
8377 ]. |
|
8378 |
|
8379 "show enterbox for category to copy from" |
|
8380 |
|
8381 box := self enterBoxTitle:'name of category to copy from (matchpattern allowed, * for all):' |
|
8382 okText:'copy'. |
|
8383 box action:[:aString | self copyMethodsFromClass:class category:aString]. |
|
8384 box showAtPointer. |
|
8385 ] |
|
8386 !! |
|
8387 |
|
8388 copyMethodsFromClass:class category:category |
|
8389 currentClass notNil ifTrue:[ |
|
8390 Object abortSignal catch:[ |
|
8391 class methodArray do:[:aMethod | |
|
8392 |source| |
|
8393 |
|
8394 (category match:aMethod category) ifTrue:[ |
|
8395 source := aMethod source. |
|
8396 codeView contents:source. |
|
8397 codeView modified:false. |
|
8398 actualClass compilerClass |
|
8399 compile:source |
|
8400 forClass:actualClass |
|
8401 inCategory:aMethod category |
|
8402 notifying:codeView. |
|
8403 self updateMethodCategoryListWithScroll:false. |
|
8404 self updateMethodListWithScroll:false. |
|
8405 ] |
|
8406 ] |
|
8407 ] |
|
8408 ] |
|
8409 !! |
|
8410 |
|
8411 listOfAllMethodCategoriesInClass:aClass |
|
8412 "answer a list of all method categories of the argument, aClass" |
|
8413 |
|
8414 |newList| |
|
8415 |
|
8416 newList := Set new. |
|
8417 aClass methodArray do:[:aMethod | |
|
8418 |cat| |
|
8419 |
|
8420 cat := aMethod category. |
|
8421 cat isNil ifTrue:[ |
|
8422 cat := '* no category *' |
|
8423 ]. |
|
8424 newList add:cat |
|
8425 ]. |
|
8426 (newList size == 0) ifTrue:[^ nil]. |
|
8427 newList add:'* all *'. |
|
8428 ^ newList asOrderedCollection sort |
|
8429 !! |
|
8430 |
|
8431 listOfAllMethodCategoriesInFullProtocolHierarchy:aClass |
|
8432 "answer a list of all method categories of the argument, aClass, |
|
8433 and all of its superclasses. |
|
8434 Used with fullProtocol browsing." |
|
8435 |
|
8436 |newList| |
|
8437 |
|
8438 newList := Set new. |
|
8439 self classesInFullProtocolHierarchy:aClass do:[:c | |
|
8440 |cat| |
|
8441 |
|
8442 c methodArray do:[:aMethod | |
|
8443 cat := aMethod category. |
|
8444 cat isNil ifTrue:[ |
|
8445 cat := '* no category *' |
|
8446 ]. |
|
8447 newList add:cat |
|
8448 ] |
|
8449 ]. |
|
8450 (newList size == 0) ifTrue:[^ nil]. |
|
8451 newList add:'* all *'. |
|
8452 ^ newList asOrderedCollection sort |
|
8453 !! |
|
8454 |
|
8455 methodCategorySelection:lineNr |
|
8456 "user clicked on a method category line - show selectors" |
|
8457 |
|
8458 "/ |oldSelector| |
|
8459 |
|
8460 "/ oldSelector := currentSelector. |
|
8461 |
|
8462 (fullProtocol not and:[currentClass isNil]) ifTrue:[^ self]. |
|
8463 |
|
8464 currentMethodCategory := methodCategoryListView selectionValue. |
|
8465 self methodCategorySelectionChanged. |
|
8466 aspect := nil. |
|
8467 |
|
8468 "if there is only one method, show it right away" |
|
8469 methodListView list size == 1 ifTrue:[ |
|
8470 methodListView selection:1. |
|
8471 self methodSelection:1 |
|
8472 "/ ] ifFalse:[ |
|
8473 "/ oldSelector notNil ifTrue:[ |
|
8474 "/ methodListView selectElement:oldSelector. |
|
8475 "/ methodListView hasSelection ifTrue:[ |
|
8476 "/ self methodSelection:methodListView selection. |
|
8477 "/ ] |
|
8478 "/ ] |
|
8479 ] |
|
8480 |
|
8481 "Created: 23.11.1995 / 14:19:56 / cg" |
|
8482 !! |
|
8483 |
|
8484 methodCategorySelectionChanged |
|
8485 "method category selection has changed - update dependent views" |
|
8486 |
|
8487 self withWaitCursorDo:[ |
|
8488 currentMethod := currentSelector := nil. |
|
8489 |
|
8490 self updateMethodList. |
|
8491 self updateCodeView. |
|
8492 |
|
8493 currentMethodCategory notNil ifTrue:[ |
|
8494 methodCategoryListView selectElement:currentMethodCategory |
|
8495 ]. |
|
8496 |
|
8497 self setAcceptAndExplainActionsForMethod. |
|
8498 self hilightMethodsInMethodCategoryList:false inMethodList:true. |
|
8499 ] |
|
8500 |
|
8501 "Created: 23.11.1995 / 14:17:38 / cg" |
|
8502 "Modified: 23.11.1995 / 14:19:49 / cg" |
|
8503 !! |
|
8504 |
|
8505 newMethodCategory:aString |
|
8506 |categories| |
|
8507 |
|
8508 currentClass isNil ifTrue:[ |
|
8509 ^ self warn:'select/create a class first'. |
|
8510 ]. |
|
8511 categories := methodCategoryListView list. |
|
8512 categories isNil ifTrue:[categories := OrderedCollection new]. |
|
8513 (categories includes:aString) ifFalse:[ |
|
8514 categories add:aString. |
|
8515 categories sort. |
|
8516 methodCategoryListView contents:categories |
|
8517 ]. |
|
8518 currentMethodCategory := aString. |
|
8519 self methodCategorySelectionChanged |
|
8520 !! |
|
8521 |
|
8522 updateMethodCategoryList |
|
8523 self updateMethodCategoryListWithScroll:true |
|
8524 !! |
|
8525 |
|
8526 updateMethodCategoryListWithScroll:scroll |
|
8527 |categories| |
|
8528 |
|
8529 methodCategoryListView notNil ifTrue:[ |
|
8530 fullProtocol ifTrue:[ |
|
8531 currentClassHierarchy notNil ifTrue:[ |
|
8532 categories := self listOfAllMethodCategoriesInFullProtocolHierarchy:actualClass |
|
8533 ] |
|
8534 ] ifFalse:[ |
|
8535 currentClass notNil ifTrue:[ |
|
8536 categories := self listOfAllMethodCategoriesInClass:actualClass |
|
8537 ] |
|
8538 ]. |
|
8539 methodCategoryListView list = categories ifFalse:[ |
|
8540 scroll ifTrue:[ |
|
8541 methodCategoryListView contents:categories |
|
8542 ] ifFalse:[ |
|
8543 methodCategoryListView setContents:categories |
|
8544 ]. |
|
8545 currentMethodCategory notNil ifTrue:[ |
|
8546 methodCategoryListView selectElement:currentMethodCategory |
|
8547 ] |
|
8548 ] |
|
8549 ] |
|
8550 !! |
|
8551 |
|
8552 whenMethodCategorySelected:aBlock |
|
8553 self checkMethodCategorySelected ifTrue:[ |
|
8554 self withWaitCursorDo:aBlock |
|
8555 ] |
|
8556 !! !! |
|
8557 |
|
8558 !!BrowserView methodsFor:'method list menu'!! |
|
8559 |
|
8560 commonTraceHelperWith:aSelector |
|
8561 currentMethod := MessageTracer perform:aSelector with:currentMethod. |
|
8562 self updateMethodListWithScroll:false keepSelection:true. |
|
8563 currentClass changed:#methodDictionary with:currentSelector. |
|
8564 !! |
|
8565 |
|
8566 methodAproposSearch |
|
8567 "launch an enterBox for a keyword search" |
|
8568 |
|
8569 self askForSelectorTitle:'keyword to search for:' |
|
8570 openWith:#aproposSearch: |
|
8571 !! |
|
8572 |
|
8573 methodBreakPoint |
|
8574 "set a breakpoint on the current method" |
|
8575 |
|
8576 currentSelector notNil ifTrue:[ |
|
8577 currentMethod := actualClass compiledMethodAt:currentSelector. |
|
8578 currentMethod isWrapped ifFalse:[ |
|
8579 (currentMethod notNil and:[currentMethod isWrapped not]) ifTrue:[ |
|
8580 self commonTraceHelperWith:#trapMethod: |
|
8581 ] |
|
8582 ]. |
|
8583 ] |
|
8584 !! |
|
8585 |
|
8586 methodChangeCategory |
|
8587 "move the current method into another category - |
|
8588 nothing done here, but a query for the new category. |
|
8589 Remember the last category, to allow faster category change of a group of methods." |
|
8590 |
|
8591 |box txt| |
|
8592 |
|
8593 self checkMethodSelected ifFalse:[^ self]. |
|
8594 |
|
8595 actualClass isNil ifTrue:[ |
|
8596 box := self enterBoxTitle:'' okText:'change'. |
|
8597 ] ifFalse:[ |
|
8598 |someCategories| |
|
8599 |
|
8600 someCategories := actualClass categories sort. |
|
8601 box := self listBoxTitle:'' okText:'change' list:someCategories. |
|
8602 ]. |
|
8603 box title:('change category from ''' , currentMethod category , ''' to:'). |
|
8604 lastMethodCategory isNil ifTrue:[ |
|
8605 txt := currentMethod category. |
|
8606 ] ifFalse:[ |
|
8607 txt := lastMethodCategory |
|
8608 ]. |
|
8609 box initialText:txt. |
|
8610 box action:[:aString | |
|
8611 lastMethodCategory := aString. |
|
8612 |
|
8613 currentMethod category:aString asSymbol. |
|
8614 actualClass changed. |
|
8615 currentMethod changed:#category. |
|
8616 actualClass updateRevisionString. |
|
8617 actualClass addChangeRecordForMethodCategory:currentMethod category:aString. |
|
8618 self updateMethodCategoryListWithScroll:false. |
|
8619 self updateMethodListWithScroll:false |
|
8620 ]. |
|
8621 box showAtPointer |
|
8622 |
|
8623 "Created: 29.10.1995 / 19:59:22 / cg" |
|
8624 !! |
|
8625 |
|
8626 methodDecompile |
|
8627 "decompile the current methods bytecodes. |
|
8628 The Decompiler is delivered as an extra, and not normally |
|
8629 avaliable with the system." |
|
8630 |
|
8631 self checkMethodSelected ifFalse:[^ self]. |
|
8632 Decompiler notNil ifTrue:[ |
|
8633 Autoload autoloadFailedSignal handle:[:ex | |
|
8634 ex return |
|
8635 ] do:[ |
|
8636 Decompiler autoload. |
|
8637 ]. |
|
8638 ]. |
|
8639 Decompiler isLoaded ifFalse:[ |
|
8640 Smalltalk |
|
8641 fileIn:'/phys/clam/claus/work/libcomp/not_delivered/Decomp.st' |
|
8642 logged:false. |
|
8643 ]. |
|
8644 Decompiler isLoaded ifFalse:[ |
|
8645 ^ self warn:'No decompiler available'. |
|
8646 ]. |
|
8647 |
|
8648 Decompiler decompile:currentMethod. |
|
8649 !! |
|
8650 |
|
8651 methodFileOut |
|
8652 "file out the current method" |
|
8653 |
|
8654 self checkMethodSelected ifFalse:[^ self]. |
|
8655 |
|
8656 self busyLabel:'saving:' with:currentSelector. |
|
8657 Class fileOutErrorSignal handle:[:ex | |
|
8658 self warn:'cannot create: %1' with:ex parameter. |
|
8659 ex return |
|
8660 ] do:[ |
|
8661 actualClass fileOutMethod:currentMethod. |
|
8662 ]. |
|
8663 self normalLabel. |
|
8664 !! |
|
8665 |
|
8666 methodGlobalReferends |
|
8667 "launch an enterBox for global symbol to search for" |
|
8668 |
|
8669 self enterBoxForBrowseTitle:'global variable to browse users of:' |
|
8670 action:[:aString | |
|
8671 SystemBrowser browseReferendsOf:aString asSymbol |
|
8672 ] |
|
8673 !! |
|
8674 |
|
8675 methodImplementors |
|
8676 "launch an enterBox for selector to search for" |
|
8677 |
|
8678 self askForSelectorTitle:'selector to browse implementors of:' |
|
8679 openWith:#browseImplementorsOf: |
|
8680 !! |
|
8681 |
|
8682 methodInspect |
|
8683 "inspect the current method" |
|
8684 |
|
8685 self checkMethodSelected ifFalse:[^ self]. |
|
8686 (actualClass compiledMethodAt:currentSelector) inspect. |
|
8687 !! |
|
8688 |
|
8689 methodLocalAproposSearch |
|
8690 "launch an enterBox for a local keyword search" |
|
8691 |
|
8692 self askForSelectorTitle:'keyword to search for:' |
|
8693 openWith:#aproposSearch:in: |
|
8694 and:(currentClass withAllSubclasses) |
|
8695 !! |
|
8696 |
|
8697 methodLocalImplementors |
|
8698 "launch an enterBox for selector to search for" |
|
8699 |
|
8700 self checkClassSelected ifFalse:[^ self]. |
|
8701 self askForSelectorTitle:'selector to browse local implementors of:' |
|
8702 openWith:#browseImplementorsOf:under: |
|
8703 and:currentClass |
|
8704 !! |
|
8705 |
|
8706 methodLocalSenders |
|
8707 "launch an enterBox for selector to search for in current class & subclasses" |
|
8708 |
|
8709 self checkClassSelected ifFalse:[^ self]. |
|
8710 self askForSelectorTitle:'selector to browse local senders of:' |
|
8711 openWith:#browseCallsOn:under: |
|
8712 and:currentClass |
|
8713 !! |
|
8714 |
|
8715 methodLocalStringSearch |
|
8716 "launch an enterBox for string to search for" |
|
8717 |
|
8718 self checkClassSelected ifFalse:[^ self]. |
|
8719 self askForSelectorTitle:'string to search for in local methods:' |
|
8720 openWith:#browseForString:in: |
|
8721 and:(currentClass withAllSubclasses) |
|
8722 !! |
|
8723 |
|
8724 methodLocalSuperSends |
|
8725 "launch a browser showing super sends in current class & subclasses" |
|
8726 |
|
8727 self checkClassSelected ifFalse:[^ self]. |
|
8728 self withSearchCursorDo:[ |
|
8729 SystemBrowser browseSuperCallsUnder:currentClass |
|
8730 ] |
|
8731 |
|
8732 "Created: 23.11.1995 / 12:03:57 / cg" |
|
8733 "Modified: 23.11.1995 / 14:12:15 / cg" |
|
8734 !! |
|
8735 |
|
8736 methodMakePrivate |
|
8737 "make the current method private. |
|
8738 EXPERIMENTAL" |
|
8739 |
|
8740 self methodPrivacy:#private |
|
8741 !! |
|
8742 |
|
8743 methodMakeProtected |
|
8744 "make the current method protected. |
|
8745 EXPERIMENTAL" |
|
8746 |
|
8747 self methodPrivacy:#protected |
|
8748 !! |
|
8749 |
|
8750 methodMakePublic |
|
8751 "make the current method public. |
|
8752 EXPERIMENTAL" |
|
8753 |
|
8754 self methodPrivacy:#public |
|
8755 !! |
|
8756 |
|
8757 methodMenu |
|
8758 "return a popupmenu as appropriate for the methodList" |
|
8759 |
|
8760 |m labels selectors |
|
8761 newLabels newSelectors |
|
8762 mthdLabels mthdSelectors |
|
8763 brkLabels brkSelectors |
|
8764 fileLabels fileSelectors |
|
8765 searchLabels searchSelectors |
|
8766 sepLocalLabels sepLocalSelectors |
|
8767 localSearchLabels localSearchSelectors| |
|
8768 |
|
8769 device ctrlDown ifTrue:[ |
|
8770 "/ 'secret' developpers menu |
|
8771 |
|
8772 currentMethod isNil ifTrue:[ |
|
8773 methodListView flash. |
|
8774 ^ nil |
|
8775 ]. |
|
8776 labels := #( |
|
8777 'inspect method' |
|
8778 'compile to machine code' |
|
8779 'decompile' |
|
8780 '-' |
|
8781 'make private' |
|
8782 'make protected' |
|
8783 'make public' |
|
8784 ). |
|
8785 selectors := #( |
|
8786 methodInspect |
|
8787 methodSTCCompile |
|
8788 methodDecompile |
|
8789 nil |
|
8790 methodMakePrivate |
|
8791 methodMakeProtected |
|
8792 methodMakePublic |
|
8793 ) |
|
8794 ] ifFalse:[ |
|
8795 |
|
8796 sepLocalLabels := sepLocalSelectors := #(). |
|
8797 |
|
8798 searchLabels := #( |
|
8799 'senders ...' |
|
8800 'implementors ...' |
|
8801 'globals ...' |
|
8802 'string search ...' |
|
8803 'apropos ...' |
|
8804 ). |
|
8805 searchSelectors := #( |
|
8806 methodSenders |
|
8807 methodImplementors |
|
8808 methodGlobalReferends |
|
8809 methodStringSearch |
|
8810 methodAproposSearch |
|
8811 ). |
|
8812 |
|
8813 currentClass notNil ifTrue:[ |
|
8814 localSearchLabels := #( |
|
8815 '-' |
|
8816 'local senders ...' |
|
8817 'local implementors ...' |
|
8818 'local super sends ...' |
|
8819 'local string search ...' |
|
8820 'local apropos ...' |
|
8821 ). |
|
8822 localSearchSelectors := #( |
|
8823 nil |
|
8824 methodLocalSenders |
|
8825 methodLocalImplementors |
|
8826 methodLocalSuperSends |
|
8827 methodLocalStringSearch |
|
8828 methodLocalAproposSearch |
|
8829 ). |
|
8830 ] ifFalse:[ |
|
8831 localSearchLabels := localSearchSelectors := #() |
|
8832 ]. |
|
8833 |
|
8834 currentMethodCategory notNil ifTrue:[ |
|
8835 sepLocalLabels := #('-'). sepLocalSelectors := #(nil). |
|
8836 |
|
8837 newLabels := #( |
|
8838 'new method' |
|
8839 ). |
|
8840 |
|
8841 newSelectors := #( |
|
8842 methodNewMethod |
|
8843 ). |
|
8844 ] ifFalse:[ |
|
8845 newLabels := newSelectors := #() |
|
8846 ]. |
|
8847 |
|
8848 currentMethod notNil ifTrue:[ |
|
8849 fileLabels := #( |
|
8850 'fileOut' |
|
8851 'printOut' |
|
8852 '-' |
|
8853 'SPAWN_METHOD' |
|
8854 '-' |
|
8855 ). |
|
8856 |
|
8857 fileSelectors := #( |
|
8858 methodFileOut |
|
8859 methodPrintOut |
|
8860 nil |
|
8861 methodSpawn |
|
8862 nil |
|
8863 ). |
|
8864 |
|
8865 sepLocalLabels := #('-'). sepLocalSelectors := #(nil). |
|
8866 |
|
8867 mthdLabels := #( |
|
8868 'change category ...' |
|
8869 'remove' |
|
8870 ). |
|
8871 |
|
8872 mthdSelectors := #( |
|
8873 methodChangeCategory |
|
8874 methodRemove |
|
8875 ). |
|
8876 |
|
8877 currentMethod isWrapped ifTrue:[ |
|
8878 brkLabels := #( |
|
8879 'remove break/trace' |
|
8880 '-' |
|
8881 ). |
|
8882 |
|
8883 brkSelectors := #( |
|
8884 methodRemoveBreakOrTrace |
|
8885 nil |
|
8886 ) |
|
8887 ] ifFalse:[ |
|
8888 brkLabels := #( |
|
8889 'breakpoint' |
|
8890 'trace' |
|
8891 'trace sender' |
|
8892 '-' |
|
8893 ). |
|
8894 |
|
8895 brkSelectors := #( |
|
8896 methodBreakPoint |
|
8897 methodTrace |
|
8898 methodTraceSender |
|
8899 nil |
|
8900 ) |
|
8901 ] |
|
8902 ] ifFalse:[ |
|
8903 fileLabels := fileSelectors := #(). |
|
8904 brkLabels := brkSelectors := #(). |
|
8905 mthdLabels := mthdSelectors := #(). |
|
8906 ]. |
|
8907 |
|
8908 |
|
8909 |
|
8910 labels := |
|
8911 fileLabels , |
|
8912 searchLabels , |
|
8913 localSearchLabels , |
|
8914 sepLocalLabels , |
|
8915 brkLabels , |
|
8916 newLabels , |
|
8917 mthdLabels. |
|
8918 |
|
8919 selectors := |
|
8920 fileSelectors , |
|
8921 searchSelectors , |
|
8922 localSearchSelectors , |
|
8923 sepLocalSelectors , |
|
8924 brkSelectors , |
|
8925 newSelectors , |
|
8926 mthdSelectors. |
|
8927 |
|
8928 " |
|
8929 labels := #( |
|
8930 'fileOut' |
|
8931 'printOut' |
|
8932 '-' |
|
8933 'SPAWN_METHOD' |
|
8934 '-' |
|
8935 'senders ...' |
|
8936 'implementors ...' |
|
8937 'globals ...' |
|
8938 'string search ...' |
|
8939 'apropos ...' |
|
8940 '-' |
|
8941 'local senders ...' |
|
8942 'local implementors ...' |
|
8943 'local string search ...' |
|
8944 'local apropos ...' |
|
8945 '-' |
|
8946 'breakpoint' |
|
8947 'trace' |
|
8948 'trace sender' |
|
8949 '-' |
|
8950 'new method' |
|
8951 'change category ...' |
|
8952 'remove' |
|
8953 ). |
|
8954 selectors := #( |
|
8955 methodFileOut |
|
8956 methodPrintOut |
|
8957 nil |
|
8958 methodSpawn |
|
8959 nil |
|
8960 methodSenders |
|
8961 methodImplementors |
|
8962 methodGlobalReferends |
|
8963 methodStringSearch |
|
8964 methodAproposSearch |
|
8965 nil |
|
8966 methodLocalSenders |
|
8967 methodLocalImplementors |
|
8968 methodLocalStringSearch |
|
8969 methodLocalAproposSearch |
|
8970 nil |
|
8971 methodBreakPoint |
|
8972 methodTrace |
|
8973 methodTraceSender |
|
8974 nil |
|
8975 methodNewMethod |
|
8976 methodChangeCategory |
|
8977 methodRemove |
|
8978 ) |
|
8979 " |
|
8980 ]. |
|
8981 m := PopUpMenu |
|
8982 labels:(resources array:labels) |
|
8983 selectors:selectors. |
|
8984 |
|
8985 currentMethod notNil ifTrue:[ |
|
8986 currentMethod isPrivate ifTrue:[ |
|
8987 m disable:#methodMakePrivate |
|
8988 ]. |
|
8989 currentMethod isProtected ifTrue:[ |
|
8990 m disable:#methodMakeProtected |
|
8991 ]. |
|
8992 currentMethod isPublic ifTrue:[ |
|
8993 m disable:#methodMakePublic |
|
8994 ]. |
|
8995 ]. |
|
8996 currentMethod notNil ifTrue:[ |
|
8997 (currentMethod code notNil |
|
8998 or:[Compiler canCreateMachineCode not]) ifTrue:[ |
|
8999 m disable:#methodSTCCompile |
|
9000 ]. |
|
9001 currentMethod byteCode isNil ifTrue:[ |
|
9002 m disable:#methodDecompile |
|
9003 ]. |
|
9004 ]. |
|
9005 ^ m |
|
9006 |
|
9007 "Created: 23.11.1995 / 12:02:29 / cg" |
|
9008 !! |
|
9009 |
|
9010 methodNewMethod |
|
9011 "prepare for definition of a new method - put a template into |
|
9012 code view and define accept-action to compile it" |
|
9013 |
|
9014 currentClass isNil ifTrue:[ |
|
9015 ^ self warn:'select/create a class first'. |
|
9016 ]. |
|
9017 currentMethodCategory isNil ifTrue:[ |
|
9018 ^ self warn:'select/create a method category first'. |
|
9019 ]. |
|
9020 |
|
9021 currentMethod := currentSelector := nil. |
|
9022 |
|
9023 methodListView deselect. |
|
9024 codeView contents:(self template). |
|
9025 codeView modified:false. |
|
9026 |
|
9027 self setAcceptAndExplainActionsForMethod. |
|
9028 !! |
|
9029 |
|
9030 methodPrintOut |
|
9031 "print out the current method" |
|
9032 |
|
9033 |printStream| |
|
9034 |
|
9035 self checkMethodSelected ifFalse:[^ self]. |
|
9036 |
|
9037 printStream := Printer new. |
|
9038 actualClass printOutSource:(currentMethod source) on:printStream. |
|
9039 printStream close |
|
9040 !! |
|
9041 |
|
9042 methodPrivacy:how |
|
9043 "change the current methods privacy. |
|
9044 EXPERIMENTAL" |
|
9045 |
|
9046 self checkMethodSelected ifFalse:[^ self]. |
|
9047 currentMethod isPublic ifFalse:[ |
|
9048 currentMethod privacy:how. |
|
9049 actualClass updateRevisionString. |
|
9050 actualClass addChangeRecordForMethodPrivacy:currentMethod. |
|
9051 self updateMethodListWithScroll:false keepSelection:true. |
|
9052 ] |
|
9053 |
|
9054 "Created: 29.10.1995 / 20:00:00 / cg" |
|
9055 !! |
|
9056 |
|
9057 methodRemove |
|
9058 "remove the current method" |
|
9059 |
|
9060 self checkMethodSelected ifFalse:[^ self]. |
|
9061 actualClass removeSelector:(actualClass selectorAtMethod:currentMethod). |
|
9062 currentMethod := currentSelector := nil. |
|
9063 self updateMethodListWithScroll:false |
|
9064 !! |
|
9065 |
|
9066 methodRemoveBreakOrTrace |
|
9067 "turn off tracing of the current method" |
|
9068 |
|
9069 (currentMethod notNil and:[currentMethod isWrapped]) ifTrue:[ |
|
9070 self commonTraceHelperWith:#unwrapMethod: |
|
9071 ] |
|
9072 !! |
|
9073 |
|
9074 methodSTCCompile |
|
9075 "compile the current method to machine code. |
|
9076 This is not supported on all machines, and never supported in |
|
9077 the demo version." |
|
9078 |
|
9079 |prev| |
|
9080 |
|
9081 self checkMethodSelected ifFalse:[^ self]. |
|
9082 prev := Compiler stcCompilation:#always. |
|
9083 [ |
|
9084 codeView accept. |
|
9085 ] valueNowOrOnUnwindDo:[ |
|
9086 Compiler stcCompilation:prev |
|
9087 ]. |
|
9088 !! |
|
9089 |
|
9090 methodSenders |
|
9091 "launch an enterBox for selector to search for" |
|
9092 |
|
9093 self askForSelectorTitle:'selector to browse senders of:' |
|
9094 openWith:#browseAllCallsOn: |
|
9095 !! |
|
9096 |
|
9097 methodSpawn |
|
9098 "create a new SystemBrowser browsing current method, |
|
9099 or if the current selection is of the form 'class>>selector', spawan |
|
9100 a browser on that method." |
|
9101 |
|
9102 |s sel selSymbol clsName clsSymbol cls isMeta w| |
|
9103 |
|
9104 classMethodListView notNil ifTrue:[ |
|
9105 s := classMethodListView selectionValue. |
|
9106 clsName := self classFromClassMethodString:s. |
|
9107 sel := self selectorFromClassMethodString:s. |
|
9108 isMeta := false |
|
9109 ]. |
|
9110 |
|
9111 self extractClassAndSelectorFromSelectionInto:[:c :s :m | |
|
9112 clsName := c. |
|
9113 sel := s. |
|
9114 isMeta := m |
|
9115 ]. |
|
9116 |
|
9117 (sel notNil and:[clsName notNil]) ifTrue:[ |
|
9118 (clsName knownAsSymbol and:[sel knownAsSymbol]) ifTrue:[ |
|
9119 clsSymbol := clsName asSymbol. |
|
9120 (Smalltalk includesKey:clsSymbol) ifTrue:[ |
|
9121 cls := Smalltalk at:clsSymbol. |
|
9122 isMeta ifTrue:[ |
|
9123 cls := cls class |
|
9124 ]. |
|
9125 cls isBehavior ifFalse:[ |
|
9126 cls := cls class |
|
9127 ]. |
|
9128 cls isBehavior ifTrue:[ |
|
9129 selSymbol := sel asSymbol. |
|
9130 self withWaitCursorDo:[ |
|
9131 (cls implements:selSymbol) ifFalse:[ |
|
9132 cls := cls class. |
|
9133 ]. |
|
9134 (cls implements:selSymbol) ifTrue:[ |
|
9135 SystemBrowser browseClass:cls selector:selSymbol. |
|
9136 ^ self |
|
9137 ]. |
|
9138 w := ' does not implement #' , sel |
|
9139 ] |
|
9140 ] ifFalse:[ |
|
9141 w := ' is not a class' |
|
9142 ] |
|
9143 ] ifFalse:[ |
|
9144 w := ' is unknown' |
|
9145 ] |
|
9146 ] ifFalse:[ |
|
9147 w := ' and/or ' , sel , ' are unknown' |
|
9148 ]. |
|
9149 self warn:(clsName , w). |
|
9150 ^ self |
|
9151 ]. |
|
9152 |
|
9153 self checkMethodSelected ifFalse:[ |
|
9154 self warn:'select a method first'. |
|
9155 ^ self |
|
9156 ]. |
|
9157 |
|
9158 self withWaitCursorDo:[ |
|
9159 w := currentMethod who. |
|
9160 SystemBrowser browseClass:(w at:1) selector:(w at:2) |
|
9161 ] |
|
9162 !! |
|
9163 |
|
9164 methodStringSearch |
|
9165 "launch an enterBox for string to search for" |
|
9166 |
|
9167 self askForSelectorTitle:'string to search for in sources:' |
|
9168 openWith:#browseForString: |
|
9169 !! |
|
9170 |
|
9171 methodTrace |
|
9172 "turn on tracing of the current method" |
|
9173 |
|
9174 currentClass notNil ifTrue:[ |
|
9175 currentSelector notNil ifTrue:[ |
|
9176 currentMethod := actualClass compiledMethodAt:currentSelector |
|
9177 ] |
|
9178 ]. |
|
9179 |
|
9180 (currentMethod notNil and:[currentMethod isWrapped not]) ifTrue:[ |
|
9181 self commonTraceHelperWith:#traceMethod: |
|
9182 ] |
|
9183 !! |
|
9184 |
|
9185 methodTraceSender |
|
9186 "turn on tracing of the current method" |
|
9187 |
|
9188 (currentMethod notNil and:[currentMethod isWrapped not]) ifTrue:[ |
|
9189 self commonTraceHelperWith:#traceMethodSender: |
|
9190 ] |
|
9191 !! !! |
|
9192 |
|
9193 !!BrowserView methodsFor:'method stuff'!! |
|
9194 |
|
9195 checkMethodSelected |
|
9196 currentMethod isNil ifTrue:[ |
|
9197 self warn:'select a method first'. |
|
9198 ^ false |
|
9199 ]. |
|
9200 ^ true |
|
9201 !! |
|
9202 |
|
9203 listOfAllSelectorsInCategory:aCategory inFullProtocolHierarchyOfClass:aClass |
|
9204 "answer a list of all selectors in a given method category |
|
9205 of the argument, aClass and its superclasses. |
|
9206 Used with fullProtocol browsing." |
|
9207 |
|
9208 |newList| |
|
9209 |
|
9210 newList := Set new. |
|
9211 self classesInFullProtocolHierarchy:aClass do:[:c | |
|
9212 |searchCategory| |
|
9213 |
|
9214 (aCategory = '* all *') ifTrue:[ |
|
9215 newList addAll:(c selectorArray) |
|
9216 ] ifFalse:[ |
|
9217 (aCategory = '* no category *') ifTrue:[ |
|
9218 searchCategory := nil |
|
9219 ] ifFalse:[ |
|
9220 searchCategory := aCategory |
|
9221 ]. |
|
9222 c methodArray with:c selectorArray do:[:aMethod :selector | |
|
9223 (aMethod category = searchCategory) ifTrue:[ |
|
9224 newList add:selector |
|
9225 ] |
|
9226 ] |
|
9227 ]. |
|
9228 ]. |
|
9229 (newList size == 0) ifTrue:[^ nil]. |
|
9230 ^ newList asOrderedCollection sort |
|
9231 !! |
|
9232 |
|
9233 listOfAllSelectorsInCategory:aCategory ofClass:aClass |
|
9234 "answer a list of all selectors in a given method category |
|
9235 of the argument, aClass" |
|
9236 |
|
9237 |newList searchCategory all p| |
|
9238 |
|
9239 all := (aCategory = '* all *'). |
|
9240 (aCategory = '* no category *') ifTrue:[ |
|
9241 searchCategory := nil |
|
9242 ] ifFalse:[ |
|
9243 searchCategory := aCategory |
|
9244 ]. |
|
9245 newList := OrderedCollection new. |
|
9246 aClass methodArray with:aClass selectorArray do:[:aMethod :selector | |
|
9247 |sel how| |
|
9248 |
|
9249 (all or:[aMethod category = searchCategory]) ifTrue:[ |
|
9250 sel := selector. |
|
9251 (p := aMethod privacy) ~~ #public ifTrue:[ |
|
9252 how := ' (* ' , p , ' *)'. |
|
9253 ]. |
|
9254 aMethod isWrapped ifTrue:[ |
|
9255 how := ' !!!!' |
|
9256 ]. |
|
9257 aMethod isInvalid ifTrue:[ |
|
9258 how := ' (** not executable **)' |
|
9259 ]. |
|
9260 aMethod isLazyMethod ifTrue:[ |
|
9261 "/ how := ' (lazy)' |
|
9262 ] ifFalse:[ |
|
9263 (aMethod code isNil |
|
9264 and:[aMethod byteCode isNil]) ifTrue:[ |
|
9265 how := ' (** unloaded **)' |
|
9266 ] |
|
9267 ]. |
|
9268 how notNil ifTrue:[sel := sel , how]. |
|
9269 newList add:sel |
|
9270 ] |
|
9271 ]. |
|
9272 (newList size == 0) ifTrue:[^ nil]. |
|
9273 ^ newList sort |
|
9274 |
|
9275 "Modified: 28.8.1995 / 21:53:34 / claus" |
|
9276 !! |
|
9277 |
|
9278 methodSelection:lineNr |
|
9279 "user clicked on a method line - show code" |
|
9280 |
|
9281 |selectorString selectorSymbol| |
|
9282 |
|
9283 (fullProtocol not and:[currentClass isNil]) ifTrue:[^ self]. |
|
9284 |
|
9285 selectorString := methodListView selectionValue. |
|
9286 " |
|
9287 kludge: extract real selector |
|
9288 " |
|
9289 selectorString := selectorString withoutSpaces upTo:(Character space). |
|
9290 selectorSymbol := selectorString asSymbol. |
|
9291 fullProtocol ifTrue:[ |
|
9292 currentMethod := currentSelector := nil. |
|
9293 " |
|
9294 search which class implements the selector |
|
9295 " |
|
9296 self classesInFullProtocolHierarchy:actualClass do:[:c | |
|
9297 (currentMethod isNil |
|
9298 and:[c implements:selectorSymbol]) ifTrue:[ |
|
9299 currentSelector := selectorSymbol. |
|
9300 currentMethod := c compiledMethodAt:selectorSymbol. |
|
9301 acceptClass := c |
|
9302 ] |
|
9303 ] |
|
9304 ] ifFalse:[ |
|
9305 currentSelector := selectorSymbol. |
|
9306 currentMethod := actualClass compiledMethodAt:selectorSymbol. |
|
9307 ]. |
|
9308 |
|
9309 methodCategoryListView notNil ifTrue:[ |
|
9310 currentMethod notNil ifTrue:[ |
|
9311 (currentMethodCategory = currentMethod category) ifFalse:[ |
|
9312 currentMethodCategory := currentMethod category. |
|
9313 methodCategoryListView selectElement:currentMethodCategory |
|
9314 ] |
|
9315 ] |
|
9316 ]. |
|
9317 |
|
9318 self methodSelectionChanged |
|
9319 !! |
|
9320 |
|
9321 methodSelectionChanged |
|
9322 "method selection has changed - update dependent views" |
|
9323 |
|
9324 self withWaitCursorDo:[ |
|
9325 |index cls| |
|
9326 |
|
9327 self updateCodeView. |
|
9328 aspect := nil. |
|
9329 self setAcceptAndExplainActionsForMethod. |
|
9330 |
|
9331 " |
|
9332 if there is any autoSearch string, do the search |
|
9333 " |
|
9334 autoSearch notNil ifTrue:[ |
|
9335 codeView searchFwd:autoSearch startingAtLine:1 col:0 ifAbsent:[] |
|
9336 ]. |
|
9337 |
|
9338 fullProtocol ifTrue:[ |
|
9339 " |
|
9340 remove any bold attribute from classList |
|
9341 " |
|
9342 1 to:classListView list size do:[:i | |
|
9343 classListView attributeAt:i remove:#bold. |
|
9344 ]. |
|
9345 " |
|
9346 boldify the class where this method is implemented |
|
9347 " |
|
9348 currentMethod notNil ifTrue:[ |
|
9349 cls := currentMethod who at:1. |
|
9350 index := classListView list indexOf:(cls name). |
|
9351 (index == 0 |
|
9352 and:[cls isMeta |
|
9353 and:[cls name endsWith:'class']]) ifTrue:[ |
|
9354 index := classListView list indexOf:(cls name copyWithoutLast:5). |
|
9355 ]. |
|
9356 index ~~ 0 ifTrue:[ |
|
9357 classListView attributeAt:index add:#bold. |
|
9358 ]. |
|
9359 currentClass := acceptClass := cls. |
|
9360 ] |
|
9361 ]. |
|
9362 ] |
|
9363 |
|
9364 "Created: 23.11.1995 / 14:17:44 / cg" |
|
9365 !! |
|
9366 |
|
9367 switchToAnyMethodNamed:aString |
|
9368 |aSelector classToStartSearch aClass nm| |
|
9369 |
|
9370 aSelector := aString asSymbol. |
|
9371 currentClass isNil ifTrue:[ |
|
9372 currentClassHierarchy notNil ifTrue:[ |
|
9373 classToStartSearch := currentClassHierarchy |
|
9374 ] |
|
9375 ] ifFalse:[ |
|
9376 classToStartSearch := currentClass |
|
9377 ]. |
|
9378 classToStartSearch notNil ifTrue:[ |
|
9379 showInstance ifFalse:[ |
|
9380 classToStartSearch := classToStartSearch class |
|
9381 ]. |
|
9382 aClass := classToStartSearch whichClassIncludesSelector:aSelector. |
|
9383 aClass notNil ifTrue:[ |
|
9384 nm := aClass name. |
|
9385 showInstance ifFalse:[ |
|
9386 ((nm ~= 'Metaclass') and:[nm endsWith:'class']) ifTrue:[ |
|
9387 nm := nm copyWithoutLast:5 "copyTo:(nm size - 5)" |
|
9388 ] |
|
9389 ]. |
|
9390 self switchToClassNamed:nm. |
|
9391 self switchToMethodNamed:aString |
|
9392 ] |
|
9393 ] |
|
9394 !! |
|
9395 |
|
9396 switchToMethodNamed:matchString |
|
9397 "switch (in the current class) to a method named matchString. |
|
9398 If there are more than one matches, switch to the first." |
|
9399 |
|
9400 |aSelector method cat index classToSearch selectors| |
|
9401 |
|
9402 currentClass notNil ifTrue:[ |
|
9403 showInstance ifTrue:[ |
|
9404 classToSearch := currentClass |
|
9405 ] ifFalse:[ |
|
9406 classToSearch := currentClass class |
|
9407 ]. |
|
9408 selectors := classToSearch selectorArray. |
|
9409 |
|
9410 ((matchString ~= '*') and:[matchString includesMatchCharacters]) ifTrue:[ |
|
9411 index := selectors findFirst:[:element | matchString match:element] |
|
9412 ] ifFalse:[ |
|
9413 index := selectors indexOf:matchString |
|
9414 ]. |
|
9415 |
|
9416 (index ~~ 0) ifTrue:[ |
|
9417 aSelector := selectors at:index. |
|
9418 method := classToSearch methodArray at:index. |
|
9419 cat := method category. |
|
9420 cat isNil ifTrue:[cat := '* all *']. |
|
9421 methodCategoryListView selectElement:cat. |
|
9422 currentMethodCategory := cat. |
|
9423 self updateMethodCategoryListWithScroll:false. |
|
9424 self methodCategorySelectionChanged. |
|
9425 |
|
9426 currentMethod := classToSearch compiledMethodAt:aSelector. |
|
9427 currentMethod notNil ifTrue:[ |
|
9428 currentSelector := aSelector. |
|
9429 methodListView selectElement:aSelector. |
|
9430 ]. |
|
9431 self methodSelectionChanged |
|
9432 ] |
|
9433 ] |
|
9434 !! |
|
9435 |
|
9436 template |
|
9437 "return a method definition template" |
|
9438 |
|
9439 ^ |
|
9440 'message selector and argument names |
|
9441 "comment stating purpose of message" |
|
9442 |
|
9443 |
|
9444 |temporaries| |
|
9445 statements |
|
9446 |
|
9447 |
|
9448 " |
|
9449 change above template into real code. |
|
9450 Then ''accept'' either via the menu |
|
9451 or via the keyboard (usually CMD-A). |
|
9452 |
|
9453 You do not need this template; you can also |
|
9454 select any existing methods code, change it, |
|
9455 and finally ''accept''. |
|
9456 " |
|
9457 ' |
|
9458 !! |
|
9459 |
|
9460 updateMethodList |
|
9461 self updateMethodListWithScroll:true keepSelection:false |
|
9462 !! |
|
9463 |
|
9464 updateMethodListWithScroll:scroll |
|
9465 self updateMethodListWithScroll:scroll keepSelection:false |
|
9466 !! |
|
9467 |
|
9468 updateMethodListWithScroll:scroll keepSelection:keep |
|
9469 |selectors scr first last selection| |
|
9470 |
|
9471 |
|
9472 methodListView notNil ifTrue:[ |
|
9473 selection := methodListView selection. |
|
9474 |
|
9475 currentMethodCategory notNil ifTrue:[ |
|
9476 fullProtocol ifTrue:[ |
|
9477 selectors := self listOfAllSelectorsInCategory:currentMethodCategory |
|
9478 inFullProtocolHierarchyOfClass:actualClass |
|
9479 ] ifFalse:[ |
|
9480 selectors := self listOfAllSelectorsInCategory:currentMethodCategory |
|
9481 ofClass:actualClass |
|
9482 ] |
|
9483 ]. |
|
9484 scr := scroll. |
|
9485 first := methodListView firstLineShown. |
|
9486 first ~~ 1 ifTrue:[ |
|
9487 last := methodListView lastLineShown. |
|
9488 selectors size <= (last - first + 1) ifTrue:[ |
|
9489 scr := true |
|
9490 ] |
|
9491 ]. |
|
9492 methodListView list = selectors ifFalse:[ |
|
9493 scr ifTrue:[ |
|
9494 methodListView contents:selectors |
|
9495 ] ifFalse:[ |
|
9496 methodListView setContents:selectors |
|
9497 ] |
|
9498 ]. |
|
9499 keep ifTrue:[ |
|
9500 methodListView selection:selection. |
|
9501 ] |
|
9502 ] |
|
9503 !! !! |
|
9504 |
|
9505 !!BrowserView methodsFor:'misc'!! |
|
9506 |
|
9507 instanceProtocol:aBoolean |
|
9508 "switch between instance and class protocol" |
|
9509 |
|
9510 |onToggle offToggle| |
|
9511 |
|
9512 showInstance ~~ aBoolean ifTrue:[ |
|
9513 self checkSelectionChangeAllowed ifTrue:[ |
|
9514 instanceToggle notNil ifTrue:[ |
|
9515 aBoolean ifTrue:[ |
|
9516 offToggle := classToggle. |
|
9517 onToggle := instanceToggle. |
|
9518 ] ifFalse:[ |
|
9519 onToggle := classToggle. |
|
9520 offToggle := instanceToggle. |
|
9521 ]. |
|
9522 onToggle turnOn. |
|
9523 offToggle turnOff. |
|
9524 ]. |
|
9525 showInstance := aBoolean. |
|
9526 |
|
9527 (variableListView notNil |
|
9528 and:[variableListView hasSelection]) ifTrue:[ |
|
9529 self unhilightMethodCategories. |
|
9530 self unhilightMethods. |
|
9531 variableListView deselect |
|
9532 ]. |
|
9533 |
|
9534 fullProtocol ifTrue:[ |
|
9535 showInstance ifTrue:[ |
|
9536 actualClass := currentClassHierarchy. |
|
9537 ] ifFalse:[ |
|
9538 actualClass := currentClassHierarchy class. |
|
9539 ]. |
|
9540 acceptClass := actualClass. |
|
9541 |
|
9542 self updateClassList. |
|
9543 self updateMethodCategoryListWithScroll:false. |
|
9544 self updateMethodListWithScroll:false. |
|
9545 self updateVariableList. |
|
9546 ^ self |
|
9547 ]. |
|
9548 currentClass notNil ifTrue:[ |
|
9549 self classSelectionChanged |
|
9550 ]. |
|
9551 codeView modified:false. |
|
9552 ] ifFalse:[ |
|
9553 aBoolean ifTrue:[ |
|
9554 onToggle := classToggle. |
|
9555 offToggle := instanceToggle |
|
9556 ] ifFalse:[ |
|
9557 offToggle := classToggle. |
|
9558 onToggle := instanceToggle. |
|
9559 ]. |
|
9560 onToggle turnOn. |
|
9561 offToggle turnOff. |
|
9562 ] |
|
9563 ] |
|
9564 !! |
|
9565 |
|
9566 processName |
|
9567 "the name of my process - for the processMonitor only" |
|
9568 |
|
9569 ^ 'System Browser'. |
|
9570 !! |
|
9571 |
|
9572 updateCodeView |
|
9573 |code| |
|
9574 |
|
9575 fullClass ifTrue:[ |
|
9576 currentClass notNil ifTrue:[ |
|
9577 code := currentClass source. |
|
9578 ] |
|
9579 ] ifFalse:[ |
|
9580 currentMethod notNil ifTrue:[ |
|
9581 (codeView acceptAction isNil |
|
9582 and:[actualClass notNil |
|
9583 and:[currentMethodCategory notNil]]) ifTrue:[ |
|
9584 self setAcceptAndExplainActionsForMethod. |
|
9585 ]. |
|
9586 |
|
9587 code := currentMethod source. |
|
9588 |
|
9589 ] |
|
9590 ]. |
|
9591 codeView contents:code. |
|
9592 codeView modified:false. |
|
9593 |
|
9594 self normalLabel. |
|
9595 |
|
9596 "Created: 23.11.1995 / 14:16:43 / cg" |
|
9597 "Modified: 23.11.1995 / 14:19:25 / cg" |
|
9598 !! !! |
|
9599 |
|
9600 !!BrowserView methodsFor:'private'!! |
|
9601 |
|
9602 askAndBrowseMethodCategory:title action:aBlock |
|
9603 "convenient method: setup enterBox with initial being current method category" |
|
9604 |
|
9605 |sel box| |
|
9606 |
|
9607 box := self enterBoxTitle:title okText:'browse'. |
|
9608 sel := codeView selection. |
|
9609 sel isNil ifTrue:[ |
|
9610 currentMethodCategory notNil ifTrue:[ |
|
9611 sel := currentMethodCategory |
|
9612 ] |
|
9613 ]. |
|
9614 sel notNil ifTrue:[ |
|
9615 box initialText:(sel asString withoutSpaces) |
|
9616 ]. |
|
9617 box action:[:aString | self withWaitCursorDo:[aBlock value:aString]]. |
|
9618 box showAtPointer |
|
9619 !! |
|
9620 |
|
9621 askForMethodCategory |
|
9622 |someCategories box txt| |
|
9623 |
|
9624 someCategories := actualClass categories sort. |
|
9625 box := self listBoxTitle:'accept in which method category ?' okText:'accept' list:someCategories. |
|
9626 |
|
9627 lastMethodCategory isNil ifTrue:[ |
|
9628 txt := 'new methods' |
|
9629 ] ifFalse:[ |
|
9630 txt := lastMethodCategory |
|
9631 ]. |
|
9632 box initialText:txt. |
|
9633 box action:[:aString | ^ aString ]. |
|
9634 box showAtPointer. |
|
9635 ^ nil |
|
9636 !! |
|
9637 |
|
9638 askForSelectorTitle:title |
|
9639 "convenient method: setup enterBox with text from codeView or selected |
|
9640 method for browsing based on a selector. Set action and launch box" |
|
9641 |
|
9642 |box| |
|
9643 |
|
9644 box := self enterBoxTitle:title okText:'browse'. |
|
9645 box initialText:(self selectorToSearchFor). |
|
9646 box action:[:aString | aString isEmpty ifTrue:[^ nil]. ^ aString]. |
|
9647 box showAtPointer. |
|
9648 ^ nil |
|
9649 !! |
|
9650 |
|
9651 askForSelectorTitle:title openWith:selector |
|
9652 "convenient method: setup enterBox with text from codeView or selected |
|
9653 method for browsing based on a selector. Set action and launch box" |
|
9654 |
|
9655 |string| |
|
9656 |
|
9657 string := self askForSelectorTitle:title. |
|
9658 string notNil ifTrue:[ |
|
9659 self withSearchCursorDo:[ |
|
9660 SystemBrowser perform:selector with:string |
|
9661 ] |
|
9662 ]. |
|
9663 |
|
9664 "Created: 23.11.1995 / 14:11:34 / cg" |
|
9665 !! |
|
9666 |
|
9667 askForSelectorTitle:title openWith:selector and:arg |
|
9668 "convenient method: setup enterBox with text from codeView or selected |
|
9669 method for browsing based on a selector. Set action and launch box" |
|
9670 |
|
9671 |string| |
|
9672 |
|
9673 string := self askForSelectorTitle:title. |
|
9674 string notNil ifTrue:[ |
|
9675 self withSearchCursorDo:[ |
|
9676 SystemBrowser perform:selector with:string with:arg |
|
9677 ] |
|
9678 ]. |
|
9679 |
|
9680 "Created: 23.11.1995 / 14:11:38 / cg" |
|
9681 !! |
|
9682 |
|
9683 busyLabel:what with:someArgument |
|
9684 "set the title for some warning" |
|
9685 |
|
9686 self label:('System Browser - ' , (resources string:what with:someArgument)) |
|
9687 !! |
|
9688 |
|
9689 checkSelectionChangeAllowedWithCompare:compareOffered |
|
9690 "return true, if selection change is ok; |
|
9691 its not ok, if code has been changed. |
|
9692 in this case, return the result of a user query" |
|
9693 |
|
9694 |action labels values| |
|
9695 |
|
9696 codeView modified ifFalse:[ |
|
9697 ^ true |
|
9698 ]. |
|
9699 |
|
9700 compareOffered ifTrue:[ |
|
9701 labels := #('abort' 'compare' 'accept' 'continue'). |
|
9702 values := #(false #compare #accept true). |
|
9703 ] ifFalse:[ |
|
9704 labels := #('abort' 'accept' 'continue'). |
|
9705 values := #(false #accept true). |
|
9706 ]. |
|
9707 |
|
9708 action := OptionBox |
|
9709 request:(resources at:'text has not been accepted.\\Your modifications will be lost when continuing.') withCRs |
|
9710 label:(resources string:'Attention') |
|
9711 form:(WarningBox iconBitmap) |
|
9712 buttonLabels:(resources array:labels) |
|
9713 values:values |
|
9714 default:true. |
|
9715 action ~~ #accept ifTrue:[ |
|
9716 ^ action |
|
9717 ]. |
|
9718 codeView accept. |
|
9719 ^ true |
|
9720 |
|
9721 "Created: 24.11.1995 / 10:54:46 / cg" |
|
9722 !! |
|
9723 |
|
9724 checkSelectionChangeAllowed |
|
9725 "return true, if selection change is ok; |
|
9726 its not ok, if code has been changed. |
|
9727 in this case, return the result of a user query" |
|
9728 |
|
9729 |what m src v| |
|
9730 |
|
9731 currentMethod notNil ifTrue:[ |
|
9732 m := actualClass compiledMethodAt:currentSelector. |
|
9733 m notNil ifTrue:[ |
|
9734 (src := m source) = codeView contents ifFalse:[ |
|
9735 what := self checkSelectionChangeAllowedWithCompare:true. |
|
9736 what == #compare ifTrue:[ |
|
9737 v := DiffTextView |
|
9738 openOn:codeView contents label:'code here (to be accepted ?)' |
|
9739 and:src label:'methods actual code'. |
|
9740 v label:'comparing method versions'. |
|
9741 ^ false |
|
9742 ]. |
|
9743 ^ what |
|
9744 ] |
|
9745 ] |
|
9746 ]. |
|
9747 |
|
9748 ^ self checkSelectionChangeAllowedWithCompare:false |
|
9749 |
|
9750 "Created: 24.11.1995 / 11:03:33 / cg" |
|
9751 "Modified: 24.11.1995 / 11:05:49 / cg" |
|
9752 !! |
|
9753 |
|
9754 classHierarchyDo:aBlock |
|
9755 "eavluate the 2-arg block for every class, |
|
9756 starting at Object; passing class and nesting level to the block." |
|
9757 |
|
9758 |classes s classDict l| |
|
9759 |
|
9760 classes := Smalltalk allClasses. |
|
9761 classDict := IdentityDictionary new:classes size. |
|
9762 classes do:[:aClass | |
|
9763 s := aClass superclass. |
|
9764 s notNil ifTrue:[ |
|
9765 l := classDict at:s ifAbsent:[nil]. |
|
9766 l isNil ifTrue:[ |
|
9767 l := OrderedCollection new:5. |
|
9768 classDict at:s put:l |
|
9769 ]. |
|
9770 l add:aClass |
|
9771 ] |
|
9772 ]. |
|
9773 self classHierarchyOf:Object level:0 do:aBlock using:classDict |
|
9774 !! |
|
9775 |
|
9776 classHierarchyOf:aClass level:level do:aBlock using:aDictionary |
|
9777 "evaluate the 2-arg block for every subclass of aClass, |
|
9778 passing class and nesting level to the block." |
|
9779 |
|
9780 |names subclasses| |
|
9781 |
|
9782 aBlock value:aClass value:level. |
|
9783 subclasses := aDictionary at:aClass ifAbsent:[nil]. |
|
9784 (subclasses size == 0) ifFalse:[ |
|
9785 names := subclasses collect:[:class | class name]. |
|
9786 names sortWith:subclasses. |
|
9787 subclasses do:[:aSubClass | |
|
9788 self classHierarchyOf:aSubClass level:(level + 1) do:aBlock using:aDictionary |
|
9789 ] |
|
9790 ] |
|
9791 !! |
|
9792 |
|
9793 classesInFullProtocolHierarchy:aClass do:aBlock |
|
9794 "evaluate aBlock for all non-striked out classes in |
|
9795 the hierarchy" |
|
9796 |
|
9797 |index| |
|
9798 |
|
9799 index := (classListView list size). |
|
9800 aClass withAllSuperclasses do:[:c | |
|
9801 (classListView isInSelection:index) ifFalse:[ |
|
9802 aBlock value:c |
|
9803 ]. |
|
9804 index := index - 1 |
|
9805 ] |
|
9806 |
|
9807 !! |
|
9808 |
|
9809 classesInHierarchy:aClass do:aBlock |
|
9810 |index| |
|
9811 |
|
9812 index := (classListView list size). |
|
9813 aClass withAllSuperclasses do:[:c | |
|
9814 (classListView isInSelection:index) ifFalse:[ |
|
9815 aBlock value:c |
|
9816 ]. |
|
9817 index := index - 1 |
|
9818 ] |
|
9819 |
|
9820 !! |
|
9821 |
|
9822 compileCode:someCode |
|
9823 (ReadStream on:someCode) fileIn |
|
9824 !! |
|
9825 |
|
9826 enterBoxForBrowseTitle:title action:aBlock |
|
9827 "convenient method: setup enterBox with text from codeView or selected |
|
9828 method for method browsing based on className/variable" |
|
9829 |
|
9830 |box| |
|
9831 |
|
9832 box := self enterBoxTitle:title okText:'browse'. |
|
9833 box initialText:(self stringToSearchFor). |
|
9834 box action:[:aString | |
|
9835 aString notEmpty ifTrue:[ |
|
9836 self withWaitCursorDo:[aBlock value:aString] |
|
9837 ]. |
|
9838 ]. |
|
9839 box showAtPointer |
|
9840 !! |
|
9841 |
|
9842 enterBoxForCodeSelectionTitle:title okText:okText |
|
9843 "convenient method: setup enterBox with text from codeview" |
|
9844 |
|
9845 |sel box| |
|
9846 |
|
9847 box := self enterBoxTitle:(resources string:title) okText:(resources string:okText). |
|
9848 sel := codeView selection. |
|
9849 sel notNil ifTrue:[ |
|
9850 box initialText:(sel asString withoutSeparators) |
|
9851 ]. |
|
9852 ^ box |
|
9853 !! |
|
9854 |
|
9855 enterBoxForSearchSelectorTitle:title |
|
9856 "convenient method: setup enterBox with text from codeView or selected |
|
9857 method for browsing based on a selector" |
|
9858 |
|
9859 |box| |
|
9860 |
|
9861 box := self enterBoxTitle:title okText:'search'. |
|
9862 box initialText:(self selectorToSearchFor). |
|
9863 ^ box |
|
9864 !! |
|
9865 |
|
9866 enterBoxTitle:title okText:okText |
|
9867 "convenient method: setup enterBox" |
|
9868 |
|
9869 |box| |
|
9870 |
|
9871 box := EnterBox new. |
|
9872 box title:(resources string:title) okText:(resources string:okText). |
|
9873 ^ box |
|
9874 !! |
|
9875 |
|
9876 extractClassAndSelectorFromSelectionInto:aBlock |
|
9877 "given a string which can be either 'class>>sel' or |
|
9878 'class sel', extract className and selector, and call aBlock with |
|
9879 the result." |
|
9880 |
|
9881 |sel clsName isMeta sep s| |
|
9882 |
|
9883 sel := codeView selection. |
|
9884 sel notNil ifTrue:[ |
|
9885 sel := sel asString withoutSeparators. |
|
9886 ('*>>*' match:sel) ifTrue:[ |
|
9887 sep := $> |
|
9888 ] ifFalse:[ |
|
9889 ('* *' match:sel) ifTrue:[ |
|
9890 sep := Character space |
|
9891 ] |
|
9892 ]. |
|
9893 sep notNil ifTrue:[ |
|
9894 " |
|
9895 extract class/sel from selection |
|
9896 " |
|
9897 s := ReadStream on:sel. |
|
9898 clsName := s upTo:sep. |
|
9899 [s peek == sep] whileTrue:[s next]. |
|
9900 sel := s upToEnd. |
|
9901 |
|
9902 (clsName endsWith:'class') ifTrue:[ |
|
9903 isMeta := true. |
|
9904 clsName := clsName copyWithoutLast:5 "copyTo:(clsName size - 5)" |
|
9905 ] ifFalse:[ |
|
9906 isMeta := false |
|
9907 ]. |
|
9908 ] |
|
9909 ]. |
|
9910 aBlock value:clsName value:sel value:isMeta |
|
9911 |
|
9912 |
|
9913 !! |
|
9914 |
|
9915 findClassOfVariable:aVariableName accessWith:aSelector |
|
9916 "this method returns the class, in which a variable |
|
9917 is defined; |
|
9918 needs either #instVarNames or #classVarNames as aSelector." |
|
9919 |
|
9920 |cls homeClass| |
|
9921 |
|
9922 " |
|
9923 first, find the class, where the variable is declared |
|
9924 " |
|
9925 cls := currentClass. |
|
9926 [cls notNil] whileTrue:[ |
|
9927 ((cls perform:aSelector) includes:aVariableName) ifTrue:[ |
|
9928 homeClass := cls. |
|
9929 cls := nil. |
|
9930 ] ifFalse:[ |
|
9931 cls := cls superclass |
|
9932 ] |
|
9933 ]. |
|
9934 homeClass isNil ifTrue:[ |
|
9935 "nope, must be one below ... (could optimize a bit, by searching down |
|
9936 for the declaring class ... |
|
9937 " |
|
9938 homeClass := currentClass |
|
9939 ] ifFalse:[ |
|
9940 "/ Transcript showCr:'starting search in ' , homeClass name. |
|
9941 ]. |
|
9942 ^ homeClass |
|
9943 !! |
|
9944 |
|
9945 listBoxForCodeSelectionTitle:title okText:okText |
|
9946 "convenient method: setup listBox with text from codeview" |
|
9947 |
|
9948 |sel box| |
|
9949 |
|
9950 box := self listBoxTitle:title okText:okText list:nil. |
|
9951 sel := codeView selection. |
|
9952 sel notNil ifTrue:[ |
|
9953 box initialText:(sel asString withoutSeparators) |
|
9954 ]. |
|
9955 ^ box |
|
9956 !! |
|
9957 |
|
9958 listBoxTitle:title okText:okText list:aList |
|
9959 "convenient method: setup a listBox & return it" |
|
9960 |
|
9961 |box| |
|
9962 |
|
9963 box := ListSelectionBox |
|
9964 title:(resources string:title) |
|
9965 okText:(resources string:okText) |
|
9966 action:nil. |
|
9967 box list:aList. |
|
9968 ^ box |
|
9969 !! |
|
9970 |
|
9971 normalLabel |
|
9972 "set the normal (inactive) window- and icon labels" |
|
9973 |
|
9974 |l il| |
|
9975 |
|
9976 myLabel notNil ifTrue:[ |
|
9977 "if I have been given an explicit label, |
|
9978 and its not the default, take that one" |
|
9979 |
|
9980 myLabel ~= 'System Browser' ifTrue:[ |
|
9981 l := il := myLabel |
|
9982 ] |
|
9983 ]. |
|
9984 l isNil ifTrue:[ |
|
9985 l := resources string:'System Browser'. |
|
9986 |
|
9987 currentClass notNil ifTrue:[ |
|
9988 l := l, ': ', currentClass name. |
|
9989 classListView isNil ifTrue:[ |
|
9990 currentSelector notNil ifTrue:[ |
|
9991 l := l , ' ' , currentSelector |
|
9992 ] |
|
9993 ]. |
|
9994 il := currentClass name |
|
9995 ] ifFalse:[ |
|
9996 il := l. |
|
9997 ] |
|
9998 ]. |
|
9999 self label:l. |
|
10000 self iconLabel:il. |
|
10001 !! |
|
10002 |
|
10003 selectorToSearchFor |
|
10004 "look in codeView and methodListView for a search-string when searching for selectors" |
|
10005 |
|
10006 |sel t| |
|
10007 |
|
10008 sel := codeView selection. |
|
10009 sel notNil ifTrue:[ |
|
10010 sel := sel asString. |
|
10011 t := Parser selectorInExpression:sel. |
|
10012 t notNil ifTrue:[ |
|
10013 sel := t |
|
10014 ]. |
|
10015 sel := sel withoutSpaces. |
|
10016 sel == #>> ifTrue:[ |
|
10017 "oops - thats probably not what we want here ..." |
|
10018 self extractClassAndSelectorFromSelectionInto:[:c :s :m | |
|
10019 sel := s |
|
10020 ] |
|
10021 ] |
|
10022 ] ifFalse:[ |
|
10023 methodListView notNil ifTrue:[ |
|
10024 sel := methodListView selectionValue |
|
10025 ] ifFalse:[ |
|
10026 classMethodListView notNil ifTrue:[ |
|
10027 sel := classMethodListView selectionValue. |
|
10028 sel notNil ifTrue:[ |
|
10029 sel := self selectorFromClassMethodString:sel |
|
10030 ] |
|
10031 ] |
|
10032 ]. |
|
10033 sel notNil ifTrue:[ |
|
10034 sel := sel withoutSpaces upTo:(Character space) |
|
10035 ] ifFalse:[ |
|
10036 sel := '' |
|
10037 ] |
|
10038 ]. |
|
10039 ^ sel |
|
10040 !! |
|
10041 |
|
10042 setAcceptAndExplainActionsForMethod |
|
10043 "tell the codeView what to do on accept and explain" |
|
10044 |
|
10045 codeView acceptAction:[:theCode | |
|
10046 |cat cls| |
|
10047 |
|
10048 codeView cursor:Cursor execute. |
|
10049 |
|
10050 (cat := currentMethodCategory) = '* all *' ifTrue:[ |
|
10051 "must check from which category this code came from ... |
|
10052 ... thanks to Arno for pointing this out" |
|
10053 |
|
10054 cat := self askForMethodCategory. |
|
10055 ]. |
|
10056 (cat notNil and:[cat notEmpty]) ifTrue:[ |
|
10057 fullProtocol ifTrue:[ |
|
10058 cls := acceptClass "/actualClass whichClassIncludesSelector:currentSelector. |
|
10059 ]. |
|
10060 cls isNil ifTrue:[ |
|
10061 cls := actualClass |
|
10062 ]. |
|
10063 |
|
10064 Object abortSignal catch:[ |
|
10065 lockUpdates := true. |
|
10066 |
|
10067 actualClass compilerClass |
|
10068 compile:theCode asString |
|
10069 forClass:cls |
|
10070 inCategory:cat |
|
10071 notifying:codeView. |
|
10072 |
|
10073 codeView modified:false. |
|
10074 self updateMethodListWithScroll:false. |
|
10075 currentMethod := actualClass compiledMethodAt:currentSelector. |
|
10076 ]. |
|
10077 lockUpdates := false. |
|
10078 ]. |
|
10079 codeView cursor:Cursor normal. |
|
10080 ]. |
|
10081 |
|
10082 codeView explainAction:[:theCode :theSelection | |
|
10083 self showExplanation:(Explainer |
|
10084 explain:theSelection |
|
10085 in:theCode |
|
10086 forClass:actualClass) |
|
10087 ]. |
|
10088 !! |
|
10089 |
|
10090 setDoitActionForClass |
|
10091 "tell the codeView what to do on doIt" |
|
10092 |
|
10093 "set self for doits. This allows accessing the current class |
|
10094 as self, and access to the class variables by name. |
|
10095 " |
|
10096 codeView doItAction:[:theCode | |
|
10097 |compiler| |
|
10098 |
|
10099 currentClass isNil ifTrue:[ |
|
10100 compiler := Compiler |
|
10101 ] ifFalse:[ |
|
10102 compiler := currentClass evaluatorClass |
|
10103 ]. |
|
10104 compiler |
|
10105 evaluate:theCode |
|
10106 in:nil |
|
10107 receiver:currentClass |
|
10108 notifying:codeView |
|
10109 logged:false |
|
10110 ifFail:nil |
|
10111 ]. |
|
10112 !! |
|
10113 |
|
10114 setSearchPattern:aString |
|
10115 codeView setSearchPattern:aString |
|
10116 !! |
|
10117 |
|
10118 showExplanation:someText |
|
10119 "show explanation from Parser" |
|
10120 |
|
10121 self information:someText |
|
10122 !! |
|
10123 |
|
10124 stringToSearchFor |
|
10125 "look in codeView and methodListView for a search-string when searching for classes/names" |
|
10126 |
|
10127 |sel| |
|
10128 |
|
10129 sel := codeView selection. |
|
10130 sel notNil ifTrue:[ |
|
10131 sel := sel asString withoutSpaces |
|
10132 ] ifFalse:[ |
|
10133 sel isNil ifTrue:[ |
|
10134 currentClass notNil ifTrue:[ |
|
10135 sel := currentClass name |
|
10136 ] |
|
10137 ]. |
|
10138 sel notNil ifTrue:[ |
|
10139 sel := sel withoutSpaces |
|
10140 ] ifFalse:[ |
|
10141 sel := '' |
|
10142 ] |
|
10143 ]. |
|
10144 ^ sel |
|
10145 !! |
|
10146 |
|
10147 warnLabel:what |
|
10148 "set the title for some warning" |
|
10149 |
|
10150 self label:('System Browser WARNING: ' , what) |
|
10151 !! |
|
10152 |
|
10153 withSearchCursorDo:aBlock |
|
10154 ^ self withCursor:(Cursor questionMark) do:aBlock |
|
10155 |
|
10156 "Created: 23.11.1995 / 14:11:14 / cg" |
|
10157 !! !! |
|
10158 |
|
10159 !!BrowserView methodsFor:'unused'!! |
|
10160 |
|
10161 listOfAllMethodCategoriesInHierarchy:aClass |
|
10162 "answer a list of all method categories of the argument, aClass, |
|
10163 and all of its superclasses" |
|
10164 |
|
10165 |newList cat| |
|
10166 |
|
10167 newList := Set new. |
|
10168 self classesInHierarchy:aClass do:[:c | |
|
10169 c methodArray do:[:aMethod | |
|
10170 cat := aMethod category. |
|
10171 cat isNil ifTrue:[ |
|
10172 cat := '* no category *' |
|
10173 ]. |
|
10174 newList add:cat |
|
10175 ] |
|
10176 ]. |
|
10177 (newList size == 0) ifTrue:[^ nil]. |
|
10178 newList add:'* all *'. |
|
10179 ^ newList asOrderedCollection sort |
|
10180 |
|
10181 !! |
|
10182 |
|
10183 listOfAllSelectorsInCategory:aCategory inHierarchyOfClass:aClass |
|
10184 "answer a list of all selectors in a given method category |
|
10185 of the argument, aClass and its superclasses" |
|
10186 |
|
10187 |newList| |
|
10188 |
|
10189 newList := Set new. |
|
10190 self classesInHierarchy:aClass do:[:c | |
|
10191 |searchCategory| |
|
10192 |
|
10193 (aCategory = '* all *') ifTrue:[ |
|
10194 newList addAll:(c selectorArray) |
|
10195 ] ifFalse:[ |
|
10196 (aCategory = '* no category *') ifTrue:[ |
|
10197 searchCategory := nil |
|
10198 ] ifFalse:[ |
|
10199 searchCategory := aCategory |
|
10200 ]. |
|
10201 c methodArray with:c selectorArray do:[:aMethod :selector | |
|
10202 (aMethod category = searchCategory) ifTrue:[ |
|
10203 newList add:selector |
|
10204 ] |
|
10205 ] |
|
10206 ]. |
|
10207 ]. |
|
10208 (newList size == 0) ifTrue:[^ nil]. |
|
10209 ^ newList asOrderedCollection sort |
|
10210 !! !! |
|
10211 |
|
10212 !!BrowserView methodsFor:'variable list menu'!! |
|
10213 |
|
10214 allClassOrInstVarRefsTitle:title access:access mods:modifications |
|
10215 "show an enterbox for instVar to search for" |
|
10216 |
|
10217 self doClassMenu:[:currentClass | |
|
10218 |box| |
|
10219 |
|
10220 box := self enterBoxForVariableSearch:title. |
|
10221 box action:[:aVariableName | |
|
10222 |homeClass| |
|
10223 |
|
10224 aVariableName isEmpty ifFalse:[ |
|
10225 self withSearchCursorDo:[ |
|
10226 homeClass := self findClassOfVariable:aVariableName accessWith:access. |
|
10227 access == #classVarNames ifTrue:[ |
|
10228 SystemBrowser |
|
10229 browseClassRefsTo:aVariableName |
|
10230 under:homeClass |
|
10231 modificationsOnly:modifications |
|
10232 ] ifFalse:[ |
|
10233 SystemBrowser |
|
10234 browseInstRefsTo:aVariableName |
|
10235 under:homeClass |
|
10236 modificationsOnly:modifications |
|
10237 ] |
|
10238 ] |
|
10239 ] |
|
10240 ]. |
|
10241 box showAtPointer |
|
10242 ] |
|
10243 |
|
10244 "Created: 23.11.1995 / 14:13:24 / cg" |
|
10245 !! |
|
10246 |
|
10247 allClassVarMods |
|
10248 "show an enterbox for classVar to search for" |
|
10249 |
|
10250 self allClassOrInstVarRefsTitle:'class variable to browse modifications of:' |
|
10251 access:#classVarNames |
|
10252 mods:true |
|
10253 !! |
|
10254 |
|
10255 allClassVarRefs |
|
10256 "show an enterbox for classVar to search for" |
|
10257 |
|
10258 self allClassOrInstVarRefsTitle:'class variable to browse references to:' |
|
10259 access:#classVarNames |
|
10260 mods:false |
|
10261 !! |
|
10262 |
|
10263 allInstVarMods |
|
10264 "show an enterbox for instVar to search for" |
|
10265 |
|
10266 self allClassOrInstVarRefsTitle:'instance variable to browse modifications of:' |
|
10267 access:#instVarNames |
|
10268 mods:true |
|
10269 !! |
|
10270 |
|
10271 allInstVarRefs |
|
10272 "show an enterbox for instVar to search for" |
|
10273 |
|
10274 self allClassOrInstVarRefsTitle:'instance variable to browse references to:' |
|
10275 access:#instVarNames |
|
10276 mods:false |
|
10277 !! |
|
10278 |
|
10279 classVarMods |
|
10280 "show an enterbox for classVar to search for" |
|
10281 |
|
10282 self classVarRefsOrModsTitle:'class variable to browse modifications of:' |
|
10283 mods:true |
|
10284 !! |
|
10285 |
|
10286 classVarRefs |
|
10287 "show an enterbox for classVar to search for" |
|
10288 |
|
10289 self classVarRefsOrModsTitle:'class variable to browse references to:' |
|
10290 mods:false |
|
10291 !! |
|
10292 |
|
10293 classVarRefsOrModsTitle:title mods:mods |
|
10294 "show an enterbox for classVar to search for" |
|
10295 |
|
10296 self doClassMenu:[:currentClass | |
|
10297 |box| |
|
10298 |
|
10299 box := self enterBoxForVariableSearch:title. |
|
10300 box action:[:aString | |
|
10301 aString notEmpty ifTrue:[ |
|
10302 self withSearchCursorDo:[ |
|
10303 SystemBrowser |
|
10304 browseClassRefsTo:aString |
|
10305 in:(Array with:currentClass) |
|
10306 modificationsOnly:mods |
|
10307 ] |
|
10308 ] |
|
10309 ]. |
|
10310 box showAtPointer |
|
10311 ] |
|
10312 |
|
10313 "Created: 23.11.1995 / 14:12:56 / cg" |
|
10314 !! |
|
10315 |
|
10316 enterBoxForVariableSearch:title |
|
10317 |box sel| |
|
10318 |
|
10319 box := self enterBoxForCodeSelectionTitle:title okText:'browse'. |
|
10320 variableListView notNil ifTrue:[ |
|
10321 codeView hasSelection ifFalse:[ |
|
10322 (sel := variableListView selectionValue) notNil ifTrue:[ |
|
10323 (sel startsWith:'---') ifFalse:[ |
|
10324 box initialText:sel |
|
10325 ] |
|
10326 ] |
|
10327 ] |
|
10328 ]. |
|
10329 ^ box |
|
10330 !! |
|
10331 |
|
10332 instVarMods |
|
10333 "show an enterbox for instVar to search for" |
|
10334 |
|
10335 self instVarRefsOrModsTitle:'instance variable to browse modifications of:' |
|
10336 mods:true |
|
10337 !! |
|
10338 |
|
10339 instVarRefs |
|
10340 "show an enterbox for instVar to search for" |
|
10341 |
|
10342 self instVarRefsOrModsTitle:'instance variable to browse references to:' |
|
10343 mods:false |
|
10344 !! |
|
10345 |
|
10346 instVarRefsOrModsTitle:title mods:mods |
|
10347 "show an enterbox for instvar to search for" |
|
10348 |
|
10349 self doClassMenu:[:currentClass | |
|
10350 |box| |
|
10351 |
|
10352 box := self enterBoxForVariableSearch:title. |
|
10353 box action:[:aString | |
|
10354 aString notEmpty ifTrue:[ |
|
10355 self withSearchCursorDo:[ |
|
10356 SystemBrowser |
|
10357 browseInstRefsTo:aString |
|
10358 in:(Array with:currentClass) |
|
10359 modificationsOnly:mods |
|
10360 ] |
|
10361 ] |
|
10362 ]. |
|
10363 box showAtPointer |
|
10364 ] |
|
10365 |
|
10366 "Created: 23.11.1995 / 14:12:40 / cg" |
|
10367 !! |
|
10368 |
|
10369 varTypeInfo |
|
10370 "show typical usage of a variable" |
|
10371 |
|
10372 |name idx classes values value msg cut names instCount subInstCount box |
|
10373 searchClass| |
|
10374 |
|
10375 name := variableListView selectionValue. |
|
10376 name isNil ifTrue:[^ self]. |
|
10377 |
|
10378 searchClass := actualClass whichClassDefinesInstVar:name. |
|
10379 |
|
10380 idx := searchClass instVarOffsetOf:name. |
|
10381 idx isNil ifTrue:[^ self]. |
|
10382 |
|
10383 classes := IdentitySet new. |
|
10384 values := IdentitySet new. |
|
10385 instCount := 0. |
|
10386 subInstCount := 0. |
|
10387 searchClass allSubInstancesDo:[:i | |
|
10388 |val| |
|
10389 |
|
10390 val := i instVarAt:idx. |
|
10391 val notNil ifTrue:[values add:val]. |
|
10392 classes add:val class. |
|
10393 (i isMemberOf:searchClass) ifTrue:[ |
|
10394 instCount := instCount + 1. |
|
10395 ] ifFalse:[ |
|
10396 subInstCount := subInstCount + 1 |
|
10397 ] |
|
10398 ]. |
|
10399 (instCount == 0 and:[subInstCount == 0]) ifTrue:[ |
|
10400 self warn:'there are currently no instances of ' , currentClass name. |
|
10401 ^ self |
|
10402 ]. |
|
10403 |
|
10404 instCount ~~ 0 ifTrue:[ |
|
10405 msg := 'in (currently: ' , instCount printString,') instances '. |
|
10406 subInstCount ~~ 0 ifTrue:[ |
|
10407 msg := msg , 'and ' |
|
10408 ] |
|
10409 ] ifFalse:[ |
|
10410 msg := 'in '. |
|
10411 ]. |
|
10412 subInstCount ~~ 0 ifTrue:[ |
|
10413 msg := msg , '(currently: ' , subInstCount printString, ') derived instances ' |
|
10414 ]. |
|
10415 msg := msg, 'of ' , searchClass name , ',\'. |
|
10416 msg := msg , name , ' '. |
|
10417 ((values size == 1) |
|
10418 or:[classes size == 1 and:[classes first == UndefinedObject]]) ifTrue:[ |
|
10419 values size == 1 ifTrue:[value := values first]. |
|
10420 (value isNumber or:[value isString]) ifTrue:[ |
|
10421 msg := msg , 'is always the same:\\ ' , |
|
10422 value class name , ' (' , value storeString , ')'. |
|
10423 ] ifFalse:[ |
|
10424 (value isNil or:[value == true or:[value == false]]) ifTrue:[ |
|
10425 msg := msg , 'is always:\\ ' , |
|
10426 value printString. |
|
10427 ] ifFalse:[ |
|
10428 msg := msg , 'is always the same:\\'. |
|
10429 msg := msg , ' ' , value class name. |
|
10430 value isLiteral ifTrue:[ |
|
10431 msg := msg , ' (' , value storeString , ')' |
|
10432 ] |
|
10433 ] |
|
10434 ] |
|
10435 ] ifFalse:[ |
|
10436 classes size == 1 ifTrue:[ |
|
10437 msg := msg , 'is always:\\'. |
|
10438 msg := msg , ' ' , classes first name , '\'. |
|
10439 ] ifFalse:[ |
|
10440 msg := msg , 'is one of:\\'. |
|
10441 classes := classes asOrderedCollection. |
|
10442 classes size > 20 ifTrue:[ |
|
10443 classes := classes copyFrom:1 to:20. |
|
10444 cut := true |
|
10445 ] ifFalse:[ |
|
10446 cut := false. |
|
10447 ]. |
|
10448 names := classes collect:[:cls | |
|
10449 |nm| |
|
10450 cls == UndefinedObject ifTrue:[ |
|
10451 'nil' |
|
10452 ] ifFalse:[ |
|
10453 cls == True ifTrue:[ |
|
10454 'true' |
|
10455 ] ifFalse:[ |
|
10456 cls == False ifTrue:[ |
|
10457 'false' |
|
10458 ] ifFalse:[ |
|
10459 cls name |
|
10460 ] |
|
10461 ] |
|
10462 ]. |
|
10463 ]. |
|
10464 names sort. |
|
10465 names do:[:nm | |
|
10466 msg := msg , ' ' , nm , '\'. |
|
10467 ]. |
|
10468 ] |
|
10469 ]. |
|
10470 |
|
10471 box := InfoBox title:msg withCRs. |
|
10472 box label:'variable type information'. |
|
10473 box showAtPointer |
|
10474 !! |
|
10475 |
|
10476 variableListMenu |
|
10477 |labels selectors| |
|
10478 |
|
10479 currentClass isNil ifTrue:[ |
|
10480 variableListView flash. |
|
10481 ^ nil |
|
10482 ]. |
|
10483 |
|
10484 labels := #( |
|
10485 'instvar refs ...' |
|
10486 'classvar refs ...' |
|
10487 'all instvar refs ...' |
|
10488 'all classvar refs ...' |
|
10489 '-' |
|
10490 'instvar mods ...' |
|
10491 'classvar mods ...' |
|
10492 'all instvar mods ...' |
|
10493 'all classvar mods ...' |
|
10494 ). |
|
10495 selectors := #( |
|
10496 instVarRefs |
|
10497 classVarRefs |
|
10498 allInstVarRefs |
|
10499 allClassVarRefs |
|
10500 nil |
|
10501 instVarMods |
|
10502 classVarMods |
|
10503 allInstVarMods |
|
10504 allClassVarMods |
|
10505 ). |
|
10506 |
|
10507 (showInstance and:[variableListView hasSelection]) ifTrue:[ |
|
10508 labels := labels , #( |
|
10509 '-' |
|
10510 'type information' |
|
10511 ). |
|
10512 selectors := selectors , #( |
|
10513 nil |
|
10514 varTypeInfo |
|
10515 ). |
|
10516 ]. |
|
10517 |
|
10518 ^ PopUpMenu labels:(resources array:labels) |
|
10519 selectors:selectors |
|
10520 !! |
|
10521 |
|
10522 variableSelection:lineNr |
|
10523 "variable selection changed" |
|
10524 |
|
10525 |name idx| |
|
10526 |
|
10527 name := variableListView selectionValue. |
|
10528 name isNil ifTrue:[ |
|
10529 self unhilightMethodCategories. |
|
10530 self unhilightMethods. |
|
10531 self autoSearch:nil. |
|
10532 ^ self |
|
10533 ]. |
|
10534 |
|
10535 " |
|
10536 first, check if the selected variable is really the one |
|
10537 we get - reselect if its hidden (for example, a class variable |
|
10538 with the same name could be defined in a subclass) |
|
10539 " |
|
10540 idx := variableListView list findLast:[:entry | entry = name]. |
|
10541 idx ~~ lineNr ifTrue:[ |
|
10542 "select it - user will see whats going on" |
|
10543 variableListView selection:idx |
|
10544 ]. |
|
10545 |
|
10546 "search for methods in the current category, which access the selected |
|
10547 variable, and highlight them" |
|
10548 |
|
10549 self hilightMethodsInMethodCategoryList:true inMethodList:true. |
|
10550 self autoSearch:name. |
|
10551 !! !! |
|
10552 |
|
10553 !!BrowserView methodsFor:'variable stuff'!! |
|
10554 |
|
10555 hilightMethodsInMethodCategoryList |
|
10556 "search for methods which access the selected |
|
10557 variable, and highlight them" |
|
10558 |
|
10559 self hilightMethodsInMethodCategoryList:true inMethodList:false |
|
10560 |
|
10561 |
|
10562 |
|
10563 !! |
|
10564 |
|
10565 hilightMethodsInMethodCategoryList:inCat inMethodList:inMethods |
|
10566 "search for methods which access the selected |
|
10567 variable, and highlight them" |
|
10568 |
|
10569 |name redefinedSelectors| |
|
10570 |
|
10571 variableListView isNil ifTrue:[^ self]. |
|
10572 |
|
10573 inCat ifTrue:[self unhilightMethodCategories]. |
|
10574 inMethods ifTrue:[self unhilightMethods]. |
|
10575 |
|
10576 actualClass isNil ifTrue:[^ self]. |
|
10577 (methodCategoryListView isNil |
|
10578 and:[methodListView isNil]) ifTrue:[^ self]. |
|
10579 |
|
10580 name := variableListView selectionValue. |
|
10581 name isNil ifTrue:[^ self]. |
|
10582 |
|
10583 self withSearchCursorDo:[ |
|
10584 |classes filter any| |
|
10585 |
|
10586 classes := Array with:actualClass. |
|
10587 currentClassHierarchy notNil ifTrue:[ |
|
10588 classes := classes , actualClass allSuperclasses. |
|
10589 redefinedSelectors := IdentitySet new. |
|
10590 ]. |
|
10591 |
|
10592 filter := SystemBrowser filterToSearchRefsTo:name classVars:showInstance not modificationsOnly:false. |
|
10593 |
|
10594 any := false. |
|
10595 " |
|
10596 highlight the method that ref this variable |
|
10597 " |
|
10598 classes do:[:someClass | |
|
10599 (fullProtocol |
|
10600 and:[classListView valueIsInSelection:(someClass name)]) ifFalse:[ |
|
10601 someClass methodArray with:someClass selectorArray |
|
10602 do:[:method :selector | |
|
10603 |
|
10604 (inCat |
|
10605 or:[methodListView list notNil |
|
10606 and:[methodListView list includes:selector]]) |
|
10607 ifTrue:[ |
|
10608 (redefinedSelectors isNil |
|
10609 or:[(redefinedSelectors includes:selector) not]) |
|
10610 ifTrue:[ |
|
10611 (filter value:someClass value:method value:selector) ifTrue:[ |
|
10612 |idx cat| |
|
10613 |
|
10614 (inCat |
|
10615 and:[methodCategoryListView notNil |
|
10616 and:[methodCategoryListView list notNil]]) ifTrue:[ |
|
10617 cat := method category. |
|
10618 " |
|
10619 highlight the methodCategory |
|
10620 " |
|
10621 idx := methodCategoryListView list indexOf:cat. |
|
10622 idx ~~ 0 ifTrue:[ |
|
10623 methodCategoryListView attributeAt:idx put:#bold. |
|
10624 ]. |
|
10625 ]. |
|
10626 |
|
10627 (inMethods |
|
10628 and:[methodListView notNil |
|
10629 and:[methodListView list notNil]]) ifTrue:[ |
|
10630 " |
|
10631 highlight the method |
|
10632 " |
|
10633 idx := methodListView list indexOf:selector. |
|
10634 idx ~~ 0 ifTrue:[ |
|
10635 methodListView attributeAt:idx put:#bold. |
|
10636 ]. |
|
10637 any := true |
|
10638 ]. |
|
10639 ]. |
|
10640 redefinedSelectors notNil ifTrue:[ |
|
10641 redefinedSelectors add:selector |
|
10642 ] |
|
10643 ] |
|
10644 ] |
|
10645 ] |
|
10646 ] |
|
10647 ]. |
|
10648 any ifTrue:[ |
|
10649 self setSearchPattern:name |
|
10650 ] |
|
10651 ] |
|
10652 |
|
10653 "Created: 23.11.1995 / 14:12:08 / cg" |
|
10654 !! |
|
10655 |
|
10656 hilightMethodsInMethodList |
|
10657 "search for methods which access the selected |
|
10658 variable, and highlight them" |
|
10659 |
|
10660 self hilightMethodsInMethodCategoryList:false inMethodList:true |
|
10661 |
|
10662 |
|
10663 |
|
10664 !! |
|
10665 |
|
10666 unhilightMethodCategories |
|
10667 "unhighlight items in method list" |
|
10668 |
|
10669 variableListView isNil ifTrue:[^ self]. |
|
10670 |
|
10671 methodCategoryListView notNil ifTrue:[ |
|
10672 1 to:methodCategoryListView list size do:[:entry | |
|
10673 methodCategoryListView attributeAt:entry put:nil. |
|
10674 ] |
|
10675 ]. |
|
10676 |
|
10677 |
|
10678 !! |
|
10679 |
|
10680 unhilightMethods |
|
10681 "unhighlight items in method list" |
|
10682 |
|
10683 variableListView isNil ifTrue:[^ self]. |
|
10684 |
|
10685 methodListView notNil ifTrue:[ |
|
10686 1 to:methodListView list size do:[:entry | |
|
10687 methodListView attributeAt:entry put:nil. |
|
10688 ]. |
|
10689 ]. |
|
10690 |
|
10691 |
|
10692 !! |
|
10693 |
|
10694 updateVariableList |
|
10695 |l subList last nameAccessSelector class oldSelection| |
|
10696 |
|
10697 variableListView isNil ifTrue:[^ self]. |
|
10698 |
|
10699 oldSelection := variableListView selectionValue. |
|
10700 |
|
10701 l := OrderedCollection new. |
|
10702 " |
|
10703 show classVars, if classProtocol is shown (instead of classInstance vars) |
|
10704 " |
|
10705 showInstance ifTrue:[ |
|
10706 nameAccessSelector := #instVarNames |
|
10707 ] ifFalse:[ |
|
10708 nameAccessSelector := #classVarNames |
|
10709 ]. |
|
10710 |
|
10711 "/ class := currentClass notNil ifTrue:[currentClass] ifFalse:[actualClass]. |
|
10712 "/ class isNil ifTrue:[class := currentClassHierarchy]. |
|
10713 class := currentClassHierarchy notNil ifTrue:[currentClassHierarchy] ifFalse:[currentClass]. |
|
10714 class withAllSuperclasses do:[:aClass | |
|
10715 |ignore| |
|
10716 |
|
10717 ignore := fullProtocol |
|
10718 and:[classListView valueIsInSelection:(aClass name asString)]. |
|
10719 ignore ifFalse:[ |
|
10720 subList := aClass perform:nameAccessSelector. |
|
10721 subList size ~~ 0 ifTrue:[ |
|
10722 l := l , (subList asOrderedCollection reverse). |
|
10723 l := l , (OrderedCollection with:'---- ' , aClass name , ' ---------'). |
|
10724 ] |
|
10725 ] |
|
10726 ]. |
|
10727 l reverse. |
|
10728 variableListView setAttributes:nil. |
|
10729 variableListView list:l. |
|
10730 l keysAndValuesDo:[:index :entry | |
|
10731 (entry startsWith:'---') ifTrue:[ |
|
10732 variableListView attributeAt:index put:#disabled. |
|
10733 last := index |
|
10734 ] |
|
10735 ]. |
|
10736 last notNil ifTrue:[variableListView scrollToLine:last]. |
|
10737 |
|
10738 oldSelection notNil ifTrue:[ |
|
10739 variableListView selectElement:oldSelection. |
|
10740 self hilightMethodsInMethodCategoryList:true inMethodList:true. |
|
10741 ] |
|
10742 !! !! |
|
10743 |
|
10744 !!BrowserView class methodsFor:'documentation'!! |
|
10745 |
|
10746 version |
|
10747 ^ '$Header: /cvs/stx/stx/libtool/BrowserView.st,v 1.58 1995-12-07 12:26:14 cg Exp $'!! !! |
|
10748 BrowserView initialize!! |
|
10749 ! |
|
10750 |
|
10751 classPrimitiveVariables |
|
10752 "show the classes primitiveVariables in the codeView. |
|
10753 Also, set accept action to change it." |
|
10754 |
|
10755 self classShowFrom:#primitiveVariablesString |
|
10756 set:#primitiveVariables: |
|
10757 aspect:#primitiveVariables |
|
10758 default:'%{ |
|
10759 |
|
10760 /* |
|
10761 * any local C variables |
|
10762 * come here (please, define as static) |
|
10763 */ |
|
10764 |
|
10765 %}' |
|
10766 !! |
|
10767 |
|
10768 classPrintOut |
|
10769 self classPrintOutWith:#printOutOn: |
|
10770 !! |
|
10771 |
|
10772 classPrintOutFullProtocol |
|
10773 self classPrintOutWith:#printOutFullProtocolOn: |
|
10774 !! |
|
10775 |
|
10776 classPrintOutProtocol |
|
10777 self classPrintOutWith:#printOutProtocolOn: |
|
10778 !! |
|
10779 |
|
10780 classPrintOutWith:aSelector |
|
10781 self doClassMenu:[:currentClass | |
|
10782 |printStream| |
|
10783 |
|
10784 printStream := Printer new. |
|
10785 currentClass perform:aSelector with:printStream. |
|
10786 printStream close |
|
10787 ] |
|
10788 !! |
|
10789 |
|
10790 classProtocols |
|
10791 ^ self |
|
10792 !! |
|
10793 |
|
10794 classRefs |
|
10795 self doClassMenu:[:currentClass | |
|
10796 self withSearchCursorDo:[ |
|
10797 SystemBrowser browseReferendsOf:currentClass name asSymbol |
|
10798 ] |
|
10799 ] |
|
10800 |
|
10801 "Created: 23.11.1995 / 14:11:43 / cg" |
|
10802 !! |
|
10803 |
|
10804 classRemove |
|
10805 "user requested remove of current class and all subclasses - |
|
10806 count subclasses and let user confirm removal." |
|
10807 |
|
10808 |count t box| |
|
10809 |
|
10810 currentClass notNil ifTrue:[ |
|
10811 count := currentClass allSubclasses size. |
|
10812 t := 'remove %1'. |
|
10813 count ~~ 0 ifTrue:[ |
|
10814 t := t , '\(with %2 subclass'. |
|
10815 count ~~ 1 ifTrue:[ |
|
10816 t := t , 'es' |
|
10817 ]. |
|
10818 t := (t , ')') |
|
10819 ]. |
|
10820 t := t , ' ?'. |
|
10821 t := (resources string:t with:currentClass name with:count) withCRs. |
|
10822 |
|
10823 box := YesNoBox |
|
10824 title:t |
|
10825 yesText:(resources at:'remove') |
|
10826 noText:(resources at:'abort'). |
|
10827 box confirm ifTrue:[ |
|
10828 "after querying user - do really remove current class |
|
10829 and all subclasses |
|
10830 " |
|
10831 self doClassMenu:[:currentClass | |
|
10832 |didRemove| |
|
10833 |
|
10834 didRemove := false. |
|
10835 |
|
10836 " |
|
10837 query ? |
|
10838 " |
|
10839 currentClass allSubclassesDo:[:aSubClass | |
|
10840 (CheckForInstancesWhenRemovingClasses not |
|
10841 or:[aSubClass hasInstances not |
|
10842 or:[self confirm:(aSubClass name , ' has instances - remove anyway ?')]]) |
|
10843 ifTrue:[ |
|
10844 Smalltalk removeClass:aSubClass |
|
10845 ] |
|
10846 ]. |
|
10847 (CheckForInstancesWhenRemovingClasses not |
|
10848 or:[currentClass hasInstances not |
|
10849 or:[self confirm:(currentClass name , ' has instances - remove anyway ?')]]) |
|
10850 ifTrue:[ |
|
10851 didRemove := true. |
|
10852 Smalltalk removeClass:currentClass. |
|
10853 ]. |
|
10854 |
|
10855 self switchToClass:nil. |
|
10856 Smalltalk changed. |
|
10857 self updateClassList. |
|
10858 |
|
10859 "if it was the last in its category, update class category list" |
|
10860 " |
|
10861 classListView numberOfLines == 0 ifTrue:[ |
|
10862 self updateClassCategoryListWithScroll:false |
|
10863 ]. |
|
10864 " |
|
10865 didRemove ifTrue:[ |
|
10866 methodCategoryListView notNil ifTrue:[methodCategoryListView contents:nil]. |
|
10867 methodListView notNil ifTrue:[methodListView contents:nil]. |
|
10868 codeView contents:nil. |
|
10869 codeView modified:false |
|
10870 ] |
|
10871 ] |
|
10872 ] |
|
10873 ] |
|
10874 !! |
|
10875 |
|
10876 classRename |
|
10877 "launch an enterBox for new name and query user" |
|
10878 |
|
10879 |box| |
|
10880 |
|
10881 self checkClassSelected ifFalse:[^ self]. |
|
10882 box := self enterBoxTitle:(resources string:'rename %1 to:' with:currentClass name) okText:'rename'. |
|
10883 box initialText:(currentClass name). |
|
10884 box action:[:aString | self renameCurrentClassTo:aString]. |
|
10885 box showAtPointer |
|
10886 !! |
|
10887 |
|
10888 classShowFrom:getSelector set:setSelector aspect:aspectSymbol default:default |
|
10889 "common helper for comment, primitive-stuff etc. |
|
10890 show the string returned from the classes getSelector-method, |
|
10891 Set acceptaction to change it via setSelector." |
|
10892 |
|
10893 self doClassMenu:[:currentClass | |
|
10894 |text| |
|
10895 |
|
10896 text := currentClass perform:getSelector. |
|
10897 text isNil ifTrue:[ |
|
10898 text := default |
|
10899 ]. |
|
10900 codeView contents:text. |
|
10901 codeView modified:false. |
|
10902 codeView acceptAction:[:theCode | |
|
10903 Object abortSignal catch:[ |
|
10904 lockUpdates := true. |
|
10905 currentClass perform:setSelector with:theCode asString. |
|
10906 codeView modified:false. |
|
10907 ]. |
|
10908 lockUpdates := false. |
|
10909 ]. |
|
10910 codeView explainAction:nil. |
|
10911 |
|
10912 methodListView notNil ifTrue:[ |
|
10913 methodListView deselect |
|
10914 ]. |
|
10915 aspect := aspectSymbol. |
|
10916 self normalLabel |
|
10917 ] |
|
10918 !! |
|
10919 |
|
10920 classSpawn |
|
10921 "create a new SystemBrowser browsing current class, |
|
10922 or if there is a selection, spawn a browser on the selected class |
|
10923 even a class/selector pair can be specified." |
|
10924 |
|
10925 self doClassMenuWithSelection:[:cls :sel | |
|
10926 |browser| |
|
10927 |
|
10928 cls isMeta ifTrue:[ |
|
10929 Smalltalk allBehaviorsDo:[:aClass | |
|
10930 aClass class == cls ifTrue:[ |
|
10931 browser := SystemBrowser browseClass:aClass. |
|
10932 browser instanceProtocol:false. |
|
10933 sel notNil ifTrue:[ |
|
10934 browser switchToMethodNamed:sel |
|
10935 ]. |
|
10936 ^ self |
|
10937 ]. |
|
10938 ]. |
|
10939 self warn:'oops, no class for this metaclass'. |
|
10940 ^ self |
|
10941 ]. |
|
10942 browser := SystemBrowser browseClass:cls. |
|
10943 cls hasMethods ifFalse:[ |
|
10944 browser instanceProtocol:false. |
|
10945 ]. |
|
10946 sel notNil ifTrue:[ |
|
10947 browser switchToMethodNamed:sel |
|
10948 ]. |
|
10949 ] |
|
10950 |
|
10951 " |
|
10952 select 'Smalltalk allClassesDo:' and use spawn from the class menu |
|
10953 select 'Smalltalk' and use spawn from the class menu |
|
10954 " |
|
10955 !! |
|
10956 |
|
10957 classSpawnFullProtocol |
|
10958 "create a new browser, browsing current classes full protocol" |
|
10959 |
|
10960 self doClassMenuWithSelection:[:cls :sel | |
|
10961 SystemBrowser browseFullClassProtocol:cls |
|
10962 ] |
|
10963 !! |
|
10964 |
|
10965 classSpawnHierarchy |
|
10966 "create a new HierarchyBrowser browsing current class" |
|
10967 |
|
10968 self doClassMenuWithSelection:[:cls :sel | |
|
10969 SystemBrowser browseClassHierarchy:cls |
|
10970 ] |
|
10971 !! |
|
10972 |
|
10973 classSpawnSubclasses |
|
10974 "create a new browser browsing current class's subclasses" |
|
10975 |
|
10976 self doClassMenuWithSelection:[:cls :sel | |
|
10977 |subs| |
|
10978 |
|
10979 subs := cls allSubclasses. |
|
10980 (subs notNil and:[subs size ~~ 0]) ifTrue:[ |
|
10981 SystemBrowser browseClasses:subs title:('subclasses of ' , cls name) |
|
10982 ] |
|
10983 ] |
|
10984 !! |
|
10985 |
|
10986 classUnload |
|
10987 "unload an autoloaded class" |
|
10988 |
|
10989 |nm| |
|
10990 |
|
10991 self checkClassSelected ifFalse:[^ self]. |
|
10992 nm := currentClass name. |
|
10993 currentClass unload. |
|
10994 self switchToClassNamed:nm |
|
10995 !! |
|
10996 |
|
10997 classUses |
|
10998 "a powerful tool, when trying to learn more about where |
|
10999 a class is used. This one searches all uses of a class, |
|
11000 and shows a list of uses - try it and like it" |
|
11001 |
|
11002 self doClassMenu:[:currentClass | |
|
11003 self withSearchCursorDo:[ |
|
11004 SystemBrowser browseUsesOf:currentClass |
|
11005 ] |
|
11006 ] |
|
11007 |
|
11008 "Created: 23.11.1995 / 14:11:47 / cg" |
|
11009 !! |
|
11010 |
|
11011 doClassMenuWithSelection:aBlock |
|
11012 "a helper - if there is a selection, which represents a classes name, |
|
11013 evaluate aBlock, passing that class and optional selector as arguments. |
|
11014 Otherwise, check if a class is selected and evaluate aBlock with the |
|
11015 current class." |
|
11016 |
|
11017 |string words clsName cls sel isMeta| |
|
11018 |
|
11019 string := codeView selection. |
|
11020 string notNil ifTrue:[ |
|
11021 self extractClassAndSelectorFromSelectionInto:[:c :s :m | |
|
11022 clsName := c. |
|
11023 sel := s. |
|
11024 isMeta := m. |
|
11025 ]. |
|
11026 clsName isNil ifTrue:[ |
|
11027 string := string asString withoutSeparators. |
|
11028 words := string asCollectionOfWords. |
|
11029 words notNil ifTrue:[ |
|
11030 clsName := words first. |
|
11031 (clsName endsWith:'class') ifTrue:[ |
|
11032 isMeta := true. |
|
11033 clsName := clsName copyWithoutLast:5 "copyTo:(clsName size - 5)" |
|
11034 ] ifFalse:[ |
|
11035 isMeta := false |
|
11036 ]. |
|
11037 sel := Parser selectorInExpression:string. |
|
11038 ] |
|
11039 ]. |
|
11040 clsName notNil ifTrue:[ |
|
11041 (cls := Smalltalk classNamed:clsName) notNil ifTrue:[ |
|
11042 isMeta ifTrue:[ |
|
11043 cls := cls class |
|
11044 ]. |
|
11045 self withWaitCursorDo:[ |
|
11046 aBlock value:cls value:sel. |
|
11047 ]. |
|
11048 ^ self |
|
11049 ] ifFalse:[ |
|
11050 self warn:'no class named: %1 - spawning current' with:clsName |
|
11051 ] |
|
11052 ]. |
|
11053 ]. |
|
11054 |
|
11055 classMethodListView notNil ifTrue:[ |
|
11056 sel := classMethodListView selectionValue. |
|
11057 sel notNil ifTrue:[ |
|
11058 sel := self selectorFromClassMethodString:sel |
|
11059 ] |
|
11060 ]. |
|
11061 self doClassMenu:[:currentClass | aBlock value:currentClass value:sel] |
|
11062 !! !! |
|
11063 |
|
11064 !!BrowserView methodsFor:'class list source administration'!! |
|
11065 |
|
11066 classCreateSourceContainerFor:aClass |
|
11067 "let user specify the source-repository values for aClass" |
|
11068 |
|
11069 |box |
|
11070 moduleDirectory subDirectory |
|
11071 fileName specialFlags |
|
11072 check y component info fn project| |
|
11073 |
|
11074 moduleDirectory := 'stx' asValue. |
|
11075 subDirectory := '' asValue. |
|
11076 |
|
11077 (Project notNil and:[(project := Project current) notNil]) ifTrue:[ |
|
11078 subDirectory value:(project name) |
|
11079 ]. |
|
11080 |
|
11081 info := SourceCodeManager sourceInfoOfClass:aClass. |
|
11082 info notNil ifTrue:[ |
|
11083 (info includesKey:#module) ifTrue:[ |
|
11084 moduleDirectory value:(info at:#module). |
|
11085 ]. |
|
11086 (info includesKey:#directory) ifTrue:[ |
|
11087 subDirectory value:(info at:#directory). |
|
11088 ]. |
|
11089 (info includesKey:#expectedFileName) ifTrue:[ |
|
11090 fn := (info at:#expectedFileName). |
|
11091 ] ifFalse:[ |
|
11092 (info includesKey:#classFileName) ifTrue:[ |
|
11093 fn := (info at:#classFileName). |
|
11094 ] |
|
11095 ] |
|
11096 ]. |
|
11097 |
|
11098 fn isNil ifTrue:[ |
|
11099 fn := (Smalltalk fileNameForClass:aClass) , '.st'. |
|
11100 ]. |
|
11101 "/ |
|
11102 "/ should check for conflicts ... |
|
11103 "/ |
|
11104 |
|
11105 fileName := fn asValue. |
|
11106 |
|
11107 box := DialogBox new. |
|
11108 box label:(resources string:'Repository information for %1' with:aClass name). |
|
11109 |
|
11110 component := box addTextLabel:(resources string:'CREATE_REPOSITORY' with:currentClass name) withCRs. |
|
11111 component adjust:#left; borderWidth:0. |
|
11112 |
|
11113 y := box yPosition. |
|
11114 component := box addTextLabel:(resources string:'Module:'). |
|
11115 component width:0.5; adjust:#right. |
|
11116 box yPosition:y. |
|
11117 component := box addInputFieldOn:moduleDirectory tabable:true. |
|
11118 component width:0.5; left:0.5; immediateAccept:true; acceptOnLeave:false; cursorMovementWhenUpdating:#beginOfLine. |
|
11119 |
|
11120 box addVerticalSpace. |
|
11121 y := box yPosition. |
|
11122 component := box addTextLabel:'Package:'. |
|
11123 component width:0.5; adjust:#right. |
|
11124 box yPosition:y. |
|
11125 component := box addInputFieldOn:subDirectory tabable:true. |
|
11126 component width:0.5; left:0.5; immediateAccept:true; acceptOnLeave:false; cursorMovementWhenUpdating:#beginOfLine. |
|
11127 |
|
11128 box addVerticalSpace. |
|
11129 y := box yPosition. |
|
11130 component := box addTextLabel:'Filename:'. |
|
11131 component width:0.5; adjust:#right. |
|
11132 box yPosition:y. |
|
11133 component := box addInputFieldOn:fileName tabable:true. |
|
11134 component width:0.5; left:0.5; immediateAccept:true; acceptOnLeave:false; cursorMovementWhenUpdating:#beginOfLine. |
|
11135 |
|
11136 box addVerticalSpace. |
|
11137 box addVerticalSpace. |
|
11138 |
|
11139 box addAbortButton; addOkButton. |
|
11140 |
|
11141 box showAtPointer. |
|
11142 |
|
11143 box accepted ifTrue:[ |
|
11144 self halt. |
|
11145 ] |
|
11146 |
|
11147 "Modified: 25.11.1995 / 18:03:25 / cg" |
|
11148 !! |
|
11149 |
|
11150 classCheckin |
|
11151 "check a class into the source repository" |
|
11152 |
|
11153 self doClassMenu:[:currentClass | |
|
11154 |logMessage info| |
|
11155 |
|
11156 (info := SourceCodeManager sourceInfoOfClass:currentClass) isNil ifTrue:[ |
|
11157 ^ self classCreateSourceContainerFor:currentClass |
|
11158 ]. |
|
11159 |
|
11160 logMessage := Dialog |
|
11161 request:'enter a log message:' |
|
11162 initialAnswer:lastSourceLogMessage |
|
11163 onCancel:nil. |
|
11164 |
|
11165 logMessage notNil ifTrue:[ |
|
11166 lastSourceLogMessage := logMessage. |
|
11167 self busyLabel:'checking in %1' with:currentClass name. |
|
11168 (SourceCodeManager checkinClass:currentClass logMessage:logMessage) ifFalse:[ |
|
11169 self warn:'checkin failed'. |
|
11170 ]. |
|
11171 aspect == #revisionInfo ifTrue:[ |
|
11172 self classListUpdate |
|
11173 ]. |
|
11174 self normalLabel. |
|
11175 ] |
|
11176 ] |
|
11177 |
|
11178 "Created: 23.11.1995 / 11:41:38 / cg" |
|
11179 "Modified: 3.12.1995 / 13:28:30 / cg" |
|
11180 !! |
|
11181 |
|
11182 classCompareWithNewestInRepository |
|
11183 "open a diff-textView comparing the current (in-image) version |
|
11184 with the most recent version found in the repository." |
|
11185 |
|
11186 self doClassMenu:[:currentClass | |
|
11187 |aStream comparedSource currentSource v rev revString| |
|
11188 |
|
11189 rev := Dialog request:'compare to revision: (empty for newest)'. |
|
11190 rev notNil ifTrue:[ |
|
11191 rev withoutSpaces isEmpty ifTrue:[ |
|
11192 self busyLabel:'extracting newest %1' with:currentClass name. |
|
11193 aStream := SourceCodeManager mostRecentSourceStreamForClassNamed:currentClass name. |
|
11194 revString := 'newest' |
|
11195 ] ifFalse:[ |
|
11196 self busyLabel:'extracting previous %1' with:currentClass name. |
|
11197 aStream := SourceCodeManager sourceStreamFor:currentClass revision:rev. |
|
11198 revString := rev |
|
11199 ]. |
|
11200 comparedSource := aStream contents. |
|
11201 aStream close. |
|
11202 |
|
11203 self busyLabel:'generating current source ...' with:nil. |
|
11204 |
|
11205 aStream := '' writeStream. |
|
11206 currentClass fileOutOn:aStream withTimeStamp:false. |
|
11207 currentSource := aStream contents. |
|
11208 aStream close. |
|
11209 |
|
11210 self busyLabel:'comparing ...' with:nil. |
|
11211 v := DiffTextView |
|
11212 openOn:currentSource label:'current (' , currentClass revision , ')' |
|
11213 and:comparedSource label:'repository (' , revString , ')'. |
|
11214 v label:'comparing ' , currentClass name. |
|
11215 self normalLabel. |
|
11216 ] |
|
11217 ] |
|
11218 |
|
11219 "Created: 14.11.1995 / 16:43:15 / cg" |
|
11220 "Modified: 22.11.1995 / 22:17:08 / cg" |
|
11221 !! |
|
11222 |
|
11223 classRevisionInfo |
|
11224 "show current classes revision info in codeView" |
|
11225 |
|
11226 self doClassMenu:[:currentClass | |
|
11227 |aStream info info2 s rv| |
|
11228 |
|
11229 aStream := WriteStream on:(String new:200). |
|
11230 currentClass notNil ifTrue:[ |
|
11231 self busyLabel:'extracting revision info' with:nil. |
|
11232 info := currentClass revisionInfo. |
|
11233 |
|
11234 rv := currentClass binaryRevision. |
|
11235 rv notNil ifTrue:[ |
|
11236 aStream nextPutAll:'**** Loaded classes binary information ****'; cr; cr. |
|
11237 aStream nextPutAll:' Binary based upon : ' , rv; cr. |
|
11238 aStream cr. |
|
11239 ]. |
|
11240 |
|
11241 info notNil ifTrue:[ |
|
11242 aStream nextPutAll:'**** Loaded classes source information ****'; cr; cr. |
|
11243 s := info at:#repositoryPath ifAbsent:nil. |
|
11244 s notNil ifTrue:[ |
|
11245 aStream nextPut:' Source repository : ' , s; cr |
|
11246 ]. |
|
11247 aStream nextPutAll:' Filename ........ : ' , (info at:#fileName ifAbsent:'?'); cr. |
|
11248 aStream nextPutAll:' Revision ........ : ' , (info at:#revision ifAbsent:'?'); cr. |
|
11249 aStream nextPutAll:' Checkin date .... : ' , (info at:#date ifAbsent:'?') , ' ' , (info at:#time ifAbsent:'?'); cr. |
|
11250 aStream nextPutAll:' Checkin user .... : ' , (info at:#user ifAbsent:'?'); cr. |
|
11251 |
|
11252 (info2 := currentClass packageSourceCodeInfo) notNil ifTrue:[ |
|
11253 aStream nextPutAll:' Repository: ..... : ' , (info2 at:#module ifAbsent:'?'); cr. |
|
11254 aStream nextPutAll:' Directory: ...... : ' , (info2 at:#directory ifAbsent:'?'); cr. |
|
11255 ]. |
|
11256 aStream nextPutAll:' Container ....... : ' , (info at:#repositoryPathName ifAbsent:'?'); cr. |
|
11257 aStream cr. |
|
11258 |
|
11259 SourceCodeManager notNil ifTrue:[ |
|
11260 aStream nextPutAll:'**** Repository information ****'; cr; cr. |
|
11261 SourceCodeManager writeRevisionLogOf:currentClass to:aStream. |
|
11262 ] |
|
11263 ] ifFalse:[ |
|
11264 aStream nextPutAll:'No revision info found' |
|
11265 ] |
|
11266 ]. |
|
11267 codeView contents:(aStream contents). |
|
11268 |
|
11269 codeView modified:false. |
|
11270 codeView acceptAction:nil. |
|
11271 codeView explainAction:nil. |
|
11272 methodListView notNil ifTrue:[ |
|
11273 methodListView deselect |
|
11274 ]. |
|
11275 aspect := #revisionInfo. |
|
11276 self normalLabel |
|
11277 ] |
|
11278 |
|
11279 "Created: 14.11.1995 / 16:43:15 / cg" |
|
11280 "Modified: 7.12.1995 / 11:00:56 / cg" |
|
11281 !! |
|
11282 |
|
11283 classLoadRevision |
|
11284 "load a specific revision into the system - especially useful to |
|
11285 upgrade a class to the newest revision" |
|
11286 |
|
11287 self doClassMenu:[:currentClass | |
|
11288 |aStream comparedSource currentSource v rev revString what| |
|
11289 |
|
11290 rev := Dialog request:'load which revision: (empty for newest)'. |
|
11291 rev notNil ifTrue:[ |
|
11292 rev withoutSpaces isEmpty ifTrue:[ |
|
11293 what := currentClass name , '(newest)'. |
|
11294 self busyLabel:'extracting %1' with:what. |
|
11295 aStream := SourceCodeManager mostRecentSourceStreamForClassNamed:currentClass name. |
|
11296 revString := 'newest' |
|
11297 ] ifFalse:[ |
|
11298 what := currentClass name , '(' , rev , ')'. |
|
11299 self busyLabel:'extracting %1' with:what. |
|
11300 aStream := SourceCodeManager sourceStreamFor:currentClass revision:rev. |
|
11301 revString := rev |
|
11302 ]. |
|
11303 self busyLabel:'loading %1' with:what . |
|
11304 |
|
11305 [ |
|
11306 Class withoutUpdatingChangesDo:[ |
|
11307 "/ rename the current class - for backup |
|
11308 Smalltalk renameClass:currentClass to:currentClass name , '_saved'. |
|
11309 aStream fileIn. |
|
11310 ]. |
|
11311 ] valueNowOrOnUnwindDo:[ |
|
11312 aStream close. |
|
11313 self normalLabel. |
|
11314 ]. |
|
11315 ] |
|
11316 ] |
|
11317 |
|
11318 "Created: 14.11.1995 / 16:43:15 / cg" |
|
11319 "Modified: 25.11.1995 / 10:44:38 / cg" |
|
11320 !! !! |
|
11321 |
|
11322 !!BrowserView methodsFor:'class stuff'!! |
|
11323 |
|
11324 checkClassSelected |
|
11325 "warn and return false, if no class is selected" |
|
11326 |
|
11327 currentClass isNil ifTrue:[ |
|
11328 self warn:'select a class first'. |
|
11329 ^ false |
|
11330 ]. |
|
11331 ^ true |
|
11332 !! |
|
11333 |
|
11334 classClassDefinitionTemplateFor:name in:cat |
|
11335 "common helper for newClass and newSubclass |
|
11336 - show a template to define class name in category cat. |
|
11337 Also, set acceptaction to install the class." |
|
11338 |
|
11339 currentMethodCategory := nil. |
|
11340 currentMethod := currentSelector := nil. |
|
11341 |
|
11342 classListView deselect. |
|
11343 |
|
11344 fullClass ifFalse:[ |
|
11345 methodCategoryListView contents:nil. |
|
11346 methodListView contents:nil |
|
11347 ]. |
|
11348 |
|
11349 codeView contents:(self templateFor:name in:cat). |
|
11350 codeView modified:false. |
|
11351 |
|
11352 codeView acceptAction:[:theCode | |
|
11353 codeView cursor:Cursor execute. |
|
11354 Object abortSignal catch:[ |
|
11355 |cls| |
|
11356 |
|
11357 cls := (Compiler evaluate:theCode asString notifying:codeView compile:false). |
|
11358 cls isBehavior ifTrue:[ |
|
11359 codeView modified:false. |
|
11360 self classCategoryUpdate. |
|
11361 self updateClassListWithScroll:false. |
|
11362 self switchToClassNamed:(cls name). |
|
11363 ] |
|
11364 ]. |
|
11365 codeView cursor:(Cursor normal). |
|
11366 ]. |
|
11367 codeView explainAction:nil. |
|
11368 self switchToClass:nil |
|
11369 !! |
|
11370 |
|
11371 classListUpdate |
|
11372 RememberAspect ifTrue:[ |
|
11373 aspect == #hierarchy ifTrue:[ |
|
11374 ^ self classHierarchy |
|
11375 ]. |
|
11376 aspect == #classInstVars ifTrue:[ |
|
11377 ^ self classClassInstVars |
|
11378 ]. |
|
11379 aspect == #comment ifTrue:[ |
|
11380 ^ self classComment |
|
11381 ]. |
|
11382 aspect == #primitiveDefinitions ifTrue:[ |
|
11383 ^ self classPrimitiveDefinitions |
|
11384 ]. |
|
11385 aspect == #primitiveFunctions ifTrue:[ |
|
11386 ^ self classPrimitiveFunctions |
|
11387 ]. |
|
11388 aspect == #primitiveVariables ifTrue:[ |
|
11389 ^ self classPrimitiveVariables |
|
11390 ]. |
|
11391 aspect == #revisionInfo ifTrue:[ |
|
11392 ^ self classRevisionInfo |
|
11393 ]. |
|
11394 ]. |
|
11395 self classDefinition |
|
11396 |
|
11397 "Created: 23.11.1995 / 11:28:58 / cg" |
|
11398 "Modified: 23.11.1995 / 11:36:08 / cg" |
|
11399 !! |
|
11400 |
|
11401 classSelection:lineNr |
|
11402 "user clicked on a class line - show method categories" |
|
11403 |
|
11404 |cls oldSelector| |
|
11405 |
|
11406 (currentClassHierarchy notNil |
|
11407 and:[fullProtocol]) ifTrue:[ |
|
11408 oldSelector := currentSelector. |
|
11409 |
|
11410 self updateMethodCategoryListWithScroll:false. |
|
11411 self updateMethodListWithScroll:false. |
|
11412 self updateVariableList. |
|
11413 ^ self |
|
11414 ]. |
|
11415 |
|
11416 cls := Smalltalk classNamed:classListView selectionValue withoutSpaces. |
|
11417 cls notNil ifTrue:[ |
|
11418 self switchToClass:cls. |
|
11419 self classSelectionChanged |
|
11420 ] |
|
11421 !! |
|
11422 |
|
11423 classSelectionChanged |
|
11424 |oldMethodCategory oldMethod oldSelector| |
|
11425 |
|
11426 self withWaitCursorDo:[ |
|
11427 oldMethodCategory := currentMethodCategory. |
|
11428 oldMethod := currentMethod. |
|
11429 oldSelector := currentSelector. |
|
11430 |
|
11431 showInstance ifTrue:[ |
|
11432 actualClass := acceptClass := currentClass |
|
11433 ] ifFalse:[ |
|
11434 actualClass := acceptClass := currentClass class |
|
11435 ]. |
|
11436 currentMethodCategory := nil. |
|
11437 currentMethod := nil. |
|
11438 currentSelector := nil. |
|
11439 |
|
11440 self updateVariableList. |
|
11441 self updateMethodCategoryList. |
|
11442 |
|
11443 oldMethodCategory notNil ifTrue:[ |
|
11444 methodCategoryListView selectElement:oldMethodCategory. |
|
11445 methodCategoryListView hasSelection ifTrue:[ |
|
11446 currentMethodCategory := oldMethodCategory. |
|
11447 self methodCategorySelectionChanged |
|
11448 ] |
|
11449 ]. |
|
11450 self updateMethodList. |
|
11451 self updateCodeView. |
|
11452 |
|
11453 fullClass ifTrue:[ |
|
11454 codeView acceptAction:[:theCode | |
|
11455 codeView cursor:Cursor execute. |
|
11456 Object abortSignal catch:[ |
|
11457 self compileCode:theCode asString. |
|
11458 codeView modified:false. |
|
11459 ]. |
|
11460 codeView cursor:Cursor normal. |
|
11461 ]. |
|
11462 ] ifFalse:[ |
|
11463 "/ self classDefinition. |
|
11464 self classListUpdate. |
|
11465 codeView acceptAction:[:theCode | |
|
11466 codeView cursor:Cursor execute. |
|
11467 Object abortSignal catch:[ |
|
11468 (Compiler evaluate:theCode asString notifying:codeView compile:false) |
|
11469 isBehavior ifTrue:[ |
|
11470 self classCategoryUpdate. |
|
11471 self updateClassListWithScroll:false. |
|
11472 codeView modified:false. |
|
11473 ]. |
|
11474 ]. |
|
11475 codeView cursor:Cursor normal. |
|
11476 ]. |
|
11477 ]. |
|
11478 codeView explainAction:nil. |
|
11479 |
|
11480 classCategoryListView notNil ifTrue:[ |
|
11481 (currentClassCategory = currentClass category) ifFalse:[ |
|
11482 currentClassCategory := currentClass category. |
|
11483 classCategoryListView selectElement:currentClassCategory |
|
11484 ] |
|
11485 ]. |
|
11486 |
|
11487 self setDoitActionForClass |
|
11488 ] |
|
11489 |
|
11490 "Created: 23.11.1995 / 11:32:03 / cg" |
|
11491 !! |
|
11492 |
|
11493 doClassMenu:aBlock |
|
11494 "a helper - check if class is selected and evaluate aBlock |
|
11495 while showing waitCursor" |
|
11496 |
|
11497 self checkClassSelected ifTrue:[ |
|
11498 self withWaitCursorDo:[aBlock value:currentClass] |
|
11499 ] |
|
11500 !! |
|
11501 |
|
11502 listOfAllClassesInCategory:aCategory |
|
11503 "return a list of all classes in a given category" |
|
11504 |
|
11505 |newList classes searchCategory nm| |
|
11506 |
|
11507 (aCategory = '* hierarchy *') ifTrue:[ |
|
11508 newList := OrderedCollection new. |
|
11509 classes := Set new. |
|
11510 self classHierarchyDo:[:aClass :lvl| |
|
11511 nm := aClass name. |
|
11512 (classes includes:nm) ifFalse:[ |
|
11513 classes add:nm. |
|
11514 newList add:(String new:lvl) , nm |
|
11515 ] |
|
11516 ]. |
|
11517 ^ newList |
|
11518 ]. |
|
11519 |
|
11520 newList := Set new. |
|
11521 |
|
11522 (aCategory = '* all *') ifTrue:[ |
|
11523 Smalltalk allBehaviorsDo:[:aClass | |
|
11524 newList add:aClass name |
|
11525 ] |
|
11526 ] ifFalse:[ |
|
11527 (aCategory = '* no category *') ifTrue:[ |
|
11528 searchCategory := nil |
|
11529 ] ifFalse:[ |
|
11530 searchCategory := aCategory |
|
11531 ]. |
|
11532 Smalltalk allBehaviorsDo:[:aClass | |
|
11533 |thisCategory| |
|
11534 |
|
11535 aClass isMeta ifFalse:[ |
|
11536 thisCategory := aClass category. |
|
11537 ((thisCategory = searchCategory) |
|
11538 or:[thisCategory = aCategory]) ifTrue:[ |
|
11539 newList add:aClass name |
|
11540 ] |
|
11541 ] |
|
11542 ] |
|
11543 ]. |
|
11544 (newList size == 0) ifTrue:[^ nil]. |
|
11545 ^ newList asOrderedCollection sort |
|
11546 !! |
|
11547 |
|
11548 listOfClassHierarchyOf:aClass |
|
11549 "return a hierarchy class-list" |
|
11550 |
|
11551 |startClass classes thisOne| |
|
11552 |
|
11553 showInstance ifTrue:[ |
|
11554 startClass := aClass |
|
11555 ] ifFalse:[ |
|
11556 startClass := aClass class. |
|
11557 ]. |
|
11558 classes := startClass allSuperclasses. |
|
11559 thisOne := Array with:startClass. |
|
11560 |
|
11561 classes notNil ifTrue:[ |
|
11562 classes := classes reverse , thisOne. |
|
11563 ] ifFalse:[ |
|
11564 classes := thisOne |
|
11565 ]. |
|
11566 |
|
11567 fullProtocol ifFalse:[ |
|
11568 classes := classes , startClass allSubclassesInOrder |
|
11569 ]. |
|
11570 ^ classes collect:[:c | c name] |
|
11571 !! |
|
11572 |
|
11573 renameCurrentClassTo:aString |
|
11574 "helper - do the rename" |
|
11575 |
|
11576 self doClassMenu:[:currentClass | |
|
11577 |oldName oldSym newSym cls| |
|
11578 |
|
11579 (cls := Smalltalk classNamed:aString) notNil ifTrue:[ |
|
11580 (self confirm:(resources string:'WARN_RENAME' with:aString with:cls category)) |
|
11581 ifFalse:[^ self] |
|
11582 ]. |
|
11583 |
|
11584 oldName := currentClass name. |
|
11585 oldSym := oldName asSymbol. |
|
11586 " |
|
11587 currentClass setName:aString. |
|
11588 newSym := aString asSymbol. |
|
11589 Smalltalk at:oldSym put:nil. |
|
11590 Smalltalk removeKey:oldSym. |
|
11591 Smalltalk at:newSym put:currentClass. |
|
11592 " |
|
11593 " |
|
11594 currentClass renameTo:aString. |
|
11595 " |
|
11596 Smalltalk renameClass:currentClass to:aString. |
|
11597 |
|
11598 self updateClassList. |
|
11599 self updateMethodCategoryListWithScroll:false. |
|
11600 self updateMethodListWithScroll:false. |
|
11601 self withWaitCursorDo:[ |
|
11602 Transcript showCr:('searching for users of ' , oldSym); endEntry. |
|
11603 SystemBrowser browseReferendsOf:oldSym warnIfNone:false |
|
11604 ] |
|
11605 ] |
|
11606 |
|
11607 "Created: 25.11.1995 / 13:02:53 / cg" |
|
11608 !! |
|
11609 |
|
11610 switchToClass:newClass |
|
11611 "switch to some other class; |
|
11612 keep instance protocol as it was ..." |
|
11613 |
|
11614 |cls meta| |
|
11615 |
|
11616 fullProtocol ifTrue:[^ self]. |
|
11617 |
|
11618 cls := newClass. |
|
11619 (meta := cls isMeta) ifTrue:[ |
|
11620 cls := cls soleInstance |
|
11621 ]. |
|
11622 currentClass notNil ifTrue:[ |
|
11623 currentClass removeDependent:self |
|
11624 ]. |
|
11625 currentClass := cls. |
|
11626 showInstance ifTrue:[ |
|
11627 actualClass := acceptClass := cls. |
|
11628 ] ifFalse:[ |
|
11629 actualClass := acceptClass := cls class. |
|
11630 ]. |
|
11631 |
|
11632 currentClass notNil ifTrue:[ |
|
11633 currentClass addDependent:self. |
|
11634 ]. |
|
11635 self normalLabel. |
|
11636 |
|
11637 "Modified: 1.9.1995 / 01:04:05 / claus" |
|
11638 !! |
|
11639 |
|
11640 switchToClassNameMatching:aMatchString |
|
11641 |classNames thisName box| |
|
11642 |
|
11643 classNames := OrderedCollection new. |
|
11644 Smalltalk allBehaviorsDo:[:aClass | |
|
11645 thisName := aClass name. |
|
11646 (aMatchString match:thisName) ifTrue:[ |
|
11647 classNames add:thisName |
|
11648 ] |
|
11649 ]. |
|
11650 (classNames size == 0) ifTrue:[^ nil]. |
|
11651 (classNames size == 1) ifTrue:[ |
|
11652 ^ self switchToClassNamed:(classNames at:1) |
|
11653 ]. |
|
11654 |
|
11655 box := self listBoxTitle:'select class to switch to:' |
|
11656 okText:'ok' |
|
11657 list:classNames sort. |
|
11658 box action:[:aString | self switchToClassNamed:aString]. |
|
11659 box showAtPointer |
|
11660 !! |
|
11661 |
|
11662 switchToClassNamed:aString |
|
11663 |meta str classSymbol theClass newCat element| |
|
11664 |
|
11665 meta := false. |
|
11666 str := aString. |
|
11667 classSymbol := aString asSymbolIfInterned. |
|
11668 classSymbol isNil ifTrue:[ |
|
11669 (aString endsWith:'class') ifTrue:[ |
|
11670 str := aString copyWithoutLast:5. |
|
11671 classSymbol := str asSymbolIfInterned. |
|
11672 classSymbol isNil ifTrue:[ |
|
11673 ^ self |
|
11674 ]. |
|
11675 meta := true |
|
11676 ]. |
|
11677 ]. |
|
11678 |
|
11679 theClass := Smalltalk at:classSymbol. |
|
11680 (theClass isNil and:[str endsWith:'class']) ifTrue:[ |
|
11681 str := str copyWithoutLast:5. |
|
11682 classSymbol := str asSymbolIfInterned. |
|
11683 classSymbol isNil ifTrue:[ |
|
11684 ^ self |
|
11685 ]. |
|
11686 meta := true. |
|
11687 theClass := Smalltalk at:classSymbol. |
|
11688 ]. |
|
11689 |
|
11690 theClass == currentClass ifTrue:[^ self]. |
|
11691 |
|
11692 theClass isBehavior ifTrue:[ |
|
11693 classCategoryListView notNil ifTrue:[ |
|
11694 currentClassHierarchy isNil ifTrue:[ |
|
11695 ((newCat := theClass category) ~= currentClassCategory) ifTrue:[ |
|
11696 currentClassCategory := newCat. |
|
11697 newCat isNil ifTrue:[ |
|
11698 element := '* no category *' |
|
11699 ] ifFalse:[ |
|
11700 element := newCat. |
|
11701 ]. |
|
11702 classCategoryListView selectElement:element. |
|
11703 "/ classCategoryListView makeSelectionVisible. |
|
11704 ] |
|
11705 ] |
|
11706 ]. |
|
11707 self updateClassList. |
|
11708 self switchToClass:theClass. |
|
11709 |
|
11710 classListView selectElement:str. |
|
11711 self instanceProtocol:meta not. |
|
11712 self classSelectionChanged |
|
11713 ] |
|
11714 |
|
11715 "Modified: 1.9.1995 / 01:41:35 / claus" |
|
11716 !! |
|
11717 |
|
11718 templateFor:className in:cat |
|
11719 "return a class definition template - be smart in what is offered initially" |
|
11720 |
|
11721 |aString name i| |
|
11722 |
|
11723 name := 'NewClass'. |
|
11724 i := 1. |
|
11725 [name knownAsSymbol and:[Smalltalk includesKey:name asSymbol]] whileTrue:[ |
|
11726 i := i + 1. |
|
11727 name := 'NewClass' , i printString |
|
11728 ]. |
|
11729 |
|
11730 aString := className , ' subclass:#' , name , ' |
|
11731 instanceVariableNames: '''' |
|
11732 classVariableNames: '''' |
|
11733 poolDictionaries: '''' |
|
11734 category: '''. |
|
11735 |
|
11736 cat notNil ifTrue:[ |
|
11737 aString := aString , cat |
|
11738 ]. |
|
11739 aString := aString , ''' |
|
11740 |
|
11741 |
|
11742 |
|
11743 |
|
11744 |
|
11745 " |
|
11746 Replace ''' , className , ''', ''', name , ''' and |
|
11747 the empty string arguments by true values. |
|
11748 |
|
11749 Install (or change) the class by ''accepting'', |
|
11750 either via the menu or the keyboard (usually CMD-A). |
|
11751 |
|
11752 To be nice to others (and yourself later), do not forget to |
|
11753 add some documentation; either under the classes documentation |
|
11754 protocol, or as a class comment. |
|
11755 " |
|
11756 '. |
|
11757 ^ aString |
|
11758 !! |
|
11759 |
|
11760 updateClassList |
|
11761 self updateClassListWithScroll:true |
|
11762 !! |
|
11763 |
|
11764 updateClassListWithScroll:scroll |
|
11765 |classes oldClassName| |
|
11766 |
|
11767 classListView notNil ifTrue:[ |
|
11768 " |
|
11769 refetch in case we are not up to date |
|
11770 " |
|
11771 (currentClass notNil and:[fullProtocol not]) ifTrue:[ |
|
11772 oldClassName := currentClass name. |
|
11773 currentClass := Smalltalk at:(oldClassName asSymbol). |
|
11774 ]. |
|
11775 |
|
11776 currentClassCategory notNil ifTrue:[ |
|
11777 classes := self listOfAllClassesInCategory:currentClassCategory |
|
11778 ] ifFalse:[ |
|
11779 currentClassHierarchy notNil ifTrue:[ |
|
11780 classes := self listOfClassHierarchyOf:currentClassHierarchy |
|
11781 ] |
|
11782 ]. |
|
11783 |
|
11784 classListView list = classes ifFalse:[ |
|
11785 scroll ifTrue:[ |
|
11786 classListView contents:classes |
|
11787 ] ifFalse:[ |
|
11788 classListView setContents:classes |
|
11789 ]. |
|
11790 oldClassName notNil ifTrue:[ |
|
11791 classListView setContents:classes. |
|
11792 classListView selectElement:oldClassName |
|
11793 ] ifFalse:[ |
|
11794 variableListView notNil ifTrue:[variableListView contents:nil] |
|
11795 ] |
|
11796 ]. |
|
11797 scroll ifTrue:[ |
|
11798 fullProtocol ifTrue:[ |
|
11799 classListView scrollToBottom |
|
11800 ] |
|
11801 ] |
|
11802 ] |
|
11803 !! !! |
|
11804 |
|
11805 !!BrowserView methodsFor:'class-method list menu'!! |
|
11806 |
|
11807 classMethodFileOutAll |
|
11808 "fileout all methods into one source file" |
|
11809 |
|
11810 |list classString selectorString cls mth outStream fileName append |
|
11811 fileBox| |
|
11812 |
|
11813 append := false. |
|
11814 fileBox := FileSaveBox |
|
11815 title:(resources string:'save methodss in:') |
|
11816 okText:(resources string:'save') |
|
11817 abortText:(resources string:'cancel') |
|
11818 action:[:fName | fileName := fName]. |
|
11819 fileBox appendAction:[:fName | fileName := fName. append := true]. |
|
11820 fileBox initialText:'some_methods.st'. |
|
11821 Project notNil ifTrue:[ |
|
11822 fileBox directory:Project currentProjectDirectory |
|
11823 ]. |
|
11824 fileBox showAtPointer. |
|
11825 |
|
11826 fileName notNil ifTrue:[ |
|
11827 " |
|
11828 if file exists, save original in a .sav file |
|
11829 " |
|
11830 fileName asFilename exists ifTrue:[ |
|
11831 fileName asFilename copyTo:(fileName , '.sav') |
|
11832 ]. |
|
11833 append ifTrue:[ |
|
11834 outStream := FileStream appendingOldFileNamed:fileName |
|
11835 ] ifFalse:[ |
|
11836 outStream := FileStream newFileNamed:fileName. |
|
11837 ]. |
|
11838 outStream isNil ifTrue:[ |
|
11839 ^ self warn:'cannot create: %1' with:fileName |
|
11840 ]. |
|
11841 self withWaitCursorDo:[ |
|
11842 list := classMethodListView list. |
|
11843 list do:[:line | |
|
11844 self busyLabel:'writing: ' with:line. |
|
11845 |
|
11846 classString := self classFromClassMethodString:line. |
|
11847 selectorString := self selectorFromClassMethodString:line. |
|
11848 |
|
11849 ((classString ~= 'Metaclass') and:[classString endsWith:'class']) ifTrue:[ |
|
11850 classString := classString copyWithoutLast:5 "copyTo:(classString size - 5)". |
|
11851 cls := (Smalltalk at:classString asSymbol). |
|
11852 cls := cls class |
|
11853 ] ifFalse:[ |
|
11854 cls := (Smalltalk at:classString asSymbol). |
|
11855 ]. |
|
11856 |
|
11857 cls isNil ifTrue:[ |
|
11858 self warn:'oops class %1 is gone' with:classString |
|
11859 ] ifFalse:[ |
|
11860 mth := cls compiledMethodAt:(selectorString asSymbol). |
|
11861 Class fileOutErrorSignal handle:[:ex | |
|
11862 |box| |
|
11863 box := YesNoBox |
|
11864 title:('fileOut error: ' |
|
11865 , ex errorString |
|
11866 , '\\continue anyway ?') withCRs |
|
11867 yesText:'continue' |
|
11868 noText:'abort'. |
|
11869 box confirm ifTrue:[ |
|
11870 ex proceed |
|
11871 ]. |
|
11872 self normalLabel. |
|
11873 ^ self |
|
11874 ] do:[ |
|
11875 cls fileOutMethod:mth on:outStream. |
|
11876 ] |
|
11877 ] |
|
11878 ]. |
|
11879 outStream close. |
|
11880 self normalLabel. |
|
11881 ] |
|
11882 ] |
|
11883 !! |
|
11884 |
|
11885 classMethodMenu |
|
11886 |labels selectors| |
|
11887 |
|
11888 labels := #( |
|
11889 'fileOut' |
|
11890 'fileOut all' |
|
11891 'printOut' |
|
11892 '-' |
|
11893 'spawn' |
|
11894 'spawn class' |
|
11895 'spawn full protocol' |
|
11896 'spawn hierarchy' |
|
11897 '-' |
|
11898 'senders ...' |
|
11899 'implementors ...' |
|
11900 'globals ...' |
|
11901 "/ '-' |
|
11902 "/ 'breakpoint' |
|
11903 "/ 'trace' |
|
11904 "/ 'trace sender' |
|
11905 '-' |
|
11906 'remove' |
|
11907 ). |
|
11908 |
|
11909 selectors := #( |
|
11910 methodFileOut |
|
11911 classMethodFileOutAll |
|
11912 methodPrintOut |
|
11913 nil |
|
11914 methodSpawn |
|
11915 classSpawn |
|
11916 classSpawnFullProtocol |
|
11917 classSpawnHierarchy |
|
11918 nil |
|
11919 methodSenders |
|
11920 methodImplementors |
|
11921 methodGlobalReferends |
|
11922 "/ nil |
|
11923 "/ methodBreakPoint |
|
11924 "/ methodTrace |
|
11925 "/ methodTraceSender |
|
11926 nil |
|
11927 methodRemove |
|
11928 ). |
|
11929 |
|
11930 ^ PopUpMenu labels:(resources array:labels) |
|
11931 selectors:selectors |
|
11932 !! !! |
|
11933 |
|
11934 !!BrowserView methodsFor:'class-method stuff'!! |
|
11935 |
|
11936 classFromClassMethodString:aString |
|
11937 "helper for classMethod-list - extract class name from the string" |
|
11938 |
|
11939 "/ |pos| |
|
11940 "/ |
|
11941 "/ pos := aString indexOf:(Character space). |
|
11942 "/ ^ aString copyTo:(pos - 1) |
|
11943 |
|
11944 ^ aString upTo:Character space |
|
11945 !! |
|
11946 |
|
11947 classMethodSelection:lineNr |
|
11948 "user clicked on a class/method line - show code" |
|
11949 |
|
11950 |cls string classString selectorString meta| |
|
11951 |
|
11952 string := classMethodListView selectionValue. |
|
11953 classString := self classFromClassMethodString:string. |
|
11954 selectorString := self selectorFromClassMethodString:string. |
|
11955 ((classString ~= 'Metaclass') and:[classString endsWith:'class']) ifTrue:[ |
|
11956 classString := classString copyWithoutLast:5 "copyTo:(classString size - 5)". |
|
11957 meta := true. |
|
11958 ] ifFalse:[ |
|
11959 meta := false. |
|
11960 ]. |
|
11961 self switchToClass:(Smalltalk at:classString asSymbol). |
|
11962 meta ifTrue:[cls := currentClass class] ifFalse:[cls := currentClass]. |
|
11963 actualClass := acceptClass := cls. |
|
11964 |
|
11965 currentClass isNil ifTrue:[ |
|
11966 self warn:'oops class is gone' |
|
11967 ] ifFalse:[ |
|
11968 currentClassCategory := currentClass category. |
|
11969 currentSelector := selectorString asSymbol. |
|
11970 currentMethod := actualClass compiledMethodAt:currentSelector. |
|
11971 currentMethod isNil ifTrue:[ |
|
11972 self warn:'oops method is gone' |
|
11973 ] ifFalse:[ |
|
11974 currentMethodCategory := currentMethod category. |
|
11975 ]. |
|
11976 |
|
11977 self methodSelectionChanged |
|
11978 ]. |
|
11979 |
|
11980 self setDoitActionForClass |
|
11981 |
|
11982 "Modified: 31.8.1995 / 11:56:02 / claus" |
|
11983 !! |
|
11984 |
|
11985 selectorFromClassMethodString:aString |
|
11986 "helper for classMethod-list - extract selector from the string" |
|
11987 |
|
11988 |pos| |
|
11989 |
|
11990 pos := aString indexOf:(Character space). |
|
11991 ^ aString copyFrom:(pos + 1) |
|
11992 !! !! |
|
11993 |
|
11994 !!BrowserView methodsFor:'help'!! |
|
11995 |
|
11996 helpTextFor:aComponent |
|
11997 |s| |
|
11998 |
|
11999 aComponent == classCategoryListView ifTrue:[ |
|
12000 s := 'HELP_CCAT_LIST' |
|
12001 ]. |
|
12002 aComponent == classListView ifTrue:[ |
|
12003 fullProtocol ifTrue:[ |
|
12004 s := 'HELP_PCLASS_LIST' |
|
12005 ] ifFalse:[ |
|
12006 currentClassHierarchy notNil ifTrue:[ |
|
12007 s := 'HELP_HCLASS_LIST' |
|
12008 ] ifFalse:[ |
|
12009 s := 'HELP_CLASS_LIST' |
|
12010 ] |
|
12011 ] |
|
12012 ]. |
|
12013 aComponent == methodCategoryListView ifTrue:[ |
|
12014 s := 'HELP_MCAT_LIST' |
|
12015 ]. |
|
12016 aComponent == methodListView ifTrue:[ |
|
12017 s := 'HELP_METHOD_LIST' |
|
12018 ]. |
|
12019 aComponent == variableListView ifTrue:[ |
|
12020 s := 'HELP_VAR_LIST' |
|
12021 ]. |
|
12022 aComponent == codeView ifTrue:[ |
|
12023 fullClass ifTrue:[ |
|
12024 s := 'HELP_FULLCODE_VIEW' |
|
12025 ] ifFalse:[ |
|
12026 s := 'HELP_CODE_VIEW' |
|
12027 ] |
|
12028 ]. |
|
12029 (aComponent == instanceToggle |
|
12030 or:[aComponent == classToggle]) ifTrue:[ |
|
12031 s := 'HELP_INST_CLASS_TOGGLE' |
|
12032 ]. |
|
12033 aComponent == classMethodListView ifTrue:[ |
|
12034 s := 'HELP_CLSMTHOD_LIST' |
|
12035 ]. |
|
12036 s notNil ifTrue:[ |
|
12037 ^ resources string:s |
|
12038 ]. |
|
12039 ^ nil |
|
12040 |
|
12041 "Modified: 31.8.1995 / 19:11:39 / claus" |
|
12042 !! !! |
|
12043 |
|
12044 !!BrowserView methodsFor:'initialize / release'!! |
|
12045 |
|
12046 autoSearch:aString |
|
12047 "used with class-method list browsing. If true, |
|
12048 selecting an entry from the list will automatically |
|
12049 search for the searchstring in the codeView" |
|
12050 |
|
12051 self setSearchPattern:aString. |
|
12052 autoSearch := aString |
|
12053 !! |
|
12054 |
|
12055 destroy |
|
12056 "relese dependant - destroy popups" |
|
12057 |
|
12058 Smalltalk removeDependent:self. |
|
12059 currentClass notNil ifTrue:[ |
|
12060 currentClass removeDependent:self. |
|
12061 currentClass := nil |
|
12062 ]. |
|
12063 super destroy |
|
12064 !! |
|
12065 |
|
12066 initialize |
|
12067 super initialize. |
|
12068 |
|
12069 showInstance := true. |
|
12070 fullClass := false. |
|
12071 fullProtocol := false. |
|
12072 aspect := nil. |
|
12073 |
|
12074 "inform me, when Smalltalk changes" |
|
12075 Smalltalk addDependent:self |
|
12076 !! |
|
12077 |
|
12078 realize |
|
12079 |v checkBlock| |
|
12080 |
|
12081 super realize. |
|
12082 |
|
12083 checkBlock := [:lineNr | self checkSelectionChangeAllowed]. |
|
12084 |
|
12085 v := classCategoryListView. |
|
12086 v notNil ifTrue:[ |
|
12087 v action:[:lineNr | self classCategorySelection:lineNr]. |
|
12088 v selectConditionBlock:checkBlock. |
|
12089 v ignoreReselect:false. |
|
12090 v contents:(self listOfAllClassCategories). |
|
12091 " |
|
12092 tell classCategoryListView to ask for the menu |
|
12093 " |
|
12094 v menuHolder:self; menuPerformer:self; menuMessage:#classCategoryMenu. |
|
12095 ]. |
|
12096 |
|
12097 v := classListView. |
|
12098 v notNil ifTrue:[ |
|
12099 v action:[:lineNr | self classSelection:lineNr]. |
|
12100 v selectConditionBlock:checkBlock. |
|
12101 v ignoreReselect:false. |
|
12102 " |
|
12103 tell classListView to ask for the menu |
|
12104 " |
|
12105 v menuHolder:self; menuPerformer:self; menuMessage:#classMenu. |
|
12106 ]. |
|
12107 |
|
12108 v := methodCategoryListView. |
|
12109 v notNil ifTrue:[ |
|
12110 v action:[:lineNr | self methodCategorySelection:lineNr]. |
|
12111 v selectConditionBlock:checkBlock. |
|
12112 v ignoreReselect:false. |
|
12113 " |
|
12114 tell methodCategoryListView to ask for the menu |
|
12115 " |
|
12116 v menuHolder:self; menuPerformer:self; menuMessage:#methodCategoryMenu. |
|
12117 ]. |
|
12118 |
|
12119 v := methodListView. |
|
12120 v notNil ifTrue:[ |
|
12121 v action:[:lineNr | self methodSelection:lineNr]. |
|
12122 v selectConditionBlock:checkBlock. |
|
12123 v ignoreReselect:false. |
|
12124 " |
|
12125 tell methodListView to ask for the menu |
|
12126 " |
|
12127 v menuHolder:self; menuPerformer:self; menuMessage:#methodMenu. |
|
12128 ]. |
|
12129 |
|
12130 v := classMethodListView. |
|
12131 v notNil ifTrue:[ |
|
12132 v action:[:lineNr | self classMethodSelection:lineNr]. |
|
12133 v selectConditionBlock:checkBlock. |
|
12134 v ignoreReselect:false. |
|
12135 " |
|
12136 tell classMethodListView to ask for the menu |
|
12137 " |
|
12138 v menuHolder:self; menuPerformer:self; menuMessage:#classMethodMenu. |
|
12139 ]. |
|
12140 |
|
12141 v := variableListView. |
|
12142 v notNil ifTrue:[ |
|
12143 v action:[:lineNr | self variableSelection:lineNr]. |
|
12144 v ignoreReselect:false. |
|
12145 v toggleSelect:true. |
|
12146 v menuHolder:self; menuPerformer:self; menuMessage:#variableListMenu. |
|
12147 ]. |
|
12148 |
|
12149 " |
|
12150 normal browsers show the top at first; |
|
12151 hierarchy and fullProtocol browsers better show the end |
|
12152 initially |
|
12153 " |
|
12154 currentClassHierarchy notNil ifTrue:[ |
|
12155 classListView scrollToBottom. |
|
12156 ] |
|
12157 !! |
|
12158 |
|
12159 terminate |
|
12160 (self checkSelectionChangeAllowed) ifTrue:[ |
|
12161 super terminate |
|
12162 ] |
|
12163 !! |
|
12164 |
|
12165 title:someString |
|
12166 myLabel := someString. |
|
12167 self label:someString. |
|
12168 !! !! |
|
12169 |
|
12170 !!BrowserView methodsFor:'initialize subviews'!! |
|
12171 |
|
12172 createClassListViewIn:frame |
|
12173 "setup the classlist subview, with its toggles" |
|
12174 |
|
12175 |v panel| |
|
12176 |
|
12177 self createTogglesIn:frame. |
|
12178 |
|
12179 " |
|
12180 oldstyle had no variableList ... |
|
12181 " |
|
12182 "/ v := ScrollableView for:SelectionInListView in:frame. |
|
12183 "/ v origin:(0.0 @ 0.0) |
|
12184 "/ extent:[frame width |
|
12185 "/ @ |
|
12186 "/ (frame height |
|
12187 "/ - ViewSpacing |
|
12188 "/ - instanceToggle height |
|
12189 "/ - instanceToggle borderWidth |
|
12190 "/ + v borderWidth)]. |
|
12191 "/ |
|
12192 "/ classListView := v scrolledView |
|
12193 |
|
12194 panel := VariableVerticalPanel |
|
12195 origin:(0.0 @ 0.0) |
|
12196 corner:[frame width |
|
12197 @ |
|
12198 (frame height |
|
12199 - ViewSpacing |
|
12200 - instanceToggle height |
|
12201 "-" "+ instanceToggle borderWidth " |
|
12202 + v borderWidth)] |
|
12203 in:frame. |
|
12204 |
|
12205 v := ScrollableView for:SelectionInListView in:panel. |
|
12206 v origin:(0.0 @ 0.0) corner:(1.0 @ 0.7). |
|
12207 classListView := v scrolledView. |
|
12208 |
|
12209 |
|
12210 v := ScrollableView for:SelectionInListView in:panel. |
|
12211 v origin:(0.0 @ 0.7) corner:(1.0 @ 1.0). |
|
12212 |
|
12213 variableListView := v scrolledView. |
|
12214 !! |
|
12215 |
|
12216 createCodeViewIn:aView |
|
12217 "setup the code view" |
|
12218 |
|
12219 ^ self createCodeViewIn:aView at:0.25 |
|
12220 !! |
|
12221 |
|
12222 createCodeViewIn:aView at:relY |
|
12223 "setup the code view" |
|
12224 |v| |
|
12225 |
|
12226 v := HVScrollableView for:CodeView miniScrollerH:true miniScrollerV:false in:aView. |
|
12227 v origin:(0.0 @ relY) corner:(1.0 @ 1.0). |
|
12228 codeView := v scrolledView |
|
12229 !! |
|
12230 |
|
12231 createTogglesIn:aFrame |
|
12232 "create and setup the class/instance toggles" |
|
12233 |
|
12234 |h halfSpace classAction instanceAction| |
|
12235 |
|
12236 classAction := [self instanceProtocol:false]. |
|
12237 instanceAction := [self instanceProtocol:true]. |
|
12238 |
|
12239 halfSpace := ViewSpacing // 2. |
|
12240 |
|
12241 instanceToggle := Toggle label:(resources at:'instance') in:aFrame. |
|
12242 h := instanceToggle heightIncludingBorder. |
|
12243 instanceToggle origin:(0.0 @ 1.0) corner:(0.5 @ 1.0). |
|
12244 instanceToggle topInset:h negated. |
|
12245 |
|
12246 instanceToggle turnOn. |
|
12247 instanceToggle pressAction:instanceAction. |
|
12248 instanceToggle releaseAction:classAction. |
|
12249 |
|
12250 classToggle := Toggle label:(resources at:'class') in:aFrame. |
|
12251 h := classToggle heightIncludingBorder. |
|
12252 classToggle origin:(0.5 @ 1.0) corner:(1.0 @ 1.0). |
|
12253 classToggle topInset:h negated. |
|
12254 |
|
12255 classToggle turnOff. |
|
12256 classToggle pressAction:classAction. |
|
12257 classToggle releaseAction:instanceAction. |
|
12258 |
|
12259 styleSheet is3D ifTrue:[ |
|
12260 instanceToggle bottomInset:halfSpace. |
|
12261 classToggle bottomInset:halfSpace. |
|
12262 |
|
12263 instanceToggle leftInset:halfSpace. |
|
12264 classToggle leftInset:halfSpace. |
|
12265 instanceToggle rightInset:ViewSpacing - halfSpace. |
|
12266 classToggle rightInset:ViewSpacing - halfSpace. |
|
12267 ]. |
|
12268 !! |
|
12269 |
|
12270 focusSequence |
|
12271 |s| |
|
12272 |
|
12273 s := OrderedCollection new. |
|
12274 |
|
12275 classCategoryListView notNil ifTrue:[ |
|
12276 s add:classCategoryListView |
|
12277 ]. |
|
12278 |
|
12279 classListView notNil ifTrue:[ |
|
12280 s add:classListView |
|
12281 ]. |
|
12282 |
|
12283 "/ variableListView notNil ifTrue:[ |
|
12284 "/ s add:variableListView |
|
12285 "/ ]. |
|
12286 |
|
12287 instanceToggle notNil ifTrue:[ |
|
12288 s add:instanceToggle. |
|
12289 ]. |
|
12290 |
|
12291 methodCategoryListView notNil ifTrue:[ |
|
12292 s add:methodCategoryListView |
|
12293 ]. |
|
12294 |
|
12295 methodListView notNil ifTrue:[ |
|
12296 s add:methodListView |
|
12297 ]. |
|
12298 |
|
12299 classMethodListView notNil ifTrue:[ |
|
12300 s add:classMethodListView |
|
12301 ]. |
|
12302 |
|
12303 s add:codeView. |
|
12304 ^ s |
|
12305 !! |
|
12306 |
|
12307 setupForAll |
|
12308 "create subviews for a full browser" |
|
12309 |
|
12310 |vpanel hpanel frame v| |
|
12311 |
|
12312 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) |
|
12313 in:self. |
|
12314 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
12315 |
|
12316 v := HVScrollableView for:SelectionInListView |
|
12317 miniScrollerH:true miniScrollerV:false |
|
12318 in:hpanel. |
|
12319 v origin:(0.0 @ 0.0) corner:(0.25 @ 1.0). |
|
12320 classCategoryListView := v scrolledView. |
|
12321 |
|
12322 frame := View origin:(0.25 @ 0.0) corner:(0.5 @ 1.0) in:hpanel. |
|
12323 self createClassListViewIn:frame. |
|
12324 |
|
12325 v := HVScrollableView for:SelectionInListView miniScrollerH:true miniScrollerV:false in:hpanel. |
|
12326 v origin:(0.5 @ 0.0) corner:(0.75 @ 1.0). |
|
12327 methodCategoryListView := v scrolledView. |
|
12328 |
|
12329 v := HVScrollableView for:SelectionInListView miniScrollerH:true miniScrollerV:false in:hpanel. |
|
12330 v origin:(0.75 @ 0.0) corner:(1.0 @ 1.0). |
|
12331 methodListView := v scrolledView. |
|
12332 |
|
12333 self createCodeViewIn:vpanel |
|
12334 !! |
|
12335 |
|
12336 setupForClass:aClass |
|
12337 "create subviews for browsing a single class" |
|
12338 |
|
12339 |vpanel hpanel frame v| |
|
12340 |
|
12341 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
12342 corner:(1.0 @ 1.0) |
|
12343 in:self. |
|
12344 |
|
12345 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
12346 frame := View origin:(0.0 @ 0.0) corner:(0.5 @ 1.0)in:hpanel. |
|
12347 |
|
12348 self createTogglesIn:frame. |
|
12349 |
|
12350 v := ScrollableView for:SelectionInListView in:frame. |
|
12351 v origin:(0.0 @ 0.0) |
|
12352 extent:[frame width |
|
12353 @ |
|
12354 (frame height |
|
12355 - ViewSpacing |
|
12356 - instanceToggle height |
|
12357 - instanceToggle borderWidth |
|
12358 + v borderWidth)]. |
|
12359 methodCategoryListView := v scrolledView. |
|
12360 |
|
12361 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12362 v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0). |
|
12363 methodListView := v scrolledView. |
|
12364 |
|
12365 self createCodeViewIn:vpanel. |
|
12366 |
|
12367 self switchToClass:aClass. |
|
12368 actualClass := acceptClass := aClass. |
|
12369 self updateMethodCategoryList. |
|
12370 self updateMethodList. |
|
12371 self updateCodeView. |
|
12372 self classDefinition. |
|
12373 !! |
|
12374 |
|
12375 setupForClass:aClass methodCategory:aMethodCategory |
|
12376 "setup subviews to browse a method category" |
|
12377 |
|
12378 |vpanel v| |
|
12379 |
|
12380 vpanel := VariableVerticalPanel |
|
12381 origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) |
|
12382 in:self. |
|
12383 |
|
12384 v := ScrollableView for:SelectionInListView in:vpanel. |
|
12385 v origin:(0.0 @ 0.0) corner:(1.0 @ 0.25). |
|
12386 methodListView := v scrolledView. |
|
12387 |
|
12388 self createCodeViewIn:vpanel. |
|
12389 |
|
12390 currentClassCategory := aClass category. |
|
12391 self switchToClass:aClass. |
|
12392 actualClass := acceptClass := aClass. |
|
12393 currentMethodCategory := aMethodCategory. |
|
12394 self updateMethodList. |
|
12395 self updateCodeView. |
|
12396 !! |
|
12397 |
|
12398 setupForClass:aClass selector:selector |
|
12399 "setup subviews to browse a single method" |
|
12400 |
|
12401 |v| |
|
12402 |
|
12403 v := ScrollableView for:CodeView in:self. |
|
12404 v origin:(0.0 @ 0.0) corner:(1.0 @ 1.0). |
|
12405 codeView := v scrolledView. |
|
12406 |
|
12407 currentClassCategory := aClass category. |
|
12408 self switchToClass:aClass. |
|
12409 actualClass := acceptClass := aClass. |
|
12410 currentSelector := selector. |
|
12411 currentMethod := currentClass compiledMethodAt:selector. |
|
12412 currentMethodCategory := currentMethod category. |
|
12413 self updateCodeView |
|
12414 !! |
|
12415 |
|
12416 setupForClassCategory:aClassCategory |
|
12417 "setup subviews to browse a class category" |
|
12418 |
|
12419 |vpanel hpanel frame v| |
|
12420 |
|
12421 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
12422 corner:(1.0 @ 1.0) |
|
12423 in:self. |
|
12424 |
|
12425 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
12426 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
12427 |
|
12428 self createClassListViewIn:frame. |
|
12429 |
|
12430 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12431 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
12432 methodCategoryListView := v scrolledView. |
|
12433 |
|
12434 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12435 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
12436 methodListView := v scrolledView. |
|
12437 |
|
12438 self createCodeViewIn:vpanel. |
|
12439 |
|
12440 currentClassCategory := aClassCategory. |
|
12441 self updateClassList. |
|
12442 self updateMethodCategoryList. |
|
12443 self updateMethodList. |
|
12444 self updateCodeView |
|
12445 !! |
|
12446 |
|
12447 setupForClassHierarchy:aClass |
|
12448 "setup subviews to browse a class hierarchy" |
|
12449 |
|
12450 |vpanel hpanel frame v cls| |
|
12451 |
|
12452 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
12453 corner:(1.0 @ 1.0) |
|
12454 in:self. |
|
12455 |
|
12456 " |
|
12457 notice: we use a different ratio here |
|
12458 " |
|
12459 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.4) in:vpanel. |
|
12460 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
12461 |
|
12462 self createClassListViewIn:frame. |
|
12463 |
|
12464 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12465 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
12466 methodCategoryListView := v scrolledView. |
|
12467 |
|
12468 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12469 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
12470 methodListView := v scrolledView. |
|
12471 |
|
12472 self createCodeViewIn:vpanel at:0.4. |
|
12473 |
|
12474 cls := aClass. |
|
12475 cls isMeta ifTrue:[ |
|
12476 cls := cls soleInstance |
|
12477 ]. |
|
12478 currentClassHierarchy := currentClass := actualClass := cls. |
|
12479 self updateClassList. |
|
12480 classListView selectElement:aClass name; makeSelectionVisible. |
|
12481 self updateMethodCategoryList. |
|
12482 self updateMethodList. |
|
12483 self updateCodeView. |
|
12484 |
|
12485 aClass isMeta ifTrue:[ |
|
12486 self instanceProtocol:false |
|
12487 ]. |
|
12488 !! |
|
12489 |
|
12490 setupForClassList:aList |
|
12491 "setup subviews to browse classes from a list" |
|
12492 |
|
12493 |vpanel hpanel frame l v| |
|
12494 |
|
12495 vpanel := VariableVerticalPanel |
|
12496 origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:self. |
|
12497 |
|
12498 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
12499 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
12500 |
|
12501 self createClassListViewIn:frame. |
|
12502 |
|
12503 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12504 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
12505 methodCategoryListView := v scrolledView. |
|
12506 |
|
12507 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12508 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
12509 methodListView := v scrolledView. |
|
12510 |
|
12511 self createCodeViewIn:vpanel. |
|
12512 |
|
12513 l := (aList collect:[:entry | entry name]) asOrderedCollection. |
|
12514 classListView list:(l sort). |
|
12515 |
|
12516 self updateMethodCategoryList. |
|
12517 self updateMethodList. |
|
12518 self updateCodeView |
|
12519 !! |
|
12520 |
|
12521 setupForFullClass |
|
12522 "setup subviews to browse a class as full text" |
|
12523 |
|
12524 |vpanel hpanel v| |
|
12525 |
|
12526 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
12527 corner:(1.0 @ 1.0) |
|
12528 in:self. |
|
12529 |
|
12530 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
12531 |
|
12532 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12533 v origin:(0.0 @ 0.0) corner:(0.5 @ 1.0). |
|
12534 classCategoryListView := v scrolledView. |
|
12535 classCategoryListView contents:(self listOfAllClassCategories). |
|
12536 |
|
12537 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12538 v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0). |
|
12539 classListView := v scrolledView. |
|
12540 |
|
12541 self createCodeViewIn:vpanel. |
|
12542 |
|
12543 fullClass := true. |
|
12544 self updateCodeView |
|
12545 !! |
|
12546 |
|
12547 setupForFullClassProtocol:aClass |
|
12548 "setup subviews to browse a classes full protocol" |
|
12549 |
|
12550 |vpanel hpanel frame v cls| |
|
12551 |
|
12552 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
12553 corner:(1.0 @ 1.0) |
|
12554 in:self. |
|
12555 |
|
12556 " |
|
12557 notice: we use a different ratio here |
|
12558 " |
|
12559 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.4) in:vpanel. |
|
12560 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
12561 |
|
12562 self createClassListViewIn:frame. |
|
12563 classListView multipleSelectOk:true. |
|
12564 classListView toggleSelect:true. |
|
12565 classListView strikeOut:true. |
|
12566 |
|
12567 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12568 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
12569 methodCategoryListView := v scrolledView. |
|
12570 |
|
12571 v := ScrollableView for:SelectionInListView in:hpanel. |
|
12572 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
12573 methodListView := v scrolledView. |
|
12574 |
|
12575 self createCodeViewIn:vpanel at:0.4. |
|
12576 |
|
12577 cls := aClass. |
|
12578 cls isMeta ifTrue:[ |
|
12579 cls := cls soleInstance |
|
12580 ]. |
|
12581 currentClassHierarchy := actualClass := acceptClass := currentClass := cls. |
|
12582 fullProtocol := true. |
|
12583 |
|
12584 self updateClassList. |
|
12585 self updateMethodCategoryList. |
|
12586 self updateMethodList. |
|
12587 self updateCodeView. |
|
12588 self updateVariableList. |
|
12589 aClass isMeta ifTrue:[ |
|
12590 self instanceProtocol:false |
|
12591 ]. |
|
12592 !! |
|
12593 |
|
12594 setupForList:aList |
|
12595 "setup subviews to browse methods from a list" |
|
12596 |
|
12597 |vpanel v| |
|
12598 |
|
12599 vpanel := VariableVerticalPanel |
|
12600 origin:(0.0 @ 0.0) |
|
12601 corner:(1.0 @ 1.0) |
|
12602 in:self. |
|
12603 |
|
12604 v := ScrollableView for:SelectionInListView in:vpanel. |
|
12605 v origin:(0.0 @ 0.0) corner:(1.0 @ 0.25). |
|
12606 classMethodListView := v scrolledView. |
|
12607 classMethodListView contents:aList. |
|
12608 |
|
12609 self createCodeViewIn:vpanel. |
|
12610 aList size == 1 ifTrue:[ |
|
12611 classMethodListView selection:1. |
|
12612 self classMethodSelection:1. |
|
12613 ]. |
|
12614 self updateCodeView |
|
12615 !! !! |
|
12616 |
|
12617 !!BrowserView methodsFor:'method category list menu'!! |
|
12618 |
|
12619 methodCategoryCopyCategory |
|
12620 "show the enter box to copy from an existing method category" |
|
12621 |
|
12622 |title box| |
|
12623 |
|
12624 showInstance ifTrue:[ |
|
12625 title := 'class to copy instance method category from:' |
|
12626 ] ifFalse:[ |
|
12627 title := 'class to copy class method category from:' |
|
12628 ]. |
|
12629 |
|
12630 box := self listBoxTitle:title |
|
12631 okText:'ok' |
|
12632 list:(Smalltalk allClasses collect:[:cls | cls name]) asArray sort. |
|
12633 |
|
12634 box action:[:aString | self copyMethodsFromClass:aString]. |
|
12635 box showAtPointer |
|
12636 !! |
|
12637 |
|
12638 methodCategoryCreateAccessMethods |
|
12639 "create access methods for all instvars" |
|
12640 |
|
12641 self checkClassSelected ifFalse:[^ self]. |
|
12642 |
|
12643 showInstance ifFalse:[ |
|
12644 self warn:'select instance - and try again'. |
|
12645 ^ self. |
|
12646 ]. |
|
12647 |
|
12648 self withWaitCursorDo:[ |
|
12649 |nm names source| |
|
12650 |
|
12651 (variableListView notNil |
|
12652 and:[(nm := variableListView selectionValue) notNil]) ifTrue:[ |
|
12653 names := Array with:nm |
|
12654 ] ifFalse:[ |
|
12655 names := currentClass instVarNames |
|
12656 ]. |
|
12657 names do:[:name | |
|
12658 "check, if method is not already present" |
|
12659 (currentClass implements:(name asSymbol)) ifFalse:[ |
|
12660 source := (name , '\ "return ' , name , '"\\ ^ ' , name) withCRs. |
|
12661 Compiler compile:source forClass:currentClass inCategory:'accessing'. |
|
12662 ] ifTrue:[ |
|
12663 Transcript showCr:'method ''', name , ''' already present' |
|
12664 ]. |
|
12665 (currentClass implements:((name , ':') asSymbol)) ifFalse:[ |
|
12666 source := (name , ':something\ "set ' , name , '"\\ ' , name , ' := something.') withCRs. |
|
12667 Compiler compile:source forClass:currentClass inCategory:'accessing'. |
|
12668 ] ifTrue:[ |
|
12669 Transcript showCr:'method ''', name , ':'' already present' |
|
12670 ]. |
|
12671 ]. |
|
12672 self updateMethodCategoryListWithScroll:false. |
|
12673 self updateMethodListWithScroll:false |
|
12674 ] |
|
12675 !! |
|
12676 |
|
12677 methodCategoryCreateDocumentationMethods |
|
12678 "create empty documentation methods" |
|
12679 |
|
12680 |cls histStream| |
|
12681 |
|
12682 self checkClassSelected ifFalse:[^ self]. |
|
12683 |
|
12684 cls := currentClass class. |
|
12685 |
|
12686 self withWaitCursorDo:[ |
|
12687 |nm names source| |
|
12688 |
|
12689 "/ add version method containing RCS template |
|
12690 "/ but only if not already present. |
|
12691 |
|
12692 (cls implements:#version) ifFalse:[ |
|
12693 Compiler compile: |
|
12694 'version |
|
12695 " |
|
12696 $' , 'Header$ |
|
12697 " |
|
12698 ' forClass:cls |
|
12699 inCategory:'documentation'. |
|
12700 ]. |
|
12701 |
|
12702 "/ add documentation method containing doc template |
|
12703 "/ but only if not already present. |
|
12704 |
|
12705 (cls implements:#documentation) ifFalse:[ |
|
12706 Compiler compile: |
|
12707 'documentation |
|
12708 " |
|
12709 documentation to be added. |
|
12710 " |
|
12711 ' forClass:cls |
|
12712 inCategory:'documentation'. |
|
12713 ]. |
|
12714 |
|
12715 "/ add examples method containing examples template |
|
12716 "/ but only if not already present. |
|
12717 |
|
12718 (cls implements:#examples) ifFalse:[ |
|
12719 Compiler compile: |
|
12720 'examples |
|
12721 " |
|
12722 examples to be added. |
|
12723 " |
|
12724 ' forClass:cls |
|
12725 inCategory:'documentation'. |
|
12726 ]. |
|
12727 |
|
12728 "/ add history method containing created-entry |
|
12729 "/ but only if not already present. |
|
12730 |
|
12731 (cls implements:#history) ifFalse:[ |
|
12732 histStream := ReadWriteStream on: String new. |
|
12733 histStream nextPutAll: 'history'; cr. |
|
12734 HistoryLine isBehavior ifTrue:[ |
|
12735 histStream nextPutAll: (HistoryLine newCreated printString); cr. |
|
12736 ] ifFalse:[ |
|
12737 histStream cr. |
|
12738 ]. |
|
12739 Compiler compile:(histStream contents) |
|
12740 forClass:cls |
|
12741 inCategory:'documentation'. |
|
12742 ]. |
|
12743 |
|
12744 self instanceProtocol:false. |
|
12745 self switchToMethodNamed:#documentation |
|
12746 "/ self updateMethodCategoryListWithScroll:false. |
|
12747 "/ self updateMethodListWithScroll:false |
|
12748 ] |
|
12749 !! |
|
12750 |
|
12751 methodCategoryFileOut |
|
12752 "fileOut all methods in the selected methodcategory of |
|
12753 the current class" |
|
12754 |
|
12755 self checkClassSelected ifFalse:[^ self]. |
|
12756 self whenMethodCategorySelected:[ |
|
12757 self busyLabel:'saving: %1' with:currentClass name , '-' , currentMethodCategory. |
|
12758 Class fileOutErrorSignal handle:[:ex | |
|
12759 self warn:'cannot create: %1' with:ex parameter. |
|
12760 ex return. |
|
12761 ] do:[ |
|
12762 actualClass fileOutCategory:currentMethodCategory. |
|
12763 ]. |
|
12764 self normalLabel. |
|
12765 ] |
|
12766 !! |
|
12767 |
|
12768 methodCategoryFileOutAll |
|
12769 "fileOut all methods in the selected methodcategory of |
|
12770 the current class" |
|
12771 |
|
12772 |
|
12773 self whenMethodCategorySelected:[ |
|
12774 |fileName outStream| |
|
12775 |
|
12776 fileName := currentMethodCategory , '.st'. |
|
12777 fileName replaceAll:Character space by:$_. |
|
12778 " |
|
12779 this test allows a smalltalk to be built without Projects/ChangeSets |
|
12780 " |
|
12781 Project notNil ifTrue:[ |
|
12782 fileName := Project currentProjectDirectory , fileName. |
|
12783 ]. |
|
12784 " |
|
12785 if file exists, save original in a .sav file |
|
12786 " |
|
12787 fileName asFilename exists ifTrue:[ |
|
12788 fileName asFilename copyTo:(fileName , '.sav') |
|
12789 ]. |
|
12790 outStream := FileStream newFileNamed:fileName. |
|
12791 outStream isNil ifTrue:[ |
|
12792 ^ self warn:'cannot create: %1' with:fileName |
|
12793 ]. |
|
12794 |
|
12795 self busyLabel:'saving: ' with:currentMethodCategory. |
|
12796 Class fileOutErrorSignal handle:[:ex | |
|
12797 self warn:'cannot create: %1' with:ex parameter. |
|
12798 ex return |
|
12799 ] do:[ |
|
12800 Smalltalk allBehaviorsDo:[:class | |
|
12801 |hasMethodsInThisCategory| |
|
12802 |
|
12803 hasMethodsInThisCategory := false. |
|
12804 class methodArray do:[:method | |
|
12805 method category = currentMethodCategory ifTrue:[ |
|
12806 hasMethodsInThisCategory := true |
|
12807 ] |
|
12808 ]. |
|
12809 hasMethodsInThisCategory ifTrue:[ |
|
12810 class fileOutCategory:currentMethodCategory on:outStream. |
|
12811 outStream cr |
|
12812 ]. |
|
12813 hasMethodsInThisCategory := false. |
|
12814 class class methodArray do:[:method | |
|
12815 method category = currentMethodCategory ifTrue:[ |
|
12816 hasMethodsInThisCategory := true |
|
12817 ] |
|
12818 ]. |
|
12819 hasMethodsInThisCategory ifTrue:[ |
|
12820 class class fileOutCategory:currentMethodCategory on:outStream. |
|
12821 outStream cr |
|
12822 ] |
|
12823 ]. |
|
12824 ]. |
|
12825 outStream close. |
|
12826 self normalLabel. |
|
12827 ]. |
|
12828 !! |
|
12829 |
|
12830 methodCategoryFindAnyMethod |
|
12831 |box| |
|
12832 |
|
12833 box := self enterBoxForSearchSelectorTitle:'method selector to search for:'. |
|
12834 box action:[:aString | self switchToAnyMethodNamed:aString]. |
|
12835 box showAtPointer |
|
12836 !! |
|
12837 |
|
12838 methodCategoryFindMethod |
|
12839 |box| |
|
12840 |
|
12841 box := self enterBoxForSearchSelectorTitle:'method selector to search for:'. |
|
12842 box action:[:aString | self switchToMethodNamed:aString]. |
|
12843 box showAtPointer |
|
12844 !! |
|
12845 |
|
12846 methodCategoryMenu |
|
12847 |labels selectors i| |
|
12848 |
|
12849 currentClass isNil ifTrue:[ |
|
12850 methodCategoryListView flash. |
|
12851 ^ nil |
|
12852 ]. |
|
12853 currentMethodCategory isNil ifTrue:[ |
|
12854 labels := #( |
|
12855 'find method here ...' |
|
12856 'find method ...' |
|
12857 '-' |
|
12858 'new category ...' |
|
12859 'copy category ...' |
|
12860 'create access methods' |
|
12861 ). |
|
12862 selectors := #( |
|
12863 methodCategoryFindMethod |
|
12864 methodCategoryFindAnyMethod |
|
12865 nil |
|
12866 methodCategoryNewCategory |
|
12867 methodCategoryCopyCategory |
|
12868 methodCategoryCreateAccessMethods |
|
12869 ). |
|
12870 ] ifFalse:[ |
|
12871 labels := #( |
|
12872 'fileOut' |
|
12873 'fileOut all' |
|
12874 'printOut' |
|
12875 '-' |
|
12876 'SPAWN_METHODCATEGORY' |
|
12877 'spawn category' |
|
12878 '-' |
|
12879 'find method here ...' |
|
12880 'find method ...' |
|
12881 '-' |
|
12882 'new category ...' |
|
12883 'copy category ...' |
|
12884 'create access methods' |
|
12885 'rename ...' |
|
12886 'remove' |
|
12887 ). |
|
12888 selectors := #( |
|
12889 methodCategoryFileOut |
|
12890 methodCategoryFileOutAll |
|
12891 methodCategoryPrintOut |
|
12892 nil |
|
12893 methodCategorySpawn |
|
12894 methodCategorySpawnCategory |
|
12895 nil |
|
12896 methodCategoryFindMethod |
|
12897 methodCategoryFindAnyMethod |
|
12898 nil |
|
12899 methodCategoryNewCategory |
|
12900 methodCategoryCopyCategory |
|
12901 methodCategoryCreateAccessMethods |
|
12902 methodCategoryRename |
|
12903 methodCategoryRemove |
|
12904 ). |
|
12905 ]. |
|
12906 |
|
12907 showInstance ifFalse:[ |
|
12908 labels := labels copy. |
|
12909 selectors := selectors copy. |
|
12910 i := labels indexOf:'create access methods'. |
|
12911 labels at:i put:'create documentation stubs'. |
|
12912 selectors at:i put:#methodCategoryCreateDocumentationMethods |
|
12913 ]. |
|
12914 |
|
12915 ^ PopUpMenu labels:(resources array:labels) |
|
12916 selectors:selectors |
|
12917 !! |
|
12918 |
|
12919 methodCategoryNewCategory |
|
12920 "show the enter box to add a new method category. |
|
12921 Offer existing superclass categories in box to help avoiding |
|
12922 useless typing." |
|
12923 |
|
12924 |someCategories existingCategories box| |
|
12925 |
|
12926 actualClass notNil ifTrue:[ |
|
12927 someCategories := actualClass allCategories |
|
12928 ] ifFalse:[ |
|
12929 " |
|
12930 mhmh - offer some typical categories ... |
|
12931 " |
|
12932 showInstance ifTrue:[ |
|
12933 someCategories := #('accessing' |
|
12934 'initialization' |
|
12935 'private' |
|
12936 'printing & storing' |
|
12937 'queries' |
|
12938 'testing' |
|
12939 ) |
|
12940 ] ifFalse:[ |
|
12941 someCategories := #( |
|
12942 'documentation' |
|
12943 'initialization' |
|
12944 'instance creation' |
|
12945 ). |
|
12946 ]. |
|
12947 ]. |
|
12948 someCategories sort. |
|
12949 |
|
12950 " |
|
12951 remove existing categories |
|
12952 " |
|
12953 existingCategories := methodCategoryListView list. |
|
12954 existingCategories notNil ifTrue:[ |
|
12955 someCategories := someCategories select:[:cat | (existingCategories includes:cat) not]. |
|
12956 ]. |
|
12957 |
|
12958 box := self listBoxTitle:'name of new method category:' |
|
12959 okText:'create' |
|
12960 list:someCategories. |
|
12961 box action:[:aString | self newMethodCategory:aString]. |
|
12962 box showAtPointer |
|
12963 |
|
12964 |
|
12965 |
|
12966 !! |
|
12967 |
|
12968 methodCategoryPrintOut |
|
12969 |printStream| |
|
12970 |
|
12971 self checkClassSelected ifFalse:[^ self]. |
|
12972 self whenMethodCategorySelected:[ |
|
12973 printStream := Printer new. |
|
12974 actualClass printOutCategory:currentMethodCategory on:printStream. |
|
12975 printStream close |
|
12976 ] |
|
12977 !! |
|
12978 |
|
12979 methodCategoryRemove |
|
12980 "show number of methods to remove and query user" |
|
12981 |
|
12982 |count t box| |
|
12983 |
|
12984 currentMethodCategory notNil ifTrue:[ |
|
12985 count := 0. |
|
12986 actualClass methodArray do:[:aMethod | |
|
12987 (aMethod category = currentMethodCategory) ifTrue:[ |
|
12988 count := count + 1 |
|
12989 ] |
|
12990 ]. |
|
12991 (count == 0) ifTrue:[ |
|
12992 currentMethodCategory := nil. |
|
12993 currentMethod := currentSelector := nil. |
|
12994 self updateMethodCategoryListWithScroll:false. |
|
12995 self updateMethodList |
|
12996 ] ifFalse:[ |
|
12997 (count == 1) ifTrue:[ |
|
12998 t := 'remove %1\(with 1 method) ?' |
|
12999 ] ifFalse:[ |
|
13000 t := 'remove %1\(with %2 methods) ?' |
|
13001 ]. |
|
13002 t := resources string:t with:currentMethodCategory with:count printString. |
|
13003 t := t withCRs. |
|
13004 |
|
13005 box := YesNoBox |
|
13006 title:t |
|
13007 yesText:(resources at:'remove') |
|
13008 noText:(resources at:'abort'). |
|
13009 box confirm ifTrue:[ |
|
13010 actualClass methodArray do:[:aMethod | |
|
13011 (aMethod category = currentMethodCategory) ifTrue:[ |
|
13012 actualClass |
|
13013 removeSelector:(actualClass selectorAtMethod:aMethod) |
|
13014 ] |
|
13015 ]. |
|
13016 currentMethodCategory := nil. |
|
13017 currentMethod := currentSelector := nil. |
|
13018 self updateMethodCategoryList. |
|
13019 self updateMethodList |
|
13020 ] |
|
13021 ] |
|
13022 ] |
|
13023 !! |
|
13024 |
|
13025 methodCategoryRename |
|
13026 "launch an enterBox to rename current method category" |
|
13027 |
|
13028 |box| |
|
13029 |
|
13030 self checkMethodCategorySelected ifFalse:[^ self]. |
|
13031 |
|
13032 box := self enterBoxTitle:(resources string:'rename method category %1 to:' with:currentMethodCategory) |
|
13033 okText:(resources at:'rename'). |
|
13034 box initialText:currentMethodCategory. |
|
13035 box action:[:aString | |
|
13036 actualClass renameCategory:currentMethodCategory to:aString. |
|
13037 currentMethodCategory := aString. |
|
13038 currentMethod := currentSelector := nil. |
|
13039 self updateMethodCategoryList. |
|
13040 self updateMethodListWithScroll:false |
|
13041 ]. |
|
13042 box showAtPointer |
|
13043 !! |
|
13044 |
|
13045 methodCategorySpawn |
|
13046 "create a new SystemBrowser browsing current method category" |
|
13047 |
|
13048 currentMethodCategory notNil ifTrue:[ |
|
13049 self withWaitCursorDo:[ |
|
13050 SystemBrowser browseClass:actualClass |
|
13051 methodCategory:currentMethodCategory |
|
13052 ] |
|
13053 ] |
|
13054 !! |
|
13055 |
|
13056 methodCategorySpawnCategory |
|
13057 "create a new SystemBrowser browsing all methods from all |
|
13058 classes with same category as current method category" |
|
13059 |
|
13060 self askAndBrowseMethodCategory:'category to browse methods:' |
|
13061 action:[:aString | |
|
13062 SystemBrowser browseMethodCategory:aString |
|
13063 ] |
|
13064 !! !! |
|
13065 |
|
13066 !!BrowserView methodsFor:'method category stuff'!! |
|
13067 |
|
13068 checkMethodCategorySelected |
|
13069 currentMethodCategory isNil ifTrue:[ |
|
13070 self warn:'select a method category first'. |
|
13071 ^ false |
|
13072 ]. |
|
13073 ^ true |
|
13074 !! |
|
13075 |
|
13076 copyMethodsFromClass:aClassName |
|
13077 |class box| |
|
13078 |
|
13079 currentClass notNil ifTrue:[ |
|
13080 class := Smalltalk classNamed:aClassName. |
|
13081 class isBehavior ifFalse:[ |
|
13082 self warn:'no class named %1' with:aClassName. |
|
13083 ^ self |
|
13084 ]. |
|
13085 |
|
13086 showInstance ifFalse:[ |
|
13087 class := class class |
|
13088 ]. |
|
13089 |
|
13090 "show enterbox for category to copy from" |
|
13091 |
|
13092 box := self enterBoxTitle:'name of category to copy from (matchpattern allowed, * for all):' |
|
13093 okText:'copy'. |
|
13094 box action:[:aString | self copyMethodsFromClass:class category:aString]. |
|
13095 box showAtPointer. |
|
13096 ] |
|
13097 !! |
|
13098 |
|
13099 copyMethodsFromClass:class category:category |
|
13100 currentClass notNil ifTrue:[ |
|
13101 Object abortSignal catch:[ |
|
13102 class methodArray do:[:aMethod | |
|
13103 |source| |
|
13104 |
|
13105 (category match:aMethod category) ifTrue:[ |
|
13106 source := aMethod source. |
|
13107 codeView contents:source. |
|
13108 codeView modified:false. |
|
13109 actualClass compilerClass |
|
13110 compile:source |
|
13111 forClass:actualClass |
|
13112 inCategory:aMethod category |
|
13113 notifying:codeView. |
|
13114 self updateMethodCategoryListWithScroll:false. |
|
13115 self updateMethodListWithScroll:false. |
|
13116 ] |
|
13117 ] |
|
13118 ] |
|
13119 ] |
|
13120 !! |
|
13121 |
|
13122 listOfAllMethodCategoriesInClass:aClass |
|
13123 "answer a list of all method categories of the argument, aClass" |
|
13124 |
|
13125 |newList| |
|
13126 |
|
13127 newList := Set new. |
|
13128 aClass methodArray do:[:aMethod | |
|
13129 |cat| |
|
13130 |
|
13131 cat := aMethod category. |
|
13132 cat isNil ifTrue:[ |
|
13133 cat := '* no category *' |
|
13134 ]. |
|
13135 newList add:cat |
|
13136 ]. |
|
13137 (newList size == 0) ifTrue:[^ nil]. |
|
13138 newList add:'* all *'. |
|
13139 ^ newList asOrderedCollection sort |
|
13140 !! |
|
13141 |
|
13142 listOfAllMethodCategoriesInFullProtocolHierarchy:aClass |
|
13143 "answer a list of all method categories of the argument, aClass, |
|
13144 and all of its superclasses. |
|
13145 Used with fullProtocol browsing." |
|
13146 |
|
13147 |newList| |
|
13148 |
|
13149 newList := Set new. |
|
13150 self classesInFullProtocolHierarchy:aClass do:[:c | |
|
13151 |cat| |
|
13152 |
|
13153 c methodArray do:[:aMethod | |
|
13154 cat := aMethod category. |
|
13155 cat isNil ifTrue:[ |
|
13156 cat := '* no category *' |
|
13157 ]. |
|
13158 newList add:cat |
|
13159 ] |
|
13160 ]. |
|
13161 (newList size == 0) ifTrue:[^ nil]. |
|
13162 newList add:'* all *'. |
|
13163 ^ newList asOrderedCollection sort |
|
13164 !! |
|
13165 |
|
13166 methodCategorySelection:lineNr |
|
13167 "user clicked on a method category line - show selectors" |
|
13168 |
|
13169 "/ |oldSelector| |
|
13170 |
|
13171 "/ oldSelector := currentSelector. |
|
13172 |
|
13173 (fullProtocol not and:[currentClass isNil]) ifTrue:[^ self]. |
|
13174 |
|
13175 currentMethodCategory := methodCategoryListView selectionValue. |
|
13176 self methodCategorySelectionChanged. |
|
13177 aspect := nil. |
|
13178 |
|
13179 "if there is only one method, show it right away" |
|
13180 methodListView list size == 1 ifTrue:[ |
|
13181 methodListView selection:1. |
|
13182 self methodSelection:1 |
|
13183 "/ ] ifFalse:[ |
|
13184 "/ oldSelector notNil ifTrue:[ |
|
13185 "/ methodListView selectElement:oldSelector. |
|
13186 "/ methodListView hasSelection ifTrue:[ |
|
13187 "/ self methodSelection:methodListView selection. |
|
13188 "/ ] |
|
13189 "/ ] |
|
13190 ] |
|
13191 |
|
13192 "Created: 23.11.1995 / 14:19:56 / cg" |
|
13193 !! |
|
13194 |
|
13195 methodCategorySelectionChanged |
|
13196 "method category selection has changed - update dependent views" |
|
13197 |
|
13198 self withWaitCursorDo:[ |
|
13199 currentMethod := currentSelector := nil. |
|
13200 |
|
13201 self updateMethodList. |
|
13202 self updateCodeView. |
|
13203 |
|
13204 currentMethodCategory notNil ifTrue:[ |
|
13205 methodCategoryListView selectElement:currentMethodCategory |
|
13206 ]. |
|
13207 |
|
13208 self setAcceptAndExplainActionsForMethod. |
|
13209 self hilightMethodsInMethodCategoryList:false inMethodList:true. |
|
13210 ] |
|
13211 |
|
13212 "Created: 23.11.1995 / 14:17:38 / cg" |
|
13213 "Modified: 23.11.1995 / 14:19:49 / cg" |
|
13214 !! |
|
13215 |
|
13216 newMethodCategory:aString |
|
13217 |categories| |
|
13218 |
|
13219 currentClass isNil ifTrue:[ |
|
13220 ^ self warn:'select/create a class first'. |
|
13221 ]. |
|
13222 categories := methodCategoryListView list. |
|
13223 categories isNil ifTrue:[categories := OrderedCollection new]. |
|
13224 (categories includes:aString) ifFalse:[ |
|
13225 categories add:aString. |
|
13226 categories sort. |
|
13227 methodCategoryListView contents:categories |
|
13228 ]. |
|
13229 currentMethodCategory := aString. |
|
13230 self methodCategorySelectionChanged |
|
13231 !! |
|
13232 |
|
13233 updateMethodCategoryList |
|
13234 self updateMethodCategoryListWithScroll:true |
|
13235 !! |
|
13236 |
|
13237 updateMethodCategoryListWithScroll:scroll |
|
13238 |categories| |
|
13239 |
|
13240 methodCategoryListView notNil ifTrue:[ |
|
13241 fullProtocol ifTrue:[ |
|
13242 currentClassHierarchy notNil ifTrue:[ |
|
13243 categories := self listOfAllMethodCategoriesInFullProtocolHierarchy:actualClass |
|
13244 ] |
|
13245 ] ifFalse:[ |
|
13246 currentClass notNil ifTrue:[ |
|
13247 categories := self listOfAllMethodCategoriesInClass:actualClass |
|
13248 ] |
|
13249 ]. |
|
13250 methodCategoryListView list = categories ifFalse:[ |
|
13251 scroll ifTrue:[ |
|
13252 methodCategoryListView contents:categories |
|
13253 ] ifFalse:[ |
|
13254 methodCategoryListView setContents:categories |
|
13255 ]. |
|
13256 currentMethodCategory notNil ifTrue:[ |
|
13257 methodCategoryListView selectElement:currentMethodCategory |
|
13258 ] |
|
13259 ] |
|
13260 ] |
|
13261 !! |
|
13262 |
|
13263 whenMethodCategorySelected:aBlock |
|
13264 self checkMethodCategorySelected ifTrue:[ |
|
13265 self withWaitCursorDo:aBlock |
|
13266 ] |
|
13267 !! !! |
|
13268 |
|
13269 !!BrowserView methodsFor:'method list menu'!! |
|
13270 |
|
13271 commonTraceHelperWith:aSelector |
|
13272 currentMethod := MessageTracer perform:aSelector with:currentMethod. |
|
13273 self updateMethodListWithScroll:false keepSelection:true. |
|
13274 currentClass changed:#methodDictionary with:currentSelector. |
|
13275 !! |
|
13276 |
|
13277 methodAproposSearch |
|
13278 "launch an enterBox for a keyword search" |
|
13279 |
|
13280 self askForSelectorTitle:'keyword to search for:' |
|
13281 openWith:#aproposSearch: |
|
13282 !! |
|
13283 |
|
13284 methodBreakPoint |
|
13285 "set a breakpoint on the current method" |
|
13286 |
|
13287 currentSelector notNil ifTrue:[ |
|
13288 currentMethod := actualClass compiledMethodAt:currentSelector. |
|
13289 currentMethod isWrapped ifFalse:[ |
|
13290 (currentMethod notNil and:[currentMethod isWrapped not]) ifTrue:[ |
|
13291 self commonTraceHelperWith:#trapMethod: |
|
13292 ] |
|
13293 ]. |
|
13294 ] |
|
13295 !! |
|
13296 |
|
13297 methodChangeCategory |
|
13298 "move the current method into another category - |
|
13299 nothing done here, but a query for the new category. |
|
13300 Remember the last category, to allow faster category change of a group of methods." |
|
13301 |
|
13302 |box txt| |
|
13303 |
|
13304 self checkMethodSelected ifFalse:[^ self]. |
|
13305 |
|
13306 actualClass isNil ifTrue:[ |
|
13307 box := self enterBoxTitle:'' okText:'change'. |
|
13308 ] ifFalse:[ |
|
13309 |someCategories| |
|
13310 |
|
13311 someCategories := actualClass categories sort. |
|
13312 box := self listBoxTitle:'' okText:'change' list:someCategories. |
|
13313 ]. |
|
13314 box title:('change category from ''' , currentMethod category , ''' to:'). |
|
13315 lastMethodCategory isNil ifTrue:[ |
|
13316 txt := currentMethod category. |
|
13317 ] ifFalse:[ |
|
13318 txt := lastMethodCategory |
|
13319 ]. |
|
13320 box initialText:txt. |
|
13321 box action:[:aString | |
|
13322 lastMethodCategory := aString. |
|
13323 |
|
13324 currentMethod category:aString asSymbol. |
|
13325 actualClass changed. |
|
13326 currentMethod changed:#category. |
|
13327 actualClass updateRevisionString. |
|
13328 actualClass addChangeRecordForMethodCategory:currentMethod category:aString. |
|
13329 self updateMethodCategoryListWithScroll:false. |
|
13330 self updateMethodListWithScroll:false |
|
13331 ]. |
|
13332 box showAtPointer |
|
13333 |
|
13334 "Created: 29.10.1995 / 19:59:22 / cg" |
|
13335 !! |
|
13336 |
|
13337 methodDecompile |
|
13338 "decompile the current methods bytecodes. |
|
13339 The Decompiler is delivered as an extra, and not normally |
|
13340 avaliable with the system." |
|
13341 |
|
13342 self checkMethodSelected ifFalse:[^ self]. |
|
13343 Decompiler notNil ifTrue:[ |
|
13344 Autoload autoloadFailedSignal handle:[:ex | |
|
13345 ex return |
|
13346 ] do:[ |
|
13347 Decompiler autoload. |
|
13348 ]. |
|
13349 ]. |
|
13350 Decompiler isLoaded ifFalse:[ |
|
13351 Smalltalk |
|
13352 fileIn:'/phys/clam/claus/work/libcomp/not_delivered/Decomp.st' |
|
13353 logged:false. |
|
13354 ]. |
|
13355 Decompiler isLoaded ifFalse:[ |
|
13356 ^ self warn:'No decompiler available'. |
|
13357 ]. |
|
13358 |
|
13359 Decompiler decompile:currentMethod. |
|
13360 !! |
|
13361 |
|
13362 methodFileOut |
|
13363 "file out the current method" |
|
13364 |
|
13365 self checkMethodSelected ifFalse:[^ self]. |
|
13366 |
|
13367 self busyLabel:'saving:' with:currentSelector. |
|
13368 Class fileOutErrorSignal handle:[:ex | |
|
13369 self warn:'cannot create: %1' with:ex parameter. |
|
13370 ex return |
|
13371 ] do:[ |
|
13372 actualClass fileOutMethod:currentMethod. |
|
13373 ]. |
|
13374 self normalLabel. |
|
13375 !! |
|
13376 |
|
13377 methodGlobalReferends |
|
13378 "launch an enterBox for global symbol to search for" |
|
13379 |
|
13380 self enterBoxForBrowseTitle:'global variable to browse users of:' |
|
13381 action:[:aString | |
|
13382 SystemBrowser browseReferendsOf:aString asSymbol |
|
13383 ] |
|
13384 !! |
|
13385 |
|
13386 methodImplementors |
|
13387 "launch an enterBox for selector to search for" |
|
13388 |
|
13389 self askForSelectorTitle:'selector to browse implementors of:' |
|
13390 openWith:#browseImplementorsOf: |
|
13391 !! |
|
13392 |
|
13393 methodInspect |
|
13394 "inspect the current method" |
|
13395 |
|
13396 self checkMethodSelected ifFalse:[^ self]. |
|
13397 (actualClass compiledMethodAt:currentSelector) inspect. |
|
13398 !! |
|
13399 |
|
13400 methodLocalAproposSearch |
|
13401 "launch an enterBox for a local keyword search" |
|
13402 |
|
13403 self askForSelectorTitle:'keyword to search for:' |
|
13404 openWith:#aproposSearch:in: |
|
13405 and:(currentClass withAllSubclasses) |
|
13406 !! |
|
13407 |
|
13408 methodLocalImplementors |
|
13409 "launch an enterBox for selector to search for" |
|
13410 |
|
13411 self checkClassSelected ifFalse:[^ self]. |
|
13412 self askForSelectorTitle:'selector to browse local implementors of:' |
|
13413 openWith:#browseImplementorsOf:under: |
|
13414 and:currentClass |
|
13415 !! |
|
13416 |
|
13417 methodLocalSenders |
|
13418 "launch an enterBox for selector to search for in current class & subclasses" |
|
13419 |
|
13420 self checkClassSelected ifFalse:[^ self]. |
|
13421 self askForSelectorTitle:'selector to browse local senders of:' |
|
13422 openWith:#browseCallsOn:under: |
|
13423 and:currentClass |
|
13424 !! |
|
13425 |
|
13426 methodLocalStringSearch |
|
13427 "launch an enterBox for string to search for" |
|
13428 |
|
13429 self checkClassSelected ifFalse:[^ self]. |
|
13430 self askForSelectorTitle:'string to search for in local methods:' |
|
13431 openWith:#browseForString:in: |
|
13432 and:(currentClass withAllSubclasses) |
|
13433 !! |
|
13434 |
|
13435 methodLocalSuperSends |
|
13436 "launch a browser showing super sends in current class & subclasses" |
|
13437 |
|
13438 self checkClassSelected ifFalse:[^ self]. |
|
13439 self withSearchCursorDo:[ |
|
13440 SystemBrowser browseSuperCallsUnder:currentClass |
|
13441 ] |
|
13442 |
|
13443 "Created: 23.11.1995 / 12:03:57 / cg" |
|
13444 "Modified: 23.11.1995 / 14:12:15 / cg" |
|
13445 !! |
|
13446 |
|
13447 methodMakePrivate |
|
13448 "make the current method private. |
|
13449 EXPERIMENTAL" |
|
13450 |
|
13451 self methodPrivacy:#private |
|
13452 !! |
|
13453 |
|
13454 methodMakeProtected |
|
13455 "make the current method protected. |
|
13456 EXPERIMENTAL" |
|
13457 |
|
13458 self methodPrivacy:#protected |
|
13459 !! |
|
13460 |
|
13461 methodMakePublic |
|
13462 "make the current method public. |
|
13463 EXPERIMENTAL" |
|
13464 |
|
13465 self methodPrivacy:#public |
|
13466 !! |
|
13467 |
|
13468 methodMenu |
|
13469 "return a popupmenu as appropriate for the methodList" |
|
13470 |
|
13471 |m labels selectors |
|
13472 newLabels newSelectors |
|
13473 mthdLabels mthdSelectors |
|
13474 brkLabels brkSelectors |
|
13475 fileLabels fileSelectors |
|
13476 searchLabels searchSelectors |
|
13477 sepLocalLabels sepLocalSelectors |
|
13478 localSearchLabels localSearchSelectors| |
|
13479 |
|
13480 device ctrlDown ifTrue:[ |
|
13481 "/ 'secret' developpers menu |
|
13482 |
|
13483 currentMethod isNil ifTrue:[ |
|
13484 methodListView flash. |
|
13485 ^ nil |
|
13486 ]. |
|
13487 labels := #( |
|
13488 'inspect method' |
|
13489 'compile to machine code' |
|
13490 'decompile' |
|
13491 '-' |
|
13492 'make private' |
|
13493 'make protected' |
|
13494 'make public' |
|
13495 ). |
|
13496 selectors := #( |
|
13497 methodInspect |
|
13498 methodSTCCompile |
|
13499 methodDecompile |
|
13500 nil |
|
13501 methodMakePrivate |
|
13502 methodMakeProtected |
|
13503 methodMakePublic |
|
13504 ) |
|
13505 ] ifFalse:[ |
|
13506 |
|
13507 sepLocalLabels := sepLocalSelectors := #(). |
|
13508 |
|
13509 searchLabels := #( |
|
13510 'senders ...' |
|
13511 'implementors ...' |
|
13512 'globals ...' |
|
13513 'string search ...' |
|
13514 'apropos ...' |
|
13515 ). |
|
13516 searchSelectors := #( |
|
13517 methodSenders |
|
13518 methodImplementors |
|
13519 methodGlobalReferends |
|
13520 methodStringSearch |
|
13521 methodAproposSearch |
|
13522 ). |
|
13523 |
|
13524 currentClass notNil ifTrue:[ |
|
13525 localSearchLabels := #( |
|
13526 '-' |
|
13527 'local senders ...' |
|
13528 'local implementors ...' |
|
13529 'local super sends ...' |
|
13530 'local string search ...' |
|
13531 'local apropos ...' |
|
13532 ). |
|
13533 localSearchSelectors := #( |
|
13534 nil |
|
13535 methodLocalSenders |
|
13536 methodLocalImplementors |
|
13537 methodLocalSuperSends |
|
13538 methodLocalStringSearch |
|
13539 methodLocalAproposSearch |
|
13540 ). |
|
13541 ] ifFalse:[ |
|
13542 localSearchLabels := localSearchSelectors := #() |
|
13543 ]. |
|
13544 |
|
13545 currentMethodCategory notNil ifTrue:[ |
|
13546 sepLocalLabels := #('-'). sepLocalSelectors := #(nil). |
|
13547 |
|
13548 newLabels := #( |
|
13549 'new method' |
|
13550 ). |
|
13551 |
|
13552 newSelectors := #( |
|
13553 methodNewMethod |
|
13554 ). |
|
13555 ] ifFalse:[ |
|
13556 newLabels := newSelectors := #() |
|
13557 ]. |
|
13558 |
|
13559 currentMethod notNil ifTrue:[ |
|
13560 fileLabels := #( |
|
13561 'fileOut' |
|
13562 'printOut' |
|
13563 '-' |
|
13564 'SPAWN_METHOD' |
|
13565 '-' |
|
13566 ). |
|
13567 |
|
13568 fileSelectors := #( |
|
13569 methodFileOut |
|
13570 methodPrintOut |
|
13571 nil |
|
13572 methodSpawn |
|
13573 nil |
|
13574 ). |
|
13575 |
|
13576 sepLocalLabels := #('-'). sepLocalSelectors := #(nil). |
|
13577 |
|
13578 mthdLabels := #( |
|
13579 'change category ...' |
|
13580 'remove' |
|
13581 ). |
|
13582 |
|
13583 mthdSelectors := #( |
|
13584 methodChangeCategory |
|
13585 methodRemove |
|
13586 ). |
|
13587 |
|
13588 currentMethod isWrapped ifTrue:[ |
|
13589 brkLabels := #( |
|
13590 'remove break/trace' |
|
13591 '-' |
|
13592 ). |
|
13593 |
|
13594 brkSelectors := #( |
|
13595 methodRemoveBreakOrTrace |
|
13596 nil |
|
13597 ) |
|
13598 ] ifFalse:[ |
|
13599 brkLabels := #( |
|
13600 'breakpoint' |
|
13601 'trace' |
|
13602 'trace sender' |
|
13603 '-' |
|
13604 ). |
|
13605 |
|
13606 brkSelectors := #( |
|
13607 methodBreakPoint |
|
13608 methodTrace |
|
13609 methodTraceSender |
|
13610 nil |
|
13611 ) |
|
13612 ] |
|
13613 ] ifFalse:[ |
|
13614 fileLabels := fileSelectors := #(). |
|
13615 brkLabels := brkSelectors := #(). |
|
13616 mthdLabels := mthdSelectors := #(). |
|
13617 ]. |
|
13618 |
|
13619 |
|
13620 |
|
13621 labels := |
|
13622 fileLabels , |
|
13623 searchLabels , |
|
13624 localSearchLabels , |
|
13625 sepLocalLabels , |
|
13626 brkLabels , |
|
13627 newLabels , |
|
13628 mthdLabels. |
|
13629 |
|
13630 selectors := |
|
13631 fileSelectors , |
|
13632 searchSelectors , |
|
13633 localSearchSelectors , |
|
13634 sepLocalSelectors , |
|
13635 brkSelectors , |
|
13636 newSelectors , |
|
13637 mthdSelectors. |
|
13638 |
|
13639 " |
|
13640 labels := #( |
|
13641 'fileOut' |
|
13642 'printOut' |
|
13643 '-' |
|
13644 'SPAWN_METHOD' |
|
13645 '-' |
|
13646 'senders ...' |
|
13647 'implementors ...' |
|
13648 'globals ...' |
|
13649 'string search ...' |
|
13650 'apropos ...' |
|
13651 '-' |
|
13652 'local senders ...' |
|
13653 'local implementors ...' |
|
13654 'local string search ...' |
|
13655 'local apropos ...' |
|
13656 '-' |
|
13657 'breakpoint' |
|
13658 'trace' |
|
13659 'trace sender' |
|
13660 '-' |
|
13661 'new method' |
|
13662 'change category ...' |
|
13663 'remove' |
|
13664 ). |
|
13665 selectors := #( |
|
13666 methodFileOut |
|
13667 methodPrintOut |
|
13668 nil |
|
13669 methodSpawn |
|
13670 nil |
|
13671 methodSenders |
|
13672 methodImplementors |
|
13673 methodGlobalReferends |
|
13674 methodStringSearch |
|
13675 methodAproposSearch |
|
13676 nil |
|
13677 methodLocalSenders |
|
13678 methodLocalImplementors |
|
13679 methodLocalStringSearch |
|
13680 methodLocalAproposSearch |
|
13681 nil |
|
13682 methodBreakPoint |
|
13683 methodTrace |
|
13684 methodTraceSender |
|
13685 nil |
|
13686 methodNewMethod |
|
13687 methodChangeCategory |
|
13688 methodRemove |
|
13689 ) |
|
13690 " |
|
13691 ]. |
|
13692 m := PopUpMenu |
|
13693 labels:(resources array:labels) |
|
13694 selectors:selectors. |
|
13695 |
|
13696 currentMethod notNil ifTrue:[ |
|
13697 currentMethod isPrivate ifTrue:[ |
|
13698 m disable:#methodMakePrivate |
|
13699 ]. |
|
13700 currentMethod isProtected ifTrue:[ |
|
13701 m disable:#methodMakeProtected |
|
13702 ]. |
|
13703 currentMethod isPublic ifTrue:[ |
|
13704 m disable:#methodMakePublic |
|
13705 ]. |
|
13706 ]. |
|
13707 currentMethod notNil ifTrue:[ |
|
13708 (currentMethod code notNil |
|
13709 or:[Compiler canCreateMachineCode not]) ifTrue:[ |
|
13710 m disable:#methodSTCCompile |
|
13711 ]. |
|
13712 currentMethod byteCode isNil ifTrue:[ |
|
13713 m disable:#methodDecompile |
|
13714 ]. |
|
13715 ]. |
|
13716 ^ m |
|
13717 |
|
13718 "Created: 23.11.1995 / 12:02:29 / cg" |
|
13719 !! |
|
13720 |
|
13721 methodNewMethod |
|
13722 "prepare for definition of a new method - put a template into |
|
13723 code view and define accept-action to compile it" |
|
13724 |
|
13725 currentClass isNil ifTrue:[ |
|
13726 ^ self warn:'select/create a class first'. |
|
13727 ]. |
|
13728 currentMethodCategory isNil ifTrue:[ |
|
13729 ^ self warn:'select/create a method category first'. |
|
13730 ]. |
|
13731 |
|
13732 currentMethod := currentSelector := nil. |
|
13733 |
|
13734 methodListView deselect. |
|
13735 codeView contents:(self template). |
|
13736 codeView modified:false. |
|
13737 |
|
13738 self setAcceptAndExplainActionsForMethod. |
|
13739 !! |
|
13740 |
|
13741 methodPrintOut |
|
13742 "print out the current method" |
|
13743 |
|
13744 |printStream| |
|
13745 |
|
13746 self checkMethodSelected ifFalse:[^ self]. |
|
13747 |
|
13748 printStream := Printer new. |
|
13749 actualClass printOutSource:(currentMethod source) on:printStream. |
|
13750 printStream close |
|
13751 !! |
|
13752 |
|
13753 methodPrivacy:how |
|
13754 "change the current methods privacy. |
|
13755 EXPERIMENTAL" |
|
13756 |
|
13757 self checkMethodSelected ifFalse:[^ self]. |
|
13758 currentMethod isPublic ifFalse:[ |
|
13759 currentMethod privacy:how. |
|
13760 actualClass updateRevisionString. |
|
13761 actualClass addChangeRecordForMethodPrivacy:currentMethod. |
|
13762 self updateMethodListWithScroll:false keepSelection:true. |
|
13763 ] |
|
13764 |
|
13765 "Created: 29.10.1995 / 20:00:00 / cg" |
|
13766 !! |
|
13767 |
|
13768 methodRemove |
|
13769 "remove the current method" |
|
13770 |
|
13771 self checkMethodSelected ifFalse:[^ self]. |
|
13772 actualClass removeSelector:(actualClass selectorAtMethod:currentMethod). |
|
13773 currentMethod := currentSelector := nil. |
|
13774 self updateMethodListWithScroll:false |
|
13775 !! |
|
13776 |
|
13777 methodRemoveBreakOrTrace |
|
13778 "turn off tracing of the current method" |
|
13779 |
|
13780 (currentMethod notNil and:[currentMethod isWrapped]) ifTrue:[ |
|
13781 self commonTraceHelperWith:#unwrapMethod: |
|
13782 ] |
|
13783 !! |
|
13784 |
|
13785 methodSTCCompile |
|
13786 "compile the current method to machine code. |
|
13787 This is not supported on all machines, and never supported in |
|
13788 the demo version." |
|
13789 |
|
13790 |prev| |
|
13791 |
|
13792 self checkMethodSelected ifFalse:[^ self]. |
|
13793 prev := Compiler stcCompilation:#always. |
|
13794 [ |
|
13795 codeView accept. |
|
13796 ] valueNowOrOnUnwindDo:[ |
|
13797 Compiler stcCompilation:prev |
|
13798 ]. |
|
13799 !! |
|
13800 |
|
13801 methodSenders |
|
13802 "launch an enterBox for selector to search for" |
|
13803 |
|
13804 self askForSelectorTitle:'selector to browse senders of:' |
|
13805 openWith:#browseAllCallsOn: |
|
13806 !! |
|
13807 |
|
13808 methodSpawn |
|
13809 "create a new SystemBrowser browsing current method, |
|
13810 or if the current selection is of the form 'class>>selector', spawan |
|
13811 a browser on that method." |
|
13812 |
|
13813 |s sel selSymbol clsName clsSymbol cls isMeta w| |
|
13814 |
|
13815 classMethodListView notNil ifTrue:[ |
|
13816 s := classMethodListView selectionValue. |
|
13817 clsName := self classFromClassMethodString:s. |
|
13818 sel := self selectorFromClassMethodString:s. |
|
13819 isMeta := false |
|
13820 ]. |
|
13821 |
|
13822 self extractClassAndSelectorFromSelectionInto:[:c :s :m | |
|
13823 clsName := c. |
|
13824 sel := s. |
|
13825 isMeta := m |
|
13826 ]. |
|
13827 |
|
13828 (sel notNil and:[clsName notNil]) ifTrue:[ |
|
13829 (clsName knownAsSymbol and:[sel knownAsSymbol]) ifTrue:[ |
|
13830 clsSymbol := clsName asSymbol. |
|
13831 (Smalltalk includesKey:clsSymbol) ifTrue:[ |
|
13832 cls := Smalltalk at:clsSymbol. |
|
13833 isMeta ifTrue:[ |
|
13834 cls := cls class |
|
13835 ]. |
|
13836 cls isBehavior ifFalse:[ |
|
13837 cls := cls class |
|
13838 ]. |
|
13839 cls isBehavior ifTrue:[ |
|
13840 selSymbol := sel asSymbol. |
|
13841 self withWaitCursorDo:[ |
|
13842 (cls implements:selSymbol) ifFalse:[ |
|
13843 cls := cls class. |
|
13844 ]. |
|
13845 (cls implements:selSymbol) ifTrue:[ |
|
13846 SystemBrowser browseClass:cls selector:selSymbol. |
|
13847 ^ self |
|
13848 ]. |
|
13849 w := ' does not implement #' , sel |
|
13850 ] |
|
13851 ] ifFalse:[ |
|
13852 w := ' is not a class' |
|
13853 ] |
|
13854 ] ifFalse:[ |
|
13855 w := ' is unknown' |
|
13856 ] |
|
13857 ] ifFalse:[ |
|
13858 w := ' and/or ' , sel , ' are unknown' |
|
13859 ]. |
|
13860 self warn:(clsName , w). |
|
13861 ^ self |
|
13862 ]. |
|
13863 |
|
13864 self checkMethodSelected ifFalse:[ |
|
13865 self warn:'select a method first'. |
|
13866 ^ self |
|
13867 ]. |
|
13868 |
|
13869 self withWaitCursorDo:[ |
|
13870 w := currentMethod who. |
|
13871 SystemBrowser browseClass:(w at:1) selector:(w at:2) |
|
13872 ] |
|
13873 !! |
|
13874 |
|
13875 methodStringSearch |
|
13876 "launch an enterBox for string to search for" |
|
13877 |
|
13878 self askForSelectorTitle:'string to search for in sources:' |
|
13879 openWith:#browseForString: |
|
13880 !! |
|
13881 |
|
13882 methodTrace |
|
13883 "turn on tracing of the current method" |
|
13884 |
|
13885 currentClass notNil ifTrue:[ |
|
13886 currentSelector notNil ifTrue:[ |
|
13887 currentMethod := actualClass compiledMethodAt:currentSelector |
|
13888 ] |
|
13889 ]. |
|
13890 |
|
13891 (currentMethod notNil and:[currentMethod isWrapped not]) ifTrue:[ |
|
13892 self commonTraceHelperWith:#traceMethod: |
|
13893 ] |
|
13894 !! |
|
13895 |
|
13896 methodTraceSender |
|
13897 "turn on tracing of the current method" |
|
13898 |
|
13899 (currentMethod notNil and:[currentMethod isWrapped not]) ifTrue:[ |
|
13900 self commonTraceHelperWith:#traceMethodSender: |
|
13901 ] |
|
13902 !! !! |
|
13903 |
|
13904 !!BrowserView methodsFor:'method stuff'!! |
|
13905 |
|
13906 checkMethodSelected |
|
13907 currentMethod isNil ifTrue:[ |
|
13908 self warn:'select a method first'. |
|
13909 ^ false |
|
13910 ]. |
|
13911 ^ true |
|
13912 !! |
|
13913 |
|
13914 listOfAllSelectorsInCategory:aCategory inFullProtocolHierarchyOfClass:aClass |
|
13915 "answer a list of all selectors in a given method category |
|
13916 of the argument, aClass and its superclasses. |
|
13917 Used with fullProtocol browsing." |
|
13918 |
|
13919 |newList| |
|
13920 |
|
13921 newList := Set new. |
|
13922 self classesInFullProtocolHierarchy:aClass do:[:c | |
|
13923 |searchCategory| |
|
13924 |
|
13925 (aCategory = '* all *') ifTrue:[ |
|
13926 newList addAll:(c selectorArray) |
|
13927 ] ifFalse:[ |
|
13928 (aCategory = '* no category *') ifTrue:[ |
|
13929 searchCategory := nil |
|
13930 ] ifFalse:[ |
|
13931 searchCategory := aCategory |
|
13932 ]. |
|
13933 c methodArray with:c selectorArray do:[:aMethod :selector | |
|
13934 (aMethod category = searchCategory) ifTrue:[ |
|
13935 newList add:selector |
|
13936 ] |
|
13937 ] |
|
13938 ]. |
|
13939 ]. |
|
13940 (newList size == 0) ifTrue:[^ nil]. |
|
13941 ^ newList asOrderedCollection sort |
|
13942 !! |
|
13943 |
|
13944 listOfAllSelectorsInCategory:aCategory ofClass:aClass |
|
13945 "answer a list of all selectors in a given method category |
|
13946 of the argument, aClass" |
|
13947 |
|
13948 |newList searchCategory all p| |
|
13949 |
|
13950 all := (aCategory = '* all *'). |
|
13951 (aCategory = '* no category *') ifTrue:[ |
|
13952 searchCategory := nil |
|
13953 ] ifFalse:[ |
|
13954 searchCategory := aCategory |
|
13955 ]. |
|
13956 newList := OrderedCollection new. |
|
13957 aClass methodArray with:aClass selectorArray do:[:aMethod :selector | |
|
13958 |sel how| |
|
13959 |
|
13960 (all or:[aMethod category = searchCategory]) ifTrue:[ |
|
13961 sel := selector. |
|
13962 (p := aMethod privacy) ~~ #public ifTrue:[ |
|
13963 how := ' (* ' , p , ' *)'. |
|
13964 ]. |
|
13965 aMethod isWrapped ifTrue:[ |
|
13966 how := ' !!!!' |
|
13967 ]. |
|
13968 aMethod isInvalid ifTrue:[ |
|
13969 how := ' (** not executable **)' |
|
13970 ]. |
|
13971 aMethod isLazyMethod ifTrue:[ |
|
13972 "/ how := ' (lazy)' |
|
13973 ] ifFalse:[ |
|
13974 (aMethod code isNil |
|
13975 and:[aMethod byteCode isNil]) ifTrue:[ |
|
13976 how := ' (** unloaded **)' |
|
13977 ] |
|
13978 ]. |
|
13979 how notNil ifTrue:[sel := sel , how]. |
|
13980 newList add:sel |
|
13981 ] |
|
13982 ]. |
|
13983 (newList size == 0) ifTrue:[^ nil]. |
|
13984 ^ newList sort |
|
13985 |
|
13986 "Modified: 28.8.1995 / 21:53:34 / claus" |
|
13987 !! |
|
13988 |
|
13989 methodSelection:lineNr |
|
13990 "user clicked on a method line - show code" |
|
13991 |
|
13992 |selectorString selectorSymbol| |
|
13993 |
|
13994 (fullProtocol not and:[currentClass isNil]) ifTrue:[^ self]. |
|
13995 |
|
13996 selectorString := methodListView selectionValue. |
|
13997 " |
|
13998 kludge: extract real selector |
|
13999 " |
|
14000 selectorString := selectorString withoutSpaces upTo:(Character space). |
|
14001 selectorSymbol := selectorString asSymbol. |
|
14002 fullProtocol ifTrue:[ |
|
14003 currentMethod := currentSelector := nil. |
|
14004 " |
|
14005 search which class implements the selector |
|
14006 " |
|
14007 self classesInFullProtocolHierarchy:actualClass do:[:c | |
|
14008 (currentMethod isNil |
|
14009 and:[c implements:selectorSymbol]) ifTrue:[ |
|
14010 currentSelector := selectorSymbol. |
|
14011 currentMethod := c compiledMethodAt:selectorSymbol. |
|
14012 acceptClass := c |
|
14013 ] |
|
14014 ] |
|
14015 ] ifFalse:[ |
|
14016 currentSelector := selectorSymbol. |
|
14017 currentMethod := actualClass compiledMethodAt:selectorSymbol. |
|
14018 ]. |
|
14019 |
|
14020 methodCategoryListView notNil ifTrue:[ |
|
14021 currentMethod notNil ifTrue:[ |
|
14022 (currentMethodCategory = currentMethod category) ifFalse:[ |
|
14023 currentMethodCategory := currentMethod category. |
|
14024 methodCategoryListView selectElement:currentMethodCategory |
|
14025 ] |
|
14026 ] |
|
14027 ]. |
|
14028 |
|
14029 self methodSelectionChanged |
|
14030 !! |
|
14031 |
|
14032 methodSelectionChanged |
|
14033 "method selection has changed - update dependent views" |
|
14034 |
|
14035 self withWaitCursorDo:[ |
|
14036 |index cls| |
|
14037 |
|
14038 self updateCodeView. |
|
14039 aspect := nil. |
|
14040 self setAcceptAndExplainActionsForMethod. |
|
14041 |
|
14042 " |
|
14043 if there is any autoSearch string, do the search |
|
14044 " |
|
14045 autoSearch notNil ifTrue:[ |
|
14046 codeView searchFwd:autoSearch startingAtLine:1 col:0 ifAbsent:[] |
|
14047 ]. |
|
14048 |
|
14049 fullProtocol ifTrue:[ |
|
14050 " |
|
14051 remove any bold attribute from classList |
|
14052 " |
|
14053 1 to:classListView list size do:[:i | |
|
14054 classListView attributeAt:i remove:#bold. |
|
14055 ]. |
|
14056 " |
|
14057 boldify the class where this method is implemented |
|
14058 " |
|
14059 currentMethod notNil ifTrue:[ |
|
14060 cls := currentMethod who at:1. |
|
14061 index := classListView list indexOf:(cls name). |
|
14062 (index == 0 |
|
14063 and:[cls isMeta |
|
14064 and:[cls name endsWith:'class']]) ifTrue:[ |
|
14065 index := classListView list indexOf:(cls name copyWithoutLast:5). |
|
14066 ]. |
|
14067 index ~~ 0 ifTrue:[ |
|
14068 classListView attributeAt:index add:#bold. |
|
14069 ]. |
|
14070 currentClass := acceptClass := cls. |
|
14071 ] |
|
14072 ]. |
|
14073 ] |
|
14074 |
|
14075 "Created: 23.11.1995 / 14:17:44 / cg" |
|
14076 !! |
|
14077 |
|
14078 switchToAnyMethodNamed:aString |
|
14079 |aSelector classToStartSearch aClass nm| |
|
14080 |
|
14081 aSelector := aString asSymbol. |
|
14082 currentClass isNil ifTrue:[ |
|
14083 currentClassHierarchy notNil ifTrue:[ |
|
14084 classToStartSearch := currentClassHierarchy |
|
14085 ] |
|
14086 ] ifFalse:[ |
|
14087 classToStartSearch := currentClass |
|
14088 ]. |
|
14089 classToStartSearch notNil ifTrue:[ |
|
14090 showInstance ifFalse:[ |
|
14091 classToStartSearch := classToStartSearch class |
|
14092 ]. |
|
14093 aClass := classToStartSearch whichClassIncludesSelector:aSelector. |
|
14094 aClass notNil ifTrue:[ |
|
14095 nm := aClass name. |
|
14096 showInstance ifFalse:[ |
|
14097 ((nm ~= 'Metaclass') and:[nm endsWith:'class']) ifTrue:[ |
|
14098 nm := nm copyWithoutLast:5 "copyTo:(nm size - 5)" |
|
14099 ] |
|
14100 ]. |
|
14101 self switchToClassNamed:nm. |
|
14102 self switchToMethodNamed:aString |
|
14103 ] |
|
14104 ] |
|
14105 !! |
|
14106 |
|
14107 switchToMethodNamed:matchString |
|
14108 "switch (in the current class) to a method named matchString. |
|
14109 If there are more than one matches, switch to the first." |
|
14110 |
|
14111 |aSelector method cat index classToSearch selectors| |
|
14112 |
|
14113 currentClass notNil ifTrue:[ |
|
14114 showInstance ifTrue:[ |
|
14115 classToSearch := currentClass |
|
14116 ] ifFalse:[ |
|
14117 classToSearch := currentClass class |
|
14118 ]. |
|
14119 selectors := classToSearch selectorArray. |
|
14120 |
|
14121 ((matchString ~= '*') and:[matchString includesMatchCharacters]) ifTrue:[ |
|
14122 index := selectors findFirst:[:element | matchString match:element] |
|
14123 ] ifFalse:[ |
|
14124 index := selectors indexOf:matchString |
|
14125 ]. |
|
14126 |
|
14127 (index ~~ 0) ifTrue:[ |
|
14128 aSelector := selectors at:index. |
|
14129 method := classToSearch methodArray at:index. |
|
14130 cat := method category. |
|
14131 cat isNil ifTrue:[cat := '* all *']. |
|
14132 methodCategoryListView selectElement:cat. |
|
14133 currentMethodCategory := cat. |
|
14134 self updateMethodCategoryListWithScroll:false. |
|
14135 self methodCategorySelectionChanged. |
|
14136 |
|
14137 currentMethod := classToSearch compiledMethodAt:aSelector. |
|
14138 currentMethod notNil ifTrue:[ |
|
14139 currentSelector := aSelector. |
|
14140 methodListView selectElement:aSelector. |
|
14141 ]. |
|
14142 self methodSelectionChanged |
|
14143 ] |
|
14144 ] |
|
14145 !! |
|
14146 |
|
14147 template |
|
14148 "return a method definition template" |
|
14149 |
|
14150 ^ |
|
14151 'message selector and argument names |
|
14152 "comment stating purpose of message" |
|
14153 |
|
14154 |
|
14155 |temporaries| |
|
14156 statements |
|
14157 |
|
14158 |
|
14159 " |
|
14160 change above template into real code. |
|
14161 Then ''accept'' either via the menu |
|
14162 or via the keyboard (usually CMD-A). |
|
14163 |
|
14164 You do not need this template; you can also |
|
14165 select any existing methods code, change it, |
|
14166 and finally ''accept''. |
|
14167 " |
|
14168 ' |
|
14169 !! |
|
14170 |
|
14171 updateMethodList |
|
14172 self updateMethodListWithScroll:true keepSelection:false |
|
14173 !! |
|
14174 |
|
14175 updateMethodListWithScroll:scroll |
|
14176 self updateMethodListWithScroll:scroll keepSelection:false |
|
14177 !! |
|
14178 |
|
14179 updateMethodListWithScroll:scroll keepSelection:keep |
|
14180 |selectors scr first last selection| |
|
14181 |
|
14182 |
|
14183 methodListView notNil ifTrue:[ |
|
14184 selection := methodListView selection. |
|
14185 |
|
14186 currentMethodCategory notNil ifTrue:[ |
|
14187 fullProtocol ifTrue:[ |
|
14188 selectors := self listOfAllSelectorsInCategory:currentMethodCategory |
|
14189 inFullProtocolHierarchyOfClass:actualClass |
|
14190 ] ifFalse:[ |
|
14191 selectors := self listOfAllSelectorsInCategory:currentMethodCategory |
|
14192 ofClass:actualClass |
|
14193 ] |
|
14194 ]. |
|
14195 scr := scroll. |
|
14196 first := methodListView firstLineShown. |
|
14197 first ~~ 1 ifTrue:[ |
|
14198 last := methodListView lastLineShown. |
|
14199 selectors size <= (last - first + 1) ifTrue:[ |
|
14200 scr := true |
|
14201 ] |
|
14202 ]. |
|
14203 methodListView list = selectors ifFalse:[ |
|
14204 scr ifTrue:[ |
|
14205 methodListView contents:selectors |
|
14206 ] ifFalse:[ |
|
14207 methodListView setContents:selectors |
|
14208 ] |
|
14209 ]. |
|
14210 keep ifTrue:[ |
|
14211 methodListView selection:selection. |
|
14212 ] |
|
14213 ] |
|
14214 !! !! |
|
14215 |
|
14216 !!BrowserView methodsFor:'misc'!! |
|
14217 |
|
14218 instanceProtocol:aBoolean |
|
14219 "switch between instance and class protocol" |
|
14220 |
|
14221 |onToggle offToggle| |
|
14222 |
|
14223 showInstance ~~ aBoolean ifTrue:[ |
|
14224 self checkSelectionChangeAllowed ifTrue:[ |
|
14225 instanceToggle notNil ifTrue:[ |
|
14226 aBoolean ifTrue:[ |
|
14227 offToggle := classToggle. |
|
14228 onToggle := instanceToggle. |
|
14229 ] ifFalse:[ |
|
14230 onToggle := classToggle. |
|
14231 offToggle := instanceToggle. |
|
14232 ]. |
|
14233 onToggle turnOn. |
|
14234 offToggle turnOff. |
|
14235 ]. |
|
14236 showInstance := aBoolean. |
|
14237 |
|
14238 (variableListView notNil |
|
14239 and:[variableListView hasSelection]) ifTrue:[ |
|
14240 self unhilightMethodCategories. |
|
14241 self unhilightMethods. |
|
14242 variableListView deselect |
|
14243 ]. |
|
14244 |
|
14245 fullProtocol ifTrue:[ |
|
14246 showInstance ifTrue:[ |
|
14247 actualClass := currentClassHierarchy. |
|
14248 ] ifFalse:[ |
|
14249 actualClass := currentClassHierarchy class. |
|
14250 ]. |
|
14251 acceptClass := actualClass. |
|
14252 |
|
14253 self updateClassList. |
|
14254 self updateMethodCategoryListWithScroll:false. |
|
14255 self updateMethodListWithScroll:false. |
|
14256 self updateVariableList. |
|
14257 ^ self |
|
14258 ]. |
|
14259 currentClass notNil ifTrue:[ |
|
14260 self classSelectionChanged |
|
14261 ]. |
|
14262 codeView modified:false. |
|
14263 ] ifFalse:[ |
|
14264 aBoolean ifTrue:[ |
|
14265 onToggle := classToggle. |
|
14266 offToggle := instanceToggle |
|
14267 ] ifFalse:[ |
|
14268 offToggle := classToggle. |
|
14269 onToggle := instanceToggle. |
|
14270 ]. |
|
14271 onToggle turnOn. |
|
14272 offToggle turnOff. |
|
14273 ] |
|
14274 ] |
|
14275 !! |
|
14276 |
|
14277 processName |
|
14278 "the name of my process - for the processMonitor only" |
|
14279 |
|
14280 ^ 'System Browser'. |
|
14281 !! |
|
14282 |
|
14283 updateCodeView |
|
14284 |code| |
|
14285 |
|
14286 fullClass ifTrue:[ |
|
14287 currentClass notNil ifTrue:[ |
|
14288 code := currentClass source. |
|
14289 ] |
|
14290 ] ifFalse:[ |
|
14291 currentMethod notNil ifTrue:[ |
|
14292 (codeView acceptAction isNil |
|
14293 and:[actualClass notNil |
|
14294 and:[currentMethodCategory notNil]]) ifTrue:[ |
|
14295 self setAcceptAndExplainActionsForMethod. |
|
14296 ]. |
|
14297 |
|
14298 code := currentMethod source. |
|
14299 |
|
14300 ] |
|
14301 ]. |
|
14302 codeView contents:code. |
|
14303 codeView modified:false. |
|
14304 |
|
14305 self normalLabel. |
|
14306 |
|
14307 "Created: 23.11.1995 / 14:16:43 / cg" |
|
14308 "Modified: 23.11.1995 / 14:19:25 / cg" |
|
14309 !! !! |
|
14310 |
|
14311 !!BrowserView methodsFor:'private'!! |
|
14312 |
|
14313 askAndBrowseMethodCategory:title action:aBlock |
|
14314 "convenient method: setup enterBox with initial being current method category" |
|
14315 |
|
14316 |sel box| |
|
14317 |
|
14318 box := self enterBoxTitle:title okText:'browse'. |
|
14319 sel := codeView selection. |
|
14320 sel isNil ifTrue:[ |
|
14321 currentMethodCategory notNil ifTrue:[ |
|
14322 sel := currentMethodCategory |
|
14323 ] |
|
14324 ]. |
|
14325 sel notNil ifTrue:[ |
|
14326 box initialText:(sel asString withoutSpaces) |
|
14327 ]. |
|
14328 box action:[:aString | self withWaitCursorDo:[aBlock value:aString]]. |
|
14329 box showAtPointer |
|
14330 !! |
|
14331 |
|
14332 askForMethodCategory |
|
14333 |someCategories box txt| |
|
14334 |
|
14335 someCategories := actualClass categories sort. |
|
14336 box := self listBoxTitle:'accept in which method category ?' okText:'accept' list:someCategories. |
|
14337 |
|
14338 lastMethodCategory isNil ifTrue:[ |
|
14339 txt := 'new methods' |
|
14340 ] ifFalse:[ |
|
14341 txt := lastMethodCategory |
|
14342 ]. |
|
14343 box initialText:txt. |
|
14344 box action:[:aString | ^ aString ]. |
|
14345 box showAtPointer. |
|
14346 ^ nil |
|
14347 !! |
|
14348 |
|
14349 askForSelectorTitle:title |
|
14350 "convenient method: setup enterBox with text from codeView or selected |
|
14351 method for browsing based on a selector. Set action and launch box" |
|
14352 |
|
14353 |box| |
|
14354 |
|
14355 box := self enterBoxTitle:title okText:'browse'. |
|
14356 box initialText:(self selectorToSearchFor). |
|
14357 box action:[:aString | aString isEmpty ifTrue:[^ nil]. ^ aString]. |
|
14358 box showAtPointer. |
|
14359 ^ nil |
|
14360 !! |
|
14361 |
|
14362 askForSelectorTitle:title openWith:selector |
|
14363 "convenient method: setup enterBox with text from codeView or selected |
|
14364 method for browsing based on a selector. Set action and launch box" |
|
14365 |
|
14366 |string| |
|
14367 |
|
14368 string := self askForSelectorTitle:title. |
|
14369 string notNil ifTrue:[ |
|
14370 self withSearchCursorDo:[ |
|
14371 SystemBrowser perform:selector with:string |
|
14372 ] |
|
14373 ]. |
|
14374 |
|
14375 "Created: 23.11.1995 / 14:11:34 / cg" |
|
14376 !! |
|
14377 |
|
14378 askForSelectorTitle:title openWith:selector and:arg |
|
14379 "convenient method: setup enterBox with text from codeView or selected |
|
14380 method for browsing based on a selector. Set action and launch box" |
|
14381 |
|
14382 |string| |
|
14383 |
|
14384 string := self askForSelectorTitle:title. |
|
14385 string notNil ifTrue:[ |
|
14386 self withSearchCursorDo:[ |
|
14387 SystemBrowser perform:selector with:string with:arg |
|
14388 ] |
|
14389 ]. |
|
14390 |
|
14391 "Created: 23.11.1995 / 14:11:38 / cg" |
|
14392 !! |
|
14393 |
|
14394 busyLabel:what with:someArgument |
|
14395 "set the title for some warning" |
|
14396 |
|
14397 self label:('System Browser - ' , (resources string:what with:someArgument)) |
|
14398 !! |
|
14399 |
|
14400 checkSelectionChangeAllowedWithCompare:compareOffered |
|
14401 "return true, if selection change is ok; |
|
14402 its not ok, if code has been changed. |
|
14403 in this case, return the result of a user query" |
|
14404 |
|
14405 |action labels values| |
|
14406 |
|
14407 codeView modified ifFalse:[ |
|
14408 ^ true |
|
14409 ]. |
|
14410 |
|
14411 compareOffered ifTrue:[ |
|
14412 labels := #('abort' 'compare' 'accept' 'continue'). |
|
14413 values := #(false #compare #accept true). |
|
14414 ] ifFalse:[ |
|
14415 labels := #('abort' 'accept' 'continue'). |
|
14416 values := #(false #accept true). |
|
14417 ]. |
|
14418 |
|
14419 action := OptionBox |
|
14420 request:(resources at:'text has not been accepted.\\Your modifications will be lost when continuing.') withCRs |
|
14421 label:(resources string:'Attention') |
|
14422 form:(WarningBox iconBitmap) |
|
14423 buttonLabels:(resources array:labels) |
|
14424 values:values |
|
14425 default:true. |
|
14426 action ~~ #accept ifTrue:[ |
|
14427 ^ action |
|
14428 ]. |
|
14429 codeView accept. |
|
14430 ^ true |
|
14431 |
|
14432 "Created: 24.11.1995 / 10:54:46 / cg" |
|
14433 !! |
|
14434 |
|
14435 checkSelectionChangeAllowed |
|
14436 "return true, if selection change is ok; |
|
14437 its not ok, if code has been changed. |
|
14438 in this case, return the result of a user query" |
|
14439 |
|
14440 |what m src v| |
|
14441 |
|
14442 currentMethod notNil ifTrue:[ |
|
14443 m := actualClass compiledMethodAt:currentSelector. |
|
14444 m notNil ifTrue:[ |
|
14445 (src := m source) = codeView contents ifFalse:[ |
|
14446 what := self checkSelectionChangeAllowedWithCompare:true. |
|
14447 what == #compare ifTrue:[ |
|
14448 v := DiffTextView |
|
14449 openOn:codeView contents label:'code here (to be accepted ?)' |
|
14450 and:src label:'methods actual code'. |
|
14451 v label:'comparing method versions'. |
|
14452 ^ false |
|
14453 ]. |
|
14454 ^ what |
|
14455 ] |
|
14456 ] |
|
14457 ]. |
|
14458 |
|
14459 ^ self checkSelectionChangeAllowedWithCompare:false |
|
14460 |
|
14461 "Created: 24.11.1995 / 11:03:33 / cg" |
|
14462 "Modified: 24.11.1995 / 11:05:49 / cg" |
|
14463 !! |
|
14464 |
|
14465 classHierarchyDo:aBlock |
|
14466 "eavluate the 2-arg block for every class, |
|
14467 starting at Object; passing class and nesting level to the block." |
|
14468 |
|
14469 |classes s classDict l| |
|
14470 |
|
14471 classes := Smalltalk allClasses. |
|
14472 classDict := IdentityDictionary new:classes size. |
|
14473 classes do:[:aClass | |
|
14474 s := aClass superclass. |
|
14475 s notNil ifTrue:[ |
|
14476 l := classDict at:s ifAbsent:[nil]. |
|
14477 l isNil ifTrue:[ |
|
14478 l := OrderedCollection new:5. |
|
14479 classDict at:s put:l |
|
14480 ]. |
|
14481 l add:aClass |
|
14482 ] |
|
14483 ]. |
|
14484 self classHierarchyOf:Object level:0 do:aBlock using:classDict |
|
14485 !! |
|
14486 |
|
14487 classHierarchyOf:aClass level:level do:aBlock using:aDictionary |
|
14488 "evaluate the 2-arg block for every subclass of aClass, |
|
14489 passing class and nesting level to the block." |
|
14490 |
|
14491 |names subclasses| |
|
14492 |
|
14493 aBlock value:aClass value:level. |
|
14494 subclasses := aDictionary at:aClass ifAbsent:[nil]. |
|
14495 (subclasses size == 0) ifFalse:[ |
|
14496 names := subclasses collect:[:class | class name]. |
|
14497 names sortWith:subclasses. |
|
14498 subclasses do:[:aSubClass | |
|
14499 self classHierarchyOf:aSubClass level:(level + 1) do:aBlock using:aDictionary |
|
14500 ] |
|
14501 ] |
|
14502 !! |
|
14503 |
|
14504 classesInFullProtocolHierarchy:aClass do:aBlock |
|
14505 "evaluate aBlock for all non-striked out classes in |
|
14506 the hierarchy" |
|
14507 |
|
14508 |index| |
|
14509 |
|
14510 index := (classListView list size). |
|
14511 aClass withAllSuperclasses do:[:c | |
|
14512 (classListView isInSelection:index) ifFalse:[ |
|
14513 aBlock value:c |
|
14514 ]. |
|
14515 index := index - 1 |
|
14516 ] |
|
14517 |
|
14518 !! |
|
14519 |
|
14520 classesInHierarchy:aClass do:aBlock |
|
14521 |index| |
|
14522 |
|
14523 index := (classListView list size). |
|
14524 aClass withAllSuperclasses do:[:c | |
|
14525 (classListView isInSelection:index) ifFalse:[ |
|
14526 aBlock value:c |
|
14527 ]. |
|
14528 index := index - 1 |
|
14529 ] |
|
14530 |
|
14531 !! |
|
14532 |
|
14533 compileCode:someCode |
|
14534 (ReadStream on:someCode) fileIn |
|
14535 !! |
|
14536 |
|
14537 enterBoxForBrowseTitle:title action:aBlock |
|
14538 "convenient method: setup enterBox with text from codeView or selected |
|
14539 method for method browsing based on className/variable" |
|
14540 |
|
14541 |box| |
|
14542 |
|
14543 box := self enterBoxTitle:title okText:'browse'. |
|
14544 box initialText:(self stringToSearchFor). |
|
14545 box action:[:aString | |
|
14546 aString notEmpty ifTrue:[ |
|
14547 self withWaitCursorDo:[aBlock value:aString] |
|
14548 ]. |
|
14549 ]. |
|
14550 box showAtPointer |
|
14551 !! |
|
14552 |
|
14553 enterBoxForCodeSelectionTitle:title okText:okText |
|
14554 "convenient method: setup enterBox with text from codeview" |
|
14555 |
|
14556 |sel box| |
|
14557 |
|
14558 box := self enterBoxTitle:(resources string:title) okText:(resources string:okText). |
|
14559 sel := codeView selection. |
|
14560 sel notNil ifTrue:[ |
|
14561 box initialText:(sel asString withoutSeparators) |
|
14562 ]. |
|
14563 ^ box |
|
14564 !! |
|
14565 |
|
14566 enterBoxForSearchSelectorTitle:title |
|
14567 "convenient method: setup enterBox with text from codeView or selected |
|
14568 method for browsing based on a selector" |
|
14569 |
|
14570 |box| |
|
14571 |
|
14572 box := self enterBoxTitle:title okText:'search'. |
|
14573 box initialText:(self selectorToSearchFor). |
|
14574 ^ box |
|
14575 !! |
|
14576 |
|
14577 enterBoxTitle:title okText:okText |
|
14578 "convenient method: setup enterBox" |
|
14579 |
|
14580 |box| |
|
14581 |
|
14582 box := EnterBox new. |
|
14583 box title:(resources string:title) okText:(resources string:okText). |
|
14584 ^ box |
|
14585 !! |
|
14586 |
|
14587 extractClassAndSelectorFromSelectionInto:aBlock |
|
14588 "given a string which can be either 'class>>sel' or |
|
14589 'class sel', extract className and selector, and call aBlock with |
|
14590 the result." |
|
14591 |
|
14592 |sel clsName isMeta sep s| |
|
14593 |
|
14594 sel := codeView selection. |
|
14595 sel notNil ifTrue:[ |
|
14596 sel := sel asString withoutSeparators. |
|
14597 ('*>>*' match:sel) ifTrue:[ |
|
14598 sep := $> |
|
14599 ] ifFalse:[ |
|
14600 ('* *' match:sel) ifTrue:[ |
|
14601 sep := Character space |
|
14602 ] |
|
14603 ]. |
|
14604 sep notNil ifTrue:[ |
|
14605 " |
|
14606 extract class/sel from selection |
|
14607 " |
|
14608 s := ReadStream on:sel. |
|
14609 clsName := s upTo:sep. |
|
14610 [s peek == sep] whileTrue:[s next]. |
|
14611 sel := s upToEnd. |
|
14612 |
|
14613 (clsName endsWith:'class') ifTrue:[ |
|
14614 isMeta := true. |
|
14615 clsName := clsName copyWithoutLast:5 "copyTo:(clsName size - 5)" |
|
14616 ] ifFalse:[ |
|
14617 isMeta := false |
|
14618 ]. |
|
14619 ] |
|
14620 ]. |
|
14621 aBlock value:clsName value:sel value:isMeta |
|
14622 |
|
14623 |
|
14624 !! |
|
14625 |
|
14626 findClassOfVariable:aVariableName accessWith:aSelector |
|
14627 "this method returns the class, in which a variable |
|
14628 is defined; |
|
14629 needs either #instVarNames or #classVarNames as aSelector." |
|
14630 |
|
14631 |cls homeClass| |
|
14632 |
|
14633 " |
|
14634 first, find the class, where the variable is declared |
|
14635 " |
|
14636 cls := currentClass. |
|
14637 [cls notNil] whileTrue:[ |
|
14638 ((cls perform:aSelector) includes:aVariableName) ifTrue:[ |
|
14639 homeClass := cls. |
|
14640 cls := nil. |
|
14641 ] ifFalse:[ |
|
14642 cls := cls superclass |
|
14643 ] |
|
14644 ]. |
|
14645 homeClass isNil ifTrue:[ |
|
14646 "nope, must be one below ... (could optimize a bit, by searching down |
|
14647 for the declaring class ... |
|
14648 " |
|
14649 homeClass := currentClass |
|
14650 ] ifFalse:[ |
|
14651 "/ Transcript showCr:'starting search in ' , homeClass name. |
|
14652 ]. |
|
14653 ^ homeClass |
|
14654 !! |
|
14655 |
|
14656 listBoxForCodeSelectionTitle:title okText:okText |
|
14657 "convenient method: setup listBox with text from codeview" |
|
14658 |
|
14659 |sel box| |
|
14660 |
|
14661 box := self listBoxTitle:title okText:okText list:nil. |
|
14662 sel := codeView selection. |
|
14663 sel notNil ifTrue:[ |
|
14664 box initialText:(sel asString withoutSeparators) |
|
14665 ]. |
|
14666 ^ box |
|
14667 !! |
|
14668 |
|
14669 listBoxTitle:title okText:okText list:aList |
|
14670 "convenient method: setup a listBox & return it" |
|
14671 |
|
14672 |box| |
|
14673 |
|
14674 box := ListSelectionBox |
|
14675 title:(resources string:title) |
|
14676 okText:(resources string:okText) |
|
14677 action:nil. |
|
14678 box list:aList. |
|
14679 ^ box |
|
14680 !! |
|
14681 |
|
14682 normalLabel |
|
14683 "set the normal (inactive) window- and icon labels" |
|
14684 |
|
14685 |l il| |
|
14686 |
|
14687 myLabel notNil ifTrue:[ |
|
14688 "if I have been given an explicit label, |
|
14689 and its not the default, take that one" |
|
14690 |
|
14691 myLabel ~= 'System Browser' ifTrue:[ |
|
14692 l := il := myLabel |
|
14693 ] |
|
14694 ]. |
|
14695 l isNil ifTrue:[ |
|
14696 l := resources string:'System Browser'. |
|
14697 |
|
14698 currentClass notNil ifTrue:[ |
|
14699 l := l, ': ', currentClass name. |
|
14700 classListView isNil ifTrue:[ |
|
14701 currentSelector notNil ifTrue:[ |
|
14702 l := l , ' ' , currentSelector |
|
14703 ] |
|
14704 ]. |
|
14705 il := currentClass name |
|
14706 ] ifFalse:[ |
|
14707 il := l. |
|
14708 ] |
|
14709 ]. |
|
14710 self label:l. |
|
14711 self iconLabel:il. |
|
14712 !! |
|
14713 |
|
14714 selectorToSearchFor |
|
14715 "look in codeView and methodListView for a search-string when searching for selectors" |
|
14716 |
|
14717 |sel t| |
|
14718 |
|
14719 sel := codeView selection. |
|
14720 sel notNil ifTrue:[ |
|
14721 sel := sel asString. |
|
14722 t := Parser selectorInExpression:sel. |
|
14723 t notNil ifTrue:[ |
|
14724 sel := t |
|
14725 ]. |
|
14726 sel := sel withoutSpaces. |
|
14727 sel == #>> ifTrue:[ |
|
14728 "oops - thats probably not what we want here ..." |
|
14729 self extractClassAndSelectorFromSelectionInto:[:c :s :m | |
|
14730 sel := s |
|
14731 ] |
|
14732 ] |
|
14733 ] ifFalse:[ |
|
14734 methodListView notNil ifTrue:[ |
|
14735 sel := methodListView selectionValue |
|
14736 ] ifFalse:[ |
|
14737 classMethodListView notNil ifTrue:[ |
|
14738 sel := classMethodListView selectionValue. |
|
14739 sel notNil ifTrue:[ |
|
14740 sel := self selectorFromClassMethodString:sel |
|
14741 ] |
|
14742 ] |
|
14743 ]. |
|
14744 sel notNil ifTrue:[ |
|
14745 sel := sel withoutSpaces upTo:(Character space) |
|
14746 ] ifFalse:[ |
|
14747 sel := '' |
|
14748 ] |
|
14749 ]. |
|
14750 ^ sel |
|
14751 !! |
|
14752 |
|
14753 setAcceptAndExplainActionsForMethod |
|
14754 "tell the codeView what to do on accept and explain" |
|
14755 |
|
14756 codeView acceptAction:[:theCode | |
|
14757 |cat cls| |
|
14758 |
|
14759 codeView cursor:Cursor execute. |
|
14760 |
|
14761 (cat := currentMethodCategory) = '* all *' ifTrue:[ |
|
14762 "must check from which category this code came from ... |
|
14763 ... thanks to Arno for pointing this out" |
|
14764 |
|
14765 cat := self askForMethodCategory. |
|
14766 ]. |
|
14767 (cat notNil and:[cat notEmpty]) ifTrue:[ |
|
14768 fullProtocol ifTrue:[ |
|
14769 cls := acceptClass "/actualClass whichClassIncludesSelector:currentSelector. |
|
14770 ]. |
|
14771 cls isNil ifTrue:[ |
|
14772 cls := actualClass |
|
14773 ]. |
|
14774 |
|
14775 Object abortSignal catch:[ |
|
14776 lockUpdates := true. |
|
14777 |
|
14778 actualClass compilerClass |
|
14779 compile:theCode asString |
|
14780 forClass:cls |
|
14781 inCategory:cat |
|
14782 notifying:codeView. |
|
14783 |
|
14784 codeView modified:false. |
|
14785 self updateMethodListWithScroll:false. |
|
14786 currentMethod := actualClass compiledMethodAt:currentSelector. |
|
14787 ]. |
|
14788 lockUpdates := false. |
|
14789 ]. |
|
14790 codeView cursor:Cursor normal. |
|
14791 ]. |
|
14792 |
|
14793 codeView explainAction:[:theCode :theSelection | |
|
14794 self showExplanation:(Explainer |
|
14795 explain:theSelection |
|
14796 in:theCode |
|
14797 forClass:actualClass) |
|
14798 ]. |
|
14799 !! |
|
14800 |
|
14801 setDoitActionForClass |
|
14802 "tell the codeView what to do on doIt" |
|
14803 |
|
14804 "set self for doits. This allows accessing the current class |
|
14805 as self, and access to the class variables by name. |
|
14806 " |
|
14807 codeView doItAction:[:theCode | |
|
14808 |compiler| |
|
14809 |
|
14810 currentClass isNil ifTrue:[ |
|
14811 compiler := Compiler |
|
14812 ] ifFalse:[ |
|
14813 compiler := currentClass evaluatorClass |
|
14814 ]. |
|
14815 compiler |
|
14816 evaluate:theCode |
|
14817 in:nil |
|
14818 receiver:currentClass |
|
14819 notifying:codeView |
|
14820 logged:false |
|
14821 ifFail:nil |
|
14822 ]. |
|
14823 !! |
|
14824 |
|
14825 setSearchPattern:aString |
|
14826 codeView setSearchPattern:aString |
|
14827 !! |
|
14828 |
|
14829 showExplanation:someText |
|
14830 "show explanation from Parser" |
|
14831 |
|
14832 self information:someText |
|
14833 !! |
|
14834 |
|
14835 stringToSearchFor |
|
14836 "look in codeView and methodListView for a search-string when searching for classes/names" |
|
14837 |
|
14838 |sel| |
|
14839 |
|
14840 sel := codeView selection. |
|
14841 sel notNil ifTrue:[ |
|
14842 sel := sel asString withoutSpaces |
|
14843 ] ifFalse:[ |
|
14844 sel isNil ifTrue:[ |
|
14845 currentClass notNil ifTrue:[ |
|
14846 sel := currentClass name |
|
14847 ] |
|
14848 ]. |
|
14849 sel notNil ifTrue:[ |
|
14850 sel := sel withoutSpaces |
|
14851 ] ifFalse:[ |
|
14852 sel := '' |
|
14853 ] |
|
14854 ]. |
|
14855 ^ sel |
|
14856 !! |
|
14857 |
|
14858 warnLabel:what |
|
14859 "set the title for some warning" |
|
14860 |
|
14861 self label:('System Browser WARNING: ' , what) |
|
14862 !! |
|
14863 |
|
14864 withSearchCursorDo:aBlock |
|
14865 ^ self withCursor:(Cursor questionMark) do:aBlock |
|
14866 |
|
14867 "Created: 23.11.1995 / 14:11:14 / cg" |
|
14868 !! !! |
|
14869 |
|
14870 !!BrowserView methodsFor:'unused'!! |
|
14871 |
|
14872 listOfAllMethodCategoriesInHierarchy:aClass |
|
14873 "answer a list of all method categories of the argument, aClass, |
|
14874 and all of its superclasses" |
|
14875 |
|
14876 |newList cat| |
|
14877 |
|
14878 newList := Set new. |
|
14879 self classesInHierarchy:aClass do:[:c | |
|
14880 c methodArray do:[:aMethod | |
|
14881 cat := aMethod category. |
|
14882 cat isNil ifTrue:[ |
|
14883 cat := '* no category *' |
|
14884 ]. |
|
14885 newList add:cat |
|
14886 ] |
|
14887 ]. |
|
14888 (newList size == 0) ifTrue:[^ nil]. |
|
14889 newList add:'* all *'. |
|
14890 ^ newList asOrderedCollection sort |
|
14891 |
|
14892 !! |
|
14893 |
|
14894 listOfAllSelectorsInCategory:aCategory inHierarchyOfClass:aClass |
|
14895 "answer a list of all selectors in a given method category |
|
14896 of the argument, aClass and its superclasses" |
|
14897 |
|
14898 |newList| |
|
14899 |
|
14900 newList := Set new. |
|
14901 self classesInHierarchy:aClass do:[:c | |
|
14902 |searchCategory| |
|
14903 |
|
14904 (aCategory = '* all *') ifTrue:[ |
|
14905 newList addAll:(c selectorArray) |
|
14906 ] ifFalse:[ |
|
14907 (aCategory = '* no category *') ifTrue:[ |
|
14908 searchCategory := nil |
|
14909 ] ifFalse:[ |
|
14910 searchCategory := aCategory |
|
14911 ]. |
|
14912 c methodArray with:c selectorArray do:[:aMethod :selector | |
|
14913 (aMethod category = searchCategory) ifTrue:[ |
|
14914 newList add:selector |
|
14915 ] |
|
14916 ] |
|
14917 ]. |
|
14918 ]. |
|
14919 (newList size == 0) ifTrue:[^ nil]. |
|
14920 ^ newList asOrderedCollection sort |
|
14921 !! !! |
|
14922 |
|
14923 !!BrowserView methodsFor:'variable list menu'!! |
|
14924 |
|
14925 allClassOrInstVarRefsTitle:title access:access mods:modifications |
|
14926 "show an enterbox for instVar to search for" |
|
14927 |
|
14928 self doClassMenu:[:currentClass | |
|
14929 |box| |
|
14930 |
|
14931 box := self enterBoxForVariableSearch:title. |
|
14932 box action:[:aVariableName | |
|
14933 |homeClass| |
|
14934 |
|
14935 aVariableName isEmpty ifFalse:[ |
|
14936 self withSearchCursorDo:[ |
|
14937 homeClass := self findClassOfVariable:aVariableName accessWith:access. |
|
14938 access == #classVarNames ifTrue:[ |
|
14939 SystemBrowser |
|
14940 browseClassRefsTo:aVariableName |
|
14941 under:homeClass |
|
14942 modificationsOnly:modifications |
|
14943 ] ifFalse:[ |
|
14944 SystemBrowser |
|
14945 browseInstRefsTo:aVariableName |
|
14946 under:homeClass |
|
14947 modificationsOnly:modifications |
|
14948 ] |
|
14949 ] |
|
14950 ] |
|
14951 ]. |
|
14952 box showAtPointer |
|
14953 ] |
|
14954 |
|
14955 "Created: 23.11.1995 / 14:13:24 / cg" |
|
14956 !! |
|
14957 |
|
14958 allClassVarMods |
|
14959 "show an enterbox for classVar to search for" |
|
14960 |
|
14961 self allClassOrInstVarRefsTitle:'class variable to browse modifications of:' |
|
14962 access:#classVarNames |
|
14963 mods:true |
|
14964 !! |
|
14965 |
|
14966 allClassVarRefs |
|
14967 "show an enterbox for classVar to search for" |
|
14968 |
|
14969 self allClassOrInstVarRefsTitle:'class variable to browse references to:' |
|
14970 access:#classVarNames |
|
14971 mods:false |
|
14972 !! |
|
14973 |
|
14974 allInstVarMods |
|
14975 "show an enterbox for instVar to search for" |
|
14976 |
|
14977 self allClassOrInstVarRefsTitle:'instance variable to browse modifications of:' |
|
14978 access:#instVarNames |
|
14979 mods:true |
|
14980 !! |
|
14981 |
|
14982 allInstVarRefs |
|
14983 "show an enterbox for instVar to search for" |
|
14984 |
|
14985 self allClassOrInstVarRefsTitle:'instance variable to browse references to:' |
|
14986 access:#instVarNames |
|
14987 mods:false |
|
14988 !! |
|
14989 |
|
14990 classVarMods |
|
14991 "show an enterbox for classVar to search for" |
|
14992 |
|
14993 self classVarRefsOrModsTitle:'class variable to browse modifications of:' |
|
14994 mods:true |
|
14995 !! |
|
14996 |
|
14997 classVarRefs |
|
14998 "show an enterbox for classVar to search for" |
|
14999 |
|
15000 self classVarRefsOrModsTitle:'class variable to browse references to:' |
|
15001 mods:false |
|
15002 !! |
|
15003 |
|
15004 classVarRefsOrModsTitle:title mods:mods |
|
15005 "show an enterbox for classVar to search for" |
|
15006 |
|
15007 self doClassMenu:[:currentClass | |
|
15008 |box| |
|
15009 |
|
15010 box := self enterBoxForVariableSearch:title. |
|
15011 box action:[:aString | |
|
15012 aString notEmpty ifTrue:[ |
|
15013 self withSearchCursorDo:[ |
|
15014 SystemBrowser |
|
15015 browseClassRefsTo:aString |
|
15016 in:(Array with:currentClass) |
|
15017 modificationsOnly:mods |
|
15018 ] |
|
15019 ] |
|
15020 ]. |
|
15021 box showAtPointer |
|
15022 ] |
|
15023 |
|
15024 "Created: 23.11.1995 / 14:12:56 / cg" |
|
15025 !! |
|
15026 |
|
15027 enterBoxForVariableSearch:title |
|
15028 |box sel| |
|
15029 |
|
15030 box := self enterBoxForCodeSelectionTitle:title okText:'browse'. |
|
15031 variableListView notNil ifTrue:[ |
|
15032 codeView hasSelection ifFalse:[ |
|
15033 (sel := variableListView selectionValue) notNil ifTrue:[ |
|
15034 (sel startsWith:'---') ifFalse:[ |
|
15035 box initialText:sel |
|
15036 ] |
|
15037 ] |
|
15038 ] |
|
15039 ]. |
|
15040 ^ box |
|
15041 !! |
|
15042 |
|
15043 instVarMods |
|
15044 "show an enterbox for instVar to search for" |
|
15045 |
|
15046 self instVarRefsOrModsTitle:'instance variable to browse modifications of:' |
|
15047 mods:true |
|
15048 !! |
|
15049 |
|
15050 instVarRefs |
|
15051 "show an enterbox for instVar to search for" |
|
15052 |
|
15053 self instVarRefsOrModsTitle:'instance variable to browse references to:' |
|
15054 mods:false |
|
15055 !! |
|
15056 |
|
15057 instVarRefsOrModsTitle:title mods:mods |
|
15058 "show an enterbox for instvar to search for" |
|
15059 |
|
15060 self doClassMenu:[:currentClass | |
|
15061 |box| |
|
15062 |
|
15063 box := self enterBoxForVariableSearch:title. |
|
15064 box action:[:aString | |
|
15065 aString notEmpty ifTrue:[ |
|
15066 self withSearchCursorDo:[ |
|
15067 SystemBrowser |
|
15068 browseInstRefsTo:aString |
|
15069 in:(Array with:currentClass) |
|
15070 modificationsOnly:mods |
|
15071 ] |
|
15072 ] |
|
15073 ]. |
|
15074 box showAtPointer |
|
15075 ] |
|
15076 |
|
15077 "Created: 23.11.1995 / 14:12:40 / cg" |
|
15078 !! |
|
15079 |
|
15080 varTypeInfo |
|
15081 "show typical usage of a variable" |
|
15082 |
|
15083 |name idx classes values value msg cut names instCount subInstCount box |
|
15084 searchClass| |
|
15085 |
|
15086 name := variableListView selectionValue. |
|
15087 name isNil ifTrue:[^ self]. |
|
15088 |
|
15089 searchClass := actualClass whichClassDefinesInstVar:name. |
|
15090 |
|
15091 idx := searchClass instVarOffsetOf:name. |
|
15092 idx isNil ifTrue:[^ self]. |
|
15093 |
|
15094 classes := IdentitySet new. |
|
15095 values := IdentitySet new. |
|
15096 instCount := 0. |
|
15097 subInstCount := 0. |
|
15098 searchClass allSubInstancesDo:[:i | |
|
15099 |val| |
|
15100 |
|
15101 val := i instVarAt:idx. |
|
15102 val notNil ifTrue:[values add:val]. |
|
15103 classes add:val class. |
|
15104 (i isMemberOf:searchClass) ifTrue:[ |
|
15105 instCount := instCount + 1. |
|
15106 ] ifFalse:[ |
|
15107 subInstCount := subInstCount + 1 |
|
15108 ] |
|
15109 ]. |
|
15110 (instCount == 0 and:[subInstCount == 0]) ifTrue:[ |
|
15111 self warn:'there are currently no instances of ' , currentClass name. |
|
15112 ^ self |
|
15113 ]. |
|
15114 |
|
15115 instCount ~~ 0 ifTrue:[ |
|
15116 msg := 'in (currently: ' , instCount printString,') instances '. |
|
15117 subInstCount ~~ 0 ifTrue:[ |
|
15118 msg := msg , 'and ' |
|
15119 ] |
|
15120 ] ifFalse:[ |
|
15121 msg := 'in '. |
|
15122 ]. |
|
15123 subInstCount ~~ 0 ifTrue:[ |
|
15124 msg := msg , '(currently: ' , subInstCount printString, ') derived instances ' |
|
15125 ]. |
|
15126 msg := msg, 'of ' , searchClass name , ',\'. |
|
15127 msg := msg , name , ' '. |
|
15128 ((values size == 1) |
|
15129 or:[classes size == 1 and:[classes first == UndefinedObject]]) ifTrue:[ |
|
15130 values size == 1 ifTrue:[value := values first]. |
|
15131 (value isNumber or:[value isString]) ifTrue:[ |
|
15132 msg := msg , 'is always the same:\\ ' , |
|
15133 value class name , ' (' , value storeString , ')'. |
|
15134 ] ifFalse:[ |
|
15135 (value isNil or:[value == true or:[value == false]]) ifTrue:[ |
|
15136 msg := msg , 'is always:\\ ' , |
|
15137 value printString. |
|
15138 ] ifFalse:[ |
|
15139 msg := msg , 'is always the same:\\'. |
|
15140 msg := msg , ' ' , value class name. |
|
15141 value isLiteral ifTrue:[ |
|
15142 msg := msg , ' (' , value storeString , ')' |
|
15143 ] |
|
15144 ] |
|
15145 ] |
|
15146 ] ifFalse:[ |
|
15147 classes size == 1 ifTrue:[ |
|
15148 msg := msg , 'is always:\\'. |
|
15149 msg := msg , ' ' , classes first name , '\'. |
|
15150 ] ifFalse:[ |
|
15151 msg := msg , 'is one of:\\'. |
|
15152 classes := classes asOrderedCollection. |
|
15153 classes size > 20 ifTrue:[ |
|
15154 classes := classes copyFrom:1 to:20. |
|
15155 cut := true |
|
15156 ] ifFalse:[ |
|
15157 cut := false. |
|
15158 ]. |
|
15159 names := classes collect:[:cls | |
|
15160 |nm| |
|
15161 cls == UndefinedObject ifTrue:[ |
|
15162 'nil' |
|
15163 ] ifFalse:[ |
|
15164 cls == True ifTrue:[ |
|
15165 'true' |
|
15166 ] ifFalse:[ |
|
15167 cls == False ifTrue:[ |
|
15168 'false' |
|
15169 ] ifFalse:[ |
|
15170 cls name |
|
15171 ] |
|
15172 ] |
|
15173 ]. |
|
15174 ]. |
|
15175 names sort. |
|
15176 names do:[:nm | |
|
15177 msg := msg , ' ' , nm , '\'. |
|
15178 ]. |
|
15179 ] |
|
15180 ]. |
|
15181 |
|
15182 box := InfoBox title:msg withCRs. |
|
15183 box label:'variable type information'. |
|
15184 box showAtPointer |
|
15185 !! |
|
15186 |
|
15187 variableListMenu |
|
15188 |labels selectors| |
|
15189 |
|
15190 currentClass isNil ifTrue:[ |
|
15191 variableListView flash. |
|
15192 ^ nil |
|
15193 ]. |
|
15194 |
|
15195 labels := #( |
|
15196 'instvar refs ...' |
|
15197 'classvar refs ...' |
|
15198 'all instvar refs ...' |
|
15199 'all classvar refs ...' |
|
15200 '-' |
|
15201 'instvar mods ...' |
|
15202 'classvar mods ...' |
|
15203 'all instvar mods ...' |
|
15204 'all classvar mods ...' |
|
15205 ). |
|
15206 selectors := #( |
|
15207 instVarRefs |
|
15208 classVarRefs |
|
15209 allInstVarRefs |
|
15210 allClassVarRefs |
|
15211 nil |
|
15212 instVarMods |
|
15213 classVarMods |
|
15214 allInstVarMods |
|
15215 allClassVarMods |
|
15216 ). |
|
15217 |
|
15218 (showInstance and:[variableListView hasSelection]) ifTrue:[ |
|
15219 labels := labels , #( |
|
15220 '-' |
|
15221 'type information' |
|
15222 ). |
|
15223 selectors := selectors , #( |
|
15224 nil |
|
15225 varTypeInfo |
|
15226 ). |
|
15227 ]. |
|
15228 |
|
15229 ^ PopUpMenu labels:(resources array:labels) |
|
15230 selectors:selectors |
|
15231 !! |
|
15232 |
|
15233 variableSelection:lineNr |
|
15234 "variable selection changed" |
|
15235 |
|
15236 |name idx| |
|
15237 |
|
15238 name := variableListView selectionValue. |
|
15239 name isNil ifTrue:[ |
|
15240 self unhilightMethodCategories. |
|
15241 self unhilightMethods. |
|
15242 self autoSearch:nil. |
|
15243 ^ self |
|
15244 ]. |
|
15245 |
|
15246 " |
|
15247 first, check if the selected variable is really the one |
|
15248 we get - reselect if its hidden (for example, a class variable |
|
15249 with the same name could be defined in a subclass) |
|
15250 " |
|
15251 idx := variableListView list findLast:[:entry | entry = name]. |
|
15252 idx ~~ lineNr ifTrue:[ |
|
15253 "select it - user will see whats going on" |
|
15254 variableListView selection:idx |
|
15255 ]. |
|
15256 |
|
15257 "search for methods in the current category, which access the selected |
|
15258 variable, and highlight them" |
|
15259 |
|
15260 self hilightMethodsInMethodCategoryList:true inMethodList:true. |
|
15261 self autoSearch:name. |
|
15262 !! !! |
|
15263 |
|
15264 !!BrowserView methodsFor:'variable stuff'!! |
|
15265 |
|
15266 hilightMethodsInMethodCategoryList |
|
15267 "search for methods which access the selected |
|
15268 variable, and highlight them" |
|
15269 |
|
15270 self hilightMethodsInMethodCategoryList:true inMethodList:false |
|
15271 |
|
15272 |
|
15273 |
|
15274 !! |
|
15275 |
|
15276 hilightMethodsInMethodCategoryList:inCat inMethodList:inMethods |
|
15277 "search for methods which access the selected |
|
15278 variable, and highlight them" |
|
15279 |
|
15280 |name redefinedSelectors| |
|
15281 |
|
15282 variableListView isNil ifTrue:[^ self]. |
|
15283 |
|
15284 inCat ifTrue:[self unhilightMethodCategories]. |
|
15285 inMethods ifTrue:[self unhilightMethods]. |
|
15286 |
|
15287 actualClass isNil ifTrue:[^ self]. |
|
15288 (methodCategoryListView isNil |
|
15289 and:[methodListView isNil]) ifTrue:[^ self]. |
|
15290 |
|
15291 name := variableListView selectionValue. |
|
15292 name isNil ifTrue:[^ self]. |
|
15293 |
|
15294 self withSearchCursorDo:[ |
|
15295 |classes filter any| |
|
15296 |
|
15297 classes := Array with:actualClass. |
|
15298 currentClassHierarchy notNil ifTrue:[ |
|
15299 classes := classes , actualClass allSuperclasses. |
|
15300 redefinedSelectors := IdentitySet new. |
|
15301 ]. |
|
15302 |
|
15303 filter := SystemBrowser filterToSearchRefsTo:name classVars:showInstance not modificationsOnly:false. |
|
15304 |
|
15305 any := false. |
|
15306 " |
|
15307 highlight the method that ref this variable |
|
15308 " |
|
15309 classes do:[:someClass | |
|
15310 (fullProtocol |
|
15311 and:[classListView valueIsInSelection:(someClass name)]) ifFalse:[ |
|
15312 someClass methodArray with:someClass selectorArray |
|
15313 do:[:method :selector | |
|
15314 |
|
15315 (inCat |
|
15316 or:[methodListView list notNil |
|
15317 and:[methodListView list includes:selector]]) |
|
15318 ifTrue:[ |
|
15319 (redefinedSelectors isNil |
|
15320 or:[(redefinedSelectors includes:selector) not]) |
|
15321 ifTrue:[ |
|
15322 (filter value:someClass value:method value:selector) ifTrue:[ |
|
15323 |idx cat| |
|
15324 |
|
15325 (inCat |
|
15326 and:[methodCategoryListView notNil |
|
15327 and:[methodCategoryListView list notNil]]) ifTrue:[ |
|
15328 cat := method category. |
|
15329 " |
|
15330 highlight the methodCategory |
|
15331 " |
|
15332 idx := methodCategoryListView list indexOf:cat. |
|
15333 idx ~~ 0 ifTrue:[ |
|
15334 methodCategoryListView attributeAt:idx put:#bold. |
|
15335 ]. |
|
15336 ]. |
|
15337 |
|
15338 (inMethods |
|
15339 and:[methodListView notNil |
|
15340 and:[methodListView list notNil]]) ifTrue:[ |
|
15341 " |
|
15342 highlight the method |
|
15343 " |
|
15344 idx := methodListView list indexOf:selector. |
|
15345 idx ~~ 0 ifTrue:[ |
|
15346 methodListView attributeAt:idx put:#bold. |
|
15347 ]. |
|
15348 any := true |
|
15349 ]. |
|
15350 ]. |
|
15351 redefinedSelectors notNil ifTrue:[ |
|
15352 redefinedSelectors add:selector |
|
15353 ] |
|
15354 ] |
|
15355 ] |
|
15356 ] |
|
15357 ] |
|
15358 ]. |
|
15359 any ifTrue:[ |
|
15360 self setSearchPattern:name |
|
15361 ] |
|
15362 ] |
|
15363 |
|
15364 "Created: 23.11.1995 / 14:12:08 / cg" |
|
15365 !! |
|
15366 |
|
15367 hilightMethodsInMethodList |
|
15368 "search for methods which access the selected |
|
15369 variable, and highlight them" |
|
15370 |
|
15371 self hilightMethodsInMethodCategoryList:false inMethodList:true |
|
15372 |
|
15373 |
|
15374 |
|
15375 !! |
|
15376 |
|
15377 unhilightMethodCategories |
|
15378 "unhighlight items in method list" |
|
15379 |
|
15380 variableListView isNil ifTrue:[^ self]. |
|
15381 |
|
15382 methodCategoryListView notNil ifTrue:[ |
|
15383 1 to:methodCategoryListView list size do:[:entry | |
|
15384 methodCategoryListView attributeAt:entry put:nil. |
|
15385 ] |
|
15386 ]. |
|
15387 |
|
15388 |
|
15389 !! |
|
15390 |
|
15391 unhilightMethods |
|
15392 "unhighlight items in method list" |
|
15393 |
|
15394 variableListView isNil ifTrue:[^ self]. |
|
15395 |
|
15396 methodListView notNil ifTrue:[ |
|
15397 1 to:methodListView list size do:[:entry | |
|
15398 methodListView attributeAt:entry put:nil. |
|
15399 ]. |
|
15400 ]. |
|
15401 |
|
15402 |
|
15403 !! |
|
15404 |
|
15405 updateVariableList |
|
15406 |l subList last nameAccessSelector class oldSelection| |
|
15407 |
|
15408 variableListView isNil ifTrue:[^ self]. |
|
15409 |
|
15410 oldSelection := variableListView selectionValue. |
|
15411 |
|
15412 l := OrderedCollection new. |
|
15413 " |
|
15414 show classVars, if classProtocol is shown (instead of classInstance vars) |
|
15415 " |
|
15416 showInstance ifTrue:[ |
|
15417 nameAccessSelector := #instVarNames |
|
15418 ] ifFalse:[ |
|
15419 nameAccessSelector := #classVarNames |
|
15420 ]. |
|
15421 |
|
15422 "/ class := currentClass notNil ifTrue:[currentClass] ifFalse:[actualClass]. |
|
15423 "/ class isNil ifTrue:[class := currentClassHierarchy]. |
|
15424 class := currentClassHierarchy notNil ifTrue:[currentClassHierarchy] ifFalse:[currentClass]. |
|
15425 class withAllSuperclasses do:[:aClass | |
|
15426 |ignore| |
|
15427 |
|
15428 ignore := fullProtocol |
|
15429 and:[classListView valueIsInSelection:(aClass name asString)]. |
|
15430 ignore ifFalse:[ |
|
15431 subList := aClass perform:nameAccessSelector. |
|
15432 subList size ~~ 0 ifTrue:[ |
|
15433 l := l , (subList asOrderedCollection reverse). |
|
15434 l := l , (OrderedCollection with:'---- ' , aClass name , ' ---------'). |
|
15435 ] |
|
15436 ] |
|
15437 ]. |
|
15438 l reverse. |
|
15439 variableListView setAttributes:nil. |
|
15440 variableListView list:l. |
|
15441 l keysAndValuesDo:[:index :entry | |
|
15442 (entry startsWith:'---') ifTrue:[ |
|
15443 variableListView attributeAt:index put:#disabled. |
|
15444 last := index |
|
15445 ] |
|
15446 ]. |
|
15447 last notNil ifTrue:[variableListView scrollToLine:last]. |
|
15448 |
|
15449 oldSelection notNil ifTrue:[ |
|
15450 variableListView selectElement:oldSelection. |
|
15451 self hilightMethodsInMethodCategoryList:true inMethodList:true. |
|
15452 ] |
|
15453 !! !! |
|
15454 |
|
15455 !!BrowserView class methodsFor:'documentation'!! |
|
15456 |
|
15457 version |
|
15458 ^ '$Header: /cvs/stx/stx/libtool/BrowserView.st,v 1.58 1995-12-07 12:26:14 cg Exp $'!! !! |
|
15459 BrowserView initialize!! |
|
15460 ! |
|
15461 |
|
15462 classPrintOut |
|
15463 self classPrintOutWith:#printOutOn: |
|
15464 ! |
|
15465 |
|
15466 classPrintOutFullProtocol |
|
15467 self classPrintOutWith:#printOutFullProtocolOn: |
|
15468 ! |
|
15469 |
|
15470 classPrintOutProtocol |
|
15471 self classPrintOutWith:#printOutProtocolOn: |
|
15472 ! |
|
15473 |
|
15474 classPrintOutWith:aSelector |
|
15475 self doClassMenu:[:currentClass | |
|
15476 |printStream| |
|
15477 |
|
15478 printStream := Printer new. |
|
15479 currentClass perform:aSelector with:printStream. |
|
15480 printStream close |
|
15481 ] |
|
15482 ! |
|
15483 |
|
15484 classProtocols |
|
15485 ^ self |
|
15486 ! |
|
15487 |
|
15488 classRefs |
|
15489 self doClassMenu:[:currentClass | |
|
15490 self withSearchCursorDo:[ |
|
15491 SystemBrowser browseReferendsOf:currentClass name asSymbol |
|
15492 ] |
|
15493 ] |
|
15494 |
|
15495 "Created: 23.11.1995 / 14:11:43 / cg" |
|
15496 ! |
|
15497 |
|
15498 classRemove |
|
15499 "user requested remove of current class and all subclasses - |
|
15500 count subclasses and let user confirm removal." |
|
15501 |
|
15502 |count t box| |
|
15503 |
|
15504 currentClass notNil ifTrue:[ |
|
15505 count := currentClass allSubclasses size. |
|
15506 t := 'remove %1'. |
|
15507 count ~~ 0 ifTrue:[ |
|
15508 t := t , '\(with %2 subclass'. |
|
15509 count ~~ 1 ifTrue:[ |
|
15510 t := t , 'es' |
|
15511 ]. |
|
15512 t := (t , ')') |
|
15513 ]. |
|
15514 t := t , ' ?'. |
|
15515 t := (resources string:t with:currentClass name with:count) withCRs. |
|
15516 |
|
15517 box := YesNoBox |
|
15518 title:t |
|
15519 yesText:(resources at:'remove') |
|
15520 noText:(resources at:'abort'). |
|
15521 box confirm ifTrue:[ |
|
15522 "after querying user - do really remove current class |
|
15523 and all subclasses |
|
15524 " |
|
15525 self doClassMenu:[:currentClass | |
|
15526 |didRemove| |
|
15527 |
|
15528 didRemove := false. |
|
15529 |
|
15530 " |
|
15531 query ? |
|
15532 " |
|
15533 currentClass allSubclassesDo:[:aSubClass | |
|
15534 (CheckForInstancesWhenRemovingClasses not |
|
15535 or:[aSubClass hasInstances not |
|
15536 or:[self confirm:(aSubClass name , ' has instances - remove anyway ?')]]) |
|
15537 ifTrue:[ |
|
15538 Smalltalk removeClass:aSubClass |
|
15539 ] |
|
15540 ]. |
|
15541 (CheckForInstancesWhenRemovingClasses not |
|
15542 or:[currentClass hasInstances not |
|
15543 or:[self confirm:(currentClass name , ' has instances - remove anyway ?')]]) |
|
15544 ifTrue:[ |
|
15545 didRemove := true. |
|
15546 Smalltalk removeClass:currentClass. |
|
15547 ]. |
|
15548 |
|
15549 self switchToClass:nil. |
|
15550 Smalltalk changed. |
|
15551 self updateClassList. |
|
15552 |
|
15553 "if it was the last in its category, update class category list" |
|
15554 " |
|
15555 classListView numberOfLines == 0 ifTrue:[ |
|
15556 self updateClassCategoryListWithScroll:false |
|
15557 ]. |
|
15558 " |
|
15559 didRemove ifTrue:[ |
|
15560 methodCategoryListView notNil ifTrue:[methodCategoryListView contents:nil]. |
|
15561 methodListView notNil ifTrue:[methodListView contents:nil]. |
|
15562 codeView contents:nil. |
|
15563 codeView modified:false |
|
15564 ] |
|
15565 ] |
|
15566 ] |
|
15567 ] |
|
15568 ! |
|
15569 |
|
15570 classRename |
|
15571 "launch an enterBox for new name and query user" |
|
15572 |
|
15573 |box| |
|
15574 |
|
15575 self checkClassSelected ifFalse:[^ self]. |
|
15576 box := self enterBoxTitle:(resources string:'rename %1 to:' with:currentClass name) okText:'rename'. |
|
15577 box initialText:(currentClass name). |
|
15578 box action:[:aString | self renameCurrentClassTo:aString]. |
|
15579 box showAtPointer |
|
15580 ! |
|
15581 |
|
15582 classShowFrom:getSelector set:setSelector aspect:aspectSymbol default:default |
|
15583 "common helper for comment, primitive-stuff etc. |
|
15584 show the string returned from the classes getSelector-method, |
|
15585 Set acceptaction to change it via setSelector." |
|
15586 |
|
15587 self doClassMenu:[:currentClass | |
|
15588 |text| |
|
15589 |
|
15590 text := currentClass perform:getSelector. |
|
15591 text isNil ifTrue:[ |
|
15592 text := default |
|
15593 ]. |
|
15594 codeView contents:text. |
|
15595 codeView modified:false. |
|
15596 codeView acceptAction:[:theCode | |
|
15597 Object abortSignal catch:[ |
|
15598 lockUpdates := true. |
|
15599 currentClass perform:setSelector with:theCode asString. |
|
15600 codeView modified:false. |
|
15601 ]. |
|
15602 lockUpdates := false. |
|
15603 ]. |
|
15604 codeView explainAction:nil. |
|
15605 |
|
15606 methodListView notNil ifTrue:[ |
|
15607 methodListView deselect |
|
15608 ]. |
|
15609 aspect := aspectSymbol. |
|
15610 self normalLabel |
|
15611 ] |
|
15612 ! |
|
15613 |
|
15614 classSpawn |
|
15615 "create a new SystemBrowser browsing current class, |
|
15616 or if there is a selection, spawn a browser on the selected class |
|
15617 even a class/selector pair can be specified." |
|
15618 |
|
15619 self doClassMenuWithSelection:[:cls :sel | |
|
15620 |browser| |
|
15621 |
|
15622 cls isMeta ifTrue:[ |
|
15623 Smalltalk allBehaviorsDo:[:aClass | |
|
15624 aClass class == cls ifTrue:[ |
|
15625 browser := SystemBrowser browseClass:aClass. |
|
15626 browser instanceProtocol:false. |
|
15627 sel notNil ifTrue:[ |
|
15628 browser switchToMethodNamed:sel |
|
15629 ]. |
|
15630 ^ self |
|
15631 ]. |
|
15632 ]. |
|
15633 self warn:'oops, no class for this metaclass'. |
|
15634 ^ self |
|
15635 ]. |
|
15636 browser := SystemBrowser browseClass:cls. |
|
15637 cls hasMethods ifFalse:[ |
|
15638 browser instanceProtocol:false. |
|
15639 ]. |
|
15640 sel notNil ifTrue:[ |
|
15641 browser switchToMethodNamed:sel |
|
15642 ]. |
|
15643 ] |
|
15644 |
|
15645 " |
|
15646 select 'Smalltalk allClassesDo:' and use spawn from the class menu |
|
15647 select 'Smalltalk' and use spawn from the class menu |
|
15648 " |
|
15649 ! |
|
15650 |
|
15651 classSpawnFullProtocol |
|
15652 "create a new browser, browsing current classes full protocol" |
|
15653 |
|
15654 self doClassMenuWithSelection:[:cls :sel | |
|
15655 SystemBrowser browseFullClassProtocol:cls |
|
15656 ] |
|
15657 ! |
|
15658 |
|
15659 classSpawnHierarchy |
|
15660 "create a new HierarchyBrowser browsing current class" |
|
15661 |
|
15662 self doClassMenuWithSelection:[:cls :sel | |
|
15663 SystemBrowser browseClassHierarchy:cls |
|
15664 ] |
|
15665 ! |
|
15666 |
|
15667 classSpawnSubclasses |
|
15668 "create a new browser browsing current class's subclasses" |
|
15669 |
|
15670 self doClassMenuWithSelection:[:cls :sel | |
|
15671 |subs| |
|
15672 |
|
15673 subs := cls allSubclasses. |
|
15674 (subs notNil and:[subs size ~~ 0]) ifTrue:[ |
|
15675 SystemBrowser browseClasses:subs title:('subclasses of ' , cls name) |
|
15676 ] |
|
15677 ] |
|
15678 ! |
|
15679 |
|
15680 classUnload |
|
15681 "unload an autoloaded class" |
|
15682 |
|
15683 |nm| |
|
15684 |
|
15685 self checkClassSelected ifFalse:[^ self]. |
|
15686 nm := currentClass name. |
|
15687 currentClass unload. |
|
15688 self switchToClassNamed:nm |
|
15689 ! |
|
15690 |
|
15691 classUses |
|
15692 "a powerful tool, when trying to learn more about where |
|
15693 a class is used. This one searches all uses of a class, |
|
15694 and shows a list of uses - try it and like it" |
|
15695 |
|
15696 self doClassMenu:[:currentClass | |
|
15697 self withSearchCursorDo:[ |
|
15698 SystemBrowser browseUsesOf:currentClass |
|
15699 ] |
|
15700 ] |
|
15701 |
|
15702 "Created: 23.11.1995 / 14:11:47 / cg" |
|
15703 ! |
|
15704 |
|
15705 doClassMenuWithSelection:aBlock |
|
15706 "a helper - if there is a selection, which represents a classes name, |
|
15707 evaluate aBlock, passing that class and optional selector as arguments. |
|
15708 Otherwise, check if a class is selected and evaluate aBlock with the |
|
15709 current class." |
|
15710 |
|
15711 |string words clsName cls sel isMeta| |
|
15712 |
|
15713 string := codeView selection. |
|
15714 string notNil ifTrue:[ |
|
15715 self extractClassAndSelectorFromSelectionInto:[:c :s :m | |
|
15716 clsName := c. |
|
15717 sel := s. |
|
15718 isMeta := m. |
|
15719 ]. |
|
15720 clsName isNil ifTrue:[ |
|
15721 string := string asString withoutSeparators. |
|
15722 words := string asCollectionOfWords. |
|
15723 words notNil ifTrue:[ |
|
15724 clsName := words first. |
|
15725 (clsName endsWith:'class') ifTrue:[ |
|
15726 isMeta := true. |
|
15727 clsName := clsName copyWithoutLast:5 "copyTo:(clsName size - 5)" |
|
15728 ] ifFalse:[ |
|
15729 isMeta := false |
|
15730 ]. |
|
15731 sel := Parser selectorInExpression:string. |
|
15732 ] |
|
15733 ]. |
|
15734 clsName notNil ifTrue:[ |
|
15735 (cls := Smalltalk classNamed:clsName) notNil ifTrue:[ |
|
15736 isMeta ifTrue:[ |
|
15737 cls := cls class |
|
15738 ]. |
|
15739 self withWaitCursorDo:[ |
|
15740 aBlock value:cls value:sel. |
|
15741 ]. |
|
15742 ^ self |
|
15743 ] ifFalse:[ |
|
15744 self warn:'no class named: %1 - spawning current' with:clsName |
|
15745 ] |
|
15746 ]. |
|
15747 ]. |
|
15748 |
|
15749 classMethodListView notNil ifTrue:[ |
|
15750 sel := classMethodListView selectionValue. |
|
15751 sel notNil ifTrue:[ |
|
15752 sel := self selectorFromClassMethodString:sel |
|
15753 ] |
|
15754 ]. |
|
15755 self doClassMenu:[:currentClass | aBlock value:currentClass value:sel] |
6013 ! ! |
15756 ! ! |
6014 |
15757 |
|
15758 !BrowserView methodsFor:'class list source administration'! |
|
15759 |
|
15760 classCheckin |
|
15761 "check a class into the source repository" |
|
15762 |
|
15763 self doClassMenu:[:currentClass | |
|
15764 |logMessage info mgr| |
|
15765 |
|
15766 mgr := (currentClass sourceCodeManager). |
|
15767 (info := mgr sourceInfoOfClass:currentClass) isNil ifTrue:[ |
|
15768 ^ self classCreateSourceContainerFor:currentClass |
|
15769 ]. |
|
15770 |
|
15771 logMessage := Dialog |
|
15772 request:'enter a log message:' |
|
15773 initialAnswer:lastSourceLogMessage |
|
15774 onCancel:nil. |
|
15775 |
|
15776 logMessage notNil ifTrue:[ |
|
15777 lastSourceLogMessage := logMessage. |
|
15778 self busyLabel:'checking in %1' with:currentClass name. |
|
15779 (mgr checkinClass:currentClass logMessage:logMessage) ifFalse:[ |
|
15780 self warn:'checkin failed'. |
|
15781 ]. |
|
15782 aspect == #revisionInfo ifTrue:[ |
|
15783 self classListUpdate |
|
15784 ]. |
|
15785 self normalLabel. |
|
15786 ] |
|
15787 ] |
|
15788 |
|
15789 "Created: 23.11.1995 / 11:41:38 / cg" |
|
15790 "Modified: 7.12.1995 / 13:17:43 / cg" |
|
15791 ! |
|
15792 |
|
15793 classCompareWithNewestInRepository |
|
15794 "open a diff-textView comparing the current (in-image) version |
|
15795 with the most recent version found in the repository." |
|
15796 |
|
15797 self doClassMenu:[:currentClass | |
|
15798 |aStream comparedSource currentSource v rev revString mgr| |
|
15799 |
|
15800 mgr := currentClass sourceCodeManager. |
|
15801 |
|
15802 rev := Dialog request:'compare to revision: (empty for newest)'. |
|
15803 rev notNil ifTrue:[ |
|
15804 rev withoutSpaces isEmpty ifTrue:[ |
|
15805 self busyLabel:'extracting newest %1' with:currentClass name. |
|
15806 aStream := mgr mostRecentSourceStreamForClassNamed:currentClass name. |
|
15807 revString := 'newest' |
|
15808 ] ifFalse:[ |
|
15809 self busyLabel:'extracting previous %1' with:currentClass name. |
|
15810 aStream := mgr sourceStreamFor:currentClass revision:rev. |
|
15811 revString := rev |
|
15812 ]. |
|
15813 comparedSource := aStream contents. |
|
15814 aStream close. |
|
15815 |
|
15816 self busyLabel:'generating current source ...' with:nil. |
|
15817 |
|
15818 aStream := '' writeStream. |
|
15819 currentClass fileOutOn:aStream withTimeStamp:false. |
|
15820 currentSource := aStream contents. |
|
15821 aStream close. |
|
15822 |
|
15823 self busyLabel:'comparing ...' with:nil. |
|
15824 v := DiffTextView |
|
15825 openOn:currentSource label:'current (' , currentClass revision , ')' |
|
15826 and:comparedSource label:'repository (' , revString , ')'. |
|
15827 v label:'comparing ' , currentClass name. |
|
15828 self normalLabel. |
|
15829 ] |
|
15830 ] |
|
15831 |
|
15832 "Created: 14.11.1995 / 16:43:15 / cg" |
|
15833 "Modified: 7.12.1995 / 13:18:12 / cg" |
|
15834 ! |
|
15835 |
|
15836 classCreateSourceContainerFor:aClass |
|
15837 "let user specify the source-repository values for aClass" |
|
15838 |
|
15839 |box |
|
15840 moduleDirectory subDirectory |
|
15841 fileName specialFlags |
|
15842 check y component info fn project| |
|
15843 |
|
15844 moduleDirectory := 'stx' asValue. |
|
15845 subDirectory := '' asValue. |
|
15846 |
|
15847 (Project notNil and:[(project := Project current) notNil]) ifTrue:[ |
|
15848 subDirectory value:(project name) |
|
15849 ]. |
|
15850 |
|
15851 info := (aClass sourceCodeManager) sourceInfoOfClass:aClass. |
|
15852 info notNil ifTrue:[ |
|
15853 (info includesKey:#module) ifTrue:[ |
|
15854 moduleDirectory value:(info at:#module). |
|
15855 ]. |
|
15856 (info includesKey:#directory) ifTrue:[ |
|
15857 subDirectory value:(info at:#directory). |
|
15858 ]. |
|
15859 (info includesKey:#expectedFileName) ifTrue:[ |
|
15860 fn := (info at:#expectedFileName). |
|
15861 ] ifFalse:[ |
|
15862 (info includesKey:#classFileName) ifTrue:[ |
|
15863 fn := (info at:#classFileName). |
|
15864 ] |
|
15865 ] |
|
15866 ]. |
|
15867 |
|
15868 fn isNil ifTrue:[ |
|
15869 fn := (Smalltalk fileNameForClass:aClass) , '.st'. |
|
15870 ]. |
|
15871 "/ |
|
15872 "/ should check for conflicts ... |
|
15873 "/ |
|
15874 |
|
15875 fileName := fn asValue. |
|
15876 |
|
15877 box := DialogBox new. |
|
15878 box label:(resources string:'Repository information for %1' with:aClass name). |
|
15879 |
|
15880 component := box addTextLabel:(resources string:'CREATE_REPOSITORY' with:currentClass name) withCRs. |
|
15881 component adjust:#left; borderWidth:0. |
|
15882 |
|
15883 y := box yPosition. |
|
15884 component := box addTextLabel:(resources string:'Module:'). |
|
15885 component width:0.5; adjust:#right. |
|
15886 box yPosition:y. |
|
15887 component := box addInputFieldOn:moduleDirectory tabable:true. |
|
15888 component width:0.5; left:0.5; immediateAccept:true; acceptOnLeave:false; cursorMovementWhenUpdating:#beginOfLine. |
|
15889 |
|
15890 box addVerticalSpace. |
|
15891 y := box yPosition. |
|
15892 component := box addTextLabel:'Package:'. |
|
15893 component width:0.5; adjust:#right. |
|
15894 box yPosition:y. |
|
15895 component := box addInputFieldOn:subDirectory tabable:true. |
|
15896 component width:0.5; left:0.5; immediateAccept:true; acceptOnLeave:false; cursorMovementWhenUpdating:#beginOfLine. |
|
15897 |
|
15898 box addVerticalSpace. |
|
15899 y := box yPosition. |
|
15900 component := box addTextLabel:'Filename:'. |
|
15901 component width:0.5; adjust:#right. |
|
15902 box yPosition:y. |
|
15903 component := box addInputFieldOn:fileName tabable:true. |
|
15904 component width:0.5; left:0.5; immediateAccept:true; acceptOnLeave:false; cursorMovementWhenUpdating:#beginOfLine. |
|
15905 |
|
15906 box addVerticalSpace. |
|
15907 box addVerticalSpace. |
|
15908 |
|
15909 box addAbortButton; addOkButton. |
|
15910 |
|
15911 box showAtPointer. |
|
15912 |
|
15913 box accepted ifTrue:[ |
|
15914 self halt. |
|
15915 ] |
|
15916 |
|
15917 "Modified: 7.12.1995 / 13:18:37 / cg" |
|
15918 ! |
|
15919 |
|
15920 classLoadRevision |
|
15921 "load a specific revision into the system - especially useful to |
|
15922 upgrade a class to the newest revision" |
|
15923 |
|
15924 self doClassMenu:[:currentClass | |
|
15925 |aStream comparedSource currentSource v rev revString what mgr| |
|
15926 |
|
15927 mgr := currentClass sourceCodeManager. |
|
15928 |
|
15929 rev := Dialog request:'load which revision: (empty for newest)'. |
|
15930 rev notNil ifTrue:[ |
|
15931 rev withoutSpaces isEmpty ifTrue:[ |
|
15932 what := currentClass name , '(newest)'. |
|
15933 self busyLabel:'extracting %1' with:what. |
|
15934 aStream := mgr mostRecentSourceStreamForClassNamed:currentClass name. |
|
15935 revString := 'newest' |
|
15936 ] ifFalse:[ |
|
15937 what := currentClass name , '(' , rev , ')'. |
|
15938 self busyLabel:'extracting %1' with:what. |
|
15939 aStream := mgr sourceStreamFor:currentClass revision:rev. |
|
15940 revString := rev |
|
15941 ]. |
|
15942 self busyLabel:'loading %1' with:what . |
|
15943 |
|
15944 [ |
|
15945 Class withoutUpdatingChangesDo:[ |
|
15946 "/ rename the current class - for backup |
|
15947 Smalltalk renameClass:currentClass to:currentClass name , '_saved'. |
|
15948 aStream fileIn. |
|
15949 ]. |
|
15950 ] valueNowOrOnUnwindDo:[ |
|
15951 aStream close. |
|
15952 self normalLabel. |
|
15953 ]. |
|
15954 ] |
|
15955 ] |
|
15956 |
|
15957 "Created: 14.11.1995 / 16:43:15 / cg" |
|
15958 "Modified: 7.12.1995 / 13:19:06 / cg" |
|
15959 ! |
|
15960 |
|
15961 classRevisionInfo |
|
15962 "show current classes revision info in codeView" |
|
15963 |
|
15964 self doClassMenu:[:currentClass | |
|
15965 |aStream info info2 s rv mgr| |
|
15966 |
|
15967 aStream := WriteStream on:(String new:200). |
|
15968 currentClass notNil ifTrue:[ |
|
15969 self busyLabel:'extracting revision info' with:nil. |
|
15970 info := currentClass revisionInfo. |
|
15971 |
|
15972 rv := currentClass binaryRevision. |
|
15973 rv notNil ifTrue:[ |
|
15974 aStream nextPutAll:'**** Loaded classes binary information ****'; cr; cr. |
|
15975 aStream nextPutAll:' Binary based upon : ' , rv; cr. |
|
15976 aStream cr. |
|
15977 ]. |
|
15978 |
|
15979 info notNil ifTrue:[ |
|
15980 aStream nextPutAll:'**** Classes source information ****'; cr; cr. |
|
15981 s := info at:#repositoryPath ifAbsent:nil. |
|
15982 s notNil ifTrue:[ |
|
15983 aStream nextPut:' Source repository : ' , s; cr |
|
15984 ]. |
|
15985 aStream nextPutAll:' Filename ........ : ' , (info at:#fileName ifAbsent:'?'); cr. |
|
15986 aStream nextPutAll:' Revision ........ : ' , (info at:#revision ifAbsent:'?'); cr. |
|
15987 aStream nextPutAll:' Checkin date .... : ' , (info at:#date ifAbsent:'?') , ' ' , (info at:#time ifAbsent:'?'); cr. |
|
15988 aStream nextPutAll:' Checkin user .... : ' , (info at:#user ifAbsent:'?'); cr. |
|
15989 |
|
15990 (info2 := currentClass packageSourceCodeInfo) notNil ifTrue:[ |
|
15991 aStream nextPutAll:' Repository: ..... : ' , (info2 at:#module ifAbsent:'?'); cr. |
|
15992 aStream nextPutAll:' Directory: ...... : ' , (info2 at:#directory ifAbsent:'?'); cr. |
|
15993 ]. |
|
15994 aStream nextPutAll:' Container ....... : ' , (info at:#repositoryPathName ifAbsent:'?'); cr. |
|
15995 aStream cr. |
|
15996 |
|
15997 (mgr := currentClass sourceCodeManager) notNil ifTrue:[ |
|
15998 aStream nextPutAll:'**** Repository information ****'; cr; cr. |
|
15999 mgr writeRevisionLogOf:currentClass to:aStream. |
|
16000 ] |
|
16001 ] ifFalse:[ |
|
16002 aStream nextPutAll:'No revision info found' |
|
16003 ] |
|
16004 ]. |
|
16005 codeView contents:(aStream contents). |
|
16006 |
|
16007 codeView modified:false. |
|
16008 codeView acceptAction:nil. |
|
16009 codeView explainAction:nil. |
|
16010 methodListView notNil ifTrue:[ |
|
16011 methodListView deselect |
|
16012 ]. |
|
16013 aspect := #revisionInfo. |
|
16014 self normalLabel |
|
16015 ] |
|
16016 |
|
16017 "Created: 14.11.1995 / 16:43:15 / cg" |
|
16018 "Modified: 7.12.1995 / 13:20:42 / cg" |
|
16019 ! ! |
|
16020 |
|
16021 !BrowserView methodsFor:'class stuff'! |
|
16022 |
|
16023 checkClassSelected |
|
16024 "warn and return false, if no class is selected" |
|
16025 |
|
16026 currentClass isNil ifTrue:[ |
|
16027 self warn:'select a class first'. |
|
16028 ^ false |
|
16029 ]. |
|
16030 ^ true |
|
16031 ! |
|
16032 |
|
16033 classClassDefinitionTemplateFor:name in:cat |
|
16034 "common helper for newClass and newSubclass |
|
16035 - show a template to define class name in category cat. |
|
16036 Also, set acceptaction to install the class." |
|
16037 |
|
16038 currentMethodCategory := nil. |
|
16039 currentMethod := currentSelector := nil. |
|
16040 |
|
16041 classListView deselect. |
|
16042 |
|
16043 fullClass ifFalse:[ |
|
16044 methodCategoryListView contents:nil. |
|
16045 methodListView contents:nil |
|
16046 ]. |
|
16047 |
|
16048 codeView contents:(self templateFor:name in:cat). |
|
16049 codeView modified:false. |
|
16050 |
|
16051 codeView acceptAction:[:theCode | |
|
16052 codeView cursor:Cursor execute. |
|
16053 Object abortSignal catch:[ |
|
16054 |cls| |
|
16055 |
|
16056 cls := (Compiler evaluate:theCode asString notifying:codeView compile:false). |
|
16057 cls isBehavior ifTrue:[ |
|
16058 codeView modified:false. |
|
16059 self classCategoryUpdate. |
|
16060 self updateClassListWithScroll:false. |
|
16061 self switchToClassNamed:(cls name). |
|
16062 ] |
|
16063 ]. |
|
16064 codeView cursor:(Cursor normal). |
|
16065 ]. |
|
16066 codeView explainAction:nil. |
|
16067 self switchToClass:nil |
|
16068 ! |
|
16069 |
|
16070 classListUpdate |
|
16071 RememberAspect ifTrue:[ |
|
16072 aspect == #hierarchy ifTrue:[ |
|
16073 ^ self classHierarchy |
|
16074 ]. |
|
16075 aspect == #classInstVars ifTrue:[ |
|
16076 ^ self classClassInstVars |
|
16077 ]. |
|
16078 aspect == #comment ifTrue:[ |
|
16079 ^ self classComment |
|
16080 ]. |
|
16081 aspect == #primitiveDefinitions ifTrue:[ |
|
16082 ^ self classPrimitiveDefinitions |
|
16083 ]. |
|
16084 aspect == #primitiveFunctions ifTrue:[ |
|
16085 ^ self classPrimitiveFunctions |
|
16086 ]. |
|
16087 aspect == #primitiveVariables ifTrue:[ |
|
16088 ^ self classPrimitiveVariables |
|
16089 ]. |
|
16090 aspect == #revisionInfo ifTrue:[ |
|
16091 ^ self classRevisionInfo |
|
16092 ]. |
|
16093 ]. |
|
16094 self classDefinition |
|
16095 |
|
16096 "Created: 23.11.1995 / 11:28:58 / cg" |
|
16097 "Modified: 23.11.1995 / 11:36:08 / cg" |
|
16098 ! |
|
16099 |
|
16100 classSelection:lineNr |
|
16101 "user clicked on a class line - show method categories" |
|
16102 |
|
16103 |cls oldSelector| |
|
16104 |
|
16105 (currentClassHierarchy notNil |
|
16106 and:[fullProtocol]) ifTrue:[ |
|
16107 oldSelector := currentSelector. |
|
16108 |
|
16109 self updateMethodCategoryListWithScroll:false. |
|
16110 self updateMethodListWithScroll:false. |
|
16111 self updateVariableList. |
|
16112 ^ self |
|
16113 ]. |
|
16114 |
|
16115 cls := Smalltalk classNamed:classListView selectionValue withoutSpaces. |
|
16116 cls notNil ifTrue:[ |
|
16117 self switchToClass:cls. |
|
16118 self classSelectionChanged |
|
16119 ] |
|
16120 ! |
|
16121 |
|
16122 classSelectionChanged |
|
16123 |oldMethodCategory oldMethod oldSelector| |
|
16124 |
|
16125 self withWaitCursorDo:[ |
|
16126 oldMethodCategory := currentMethodCategory. |
|
16127 oldMethod := currentMethod. |
|
16128 oldSelector := currentSelector. |
|
16129 |
|
16130 showInstance ifTrue:[ |
|
16131 actualClass := acceptClass := currentClass |
|
16132 ] ifFalse:[ |
|
16133 actualClass := acceptClass := currentClass class |
|
16134 ]. |
|
16135 currentMethodCategory := nil. |
|
16136 currentMethod := nil. |
|
16137 currentSelector := nil. |
|
16138 |
|
16139 self updateVariableList. |
|
16140 self updateMethodCategoryList. |
|
16141 |
|
16142 oldMethodCategory notNil ifTrue:[ |
|
16143 methodCategoryListView selectElement:oldMethodCategory. |
|
16144 methodCategoryListView hasSelection ifTrue:[ |
|
16145 currentMethodCategory := oldMethodCategory. |
|
16146 self methodCategorySelectionChanged |
|
16147 ] |
|
16148 ]. |
|
16149 self updateMethodList. |
|
16150 self updateCodeView. |
|
16151 |
|
16152 fullClass ifTrue:[ |
|
16153 codeView acceptAction:[:theCode | |
|
16154 codeView cursor:Cursor execute. |
|
16155 Object abortSignal catch:[ |
|
16156 self compileCode:theCode asString. |
|
16157 codeView modified:false. |
|
16158 ]. |
|
16159 codeView cursor:Cursor normal. |
|
16160 ]. |
|
16161 ] ifFalse:[ |
|
16162 "/ self classDefinition. |
|
16163 self classListUpdate. |
|
16164 codeView acceptAction:[:theCode | |
|
16165 codeView cursor:Cursor execute. |
|
16166 Object abortSignal catch:[ |
|
16167 (Compiler evaluate:theCode asString notifying:codeView compile:false) |
|
16168 isBehavior ifTrue:[ |
|
16169 self classCategoryUpdate. |
|
16170 self updateClassListWithScroll:false. |
|
16171 codeView modified:false. |
|
16172 ]. |
|
16173 ]. |
|
16174 codeView cursor:Cursor normal. |
|
16175 ]. |
|
16176 ]. |
|
16177 codeView explainAction:nil. |
|
16178 |
|
16179 classCategoryListView notNil ifTrue:[ |
|
16180 (currentClassCategory = currentClass category) ifFalse:[ |
|
16181 currentClassCategory := currentClass category. |
|
16182 classCategoryListView selectElement:currentClassCategory |
|
16183 ] |
|
16184 ]. |
|
16185 |
|
16186 self setDoitActionForClass |
|
16187 ] |
|
16188 |
|
16189 "Created: 23.11.1995 / 11:32:03 / cg" |
|
16190 ! |
|
16191 |
|
16192 doClassMenu:aBlock |
|
16193 "a helper - check if class is selected and evaluate aBlock |
|
16194 while showing waitCursor" |
|
16195 |
|
16196 self checkClassSelected ifTrue:[ |
|
16197 self withWaitCursorDo:[aBlock value:currentClass] |
|
16198 ] |
|
16199 ! |
|
16200 |
|
16201 listOfAllClassesInCategory:aCategory |
|
16202 "return a list of all classes in a given category" |
|
16203 |
|
16204 |newList classes searchCategory nm| |
|
16205 |
|
16206 (aCategory = '* hierarchy *') ifTrue:[ |
|
16207 newList := OrderedCollection new. |
|
16208 classes := Set new. |
|
16209 self classHierarchyDo:[:aClass :lvl| |
|
16210 nm := aClass name. |
|
16211 (classes includes:nm) ifFalse:[ |
|
16212 classes add:nm. |
|
16213 newList add:(String new:lvl) , nm |
|
16214 ] |
|
16215 ]. |
|
16216 ^ newList |
|
16217 ]. |
|
16218 |
|
16219 newList := Set new. |
|
16220 |
|
16221 (aCategory = '* all *') ifTrue:[ |
|
16222 Smalltalk allBehaviorsDo:[:aClass | |
|
16223 newList add:aClass name |
|
16224 ] |
|
16225 ] ifFalse:[ |
|
16226 (aCategory = '* no category *') ifTrue:[ |
|
16227 searchCategory := nil |
|
16228 ] ifFalse:[ |
|
16229 searchCategory := aCategory |
|
16230 ]. |
|
16231 Smalltalk allBehaviorsDo:[:aClass | |
|
16232 |thisCategory| |
|
16233 |
|
16234 aClass isMeta ifFalse:[ |
|
16235 thisCategory := aClass category. |
|
16236 ((thisCategory = searchCategory) |
|
16237 or:[thisCategory = aCategory]) ifTrue:[ |
|
16238 newList add:aClass name |
|
16239 ] |
|
16240 ] |
|
16241 ] |
|
16242 ]. |
|
16243 (newList size == 0) ifTrue:[^ nil]. |
|
16244 ^ newList asOrderedCollection sort |
|
16245 ! |
|
16246 |
|
16247 listOfClassHierarchyOf:aClass |
|
16248 "return a hierarchy class-list" |
|
16249 |
|
16250 |startClass classes thisOne| |
|
16251 |
|
16252 showInstance ifTrue:[ |
|
16253 startClass := aClass |
|
16254 ] ifFalse:[ |
|
16255 startClass := aClass class. |
|
16256 ]. |
|
16257 classes := startClass allSuperclasses. |
|
16258 thisOne := Array with:startClass. |
|
16259 |
|
16260 classes notNil ifTrue:[ |
|
16261 classes := classes reverse , thisOne. |
|
16262 ] ifFalse:[ |
|
16263 classes := thisOne |
|
16264 ]. |
|
16265 |
|
16266 fullProtocol ifFalse:[ |
|
16267 classes := classes , startClass allSubclassesInOrder |
|
16268 ]. |
|
16269 ^ classes collect:[:c | c name] |
|
16270 ! |
|
16271 |
|
16272 renameCurrentClassTo:aString |
|
16273 "helper - do the rename" |
|
16274 |
|
16275 self doClassMenu:[:currentClass | |
|
16276 |oldName oldSym newSym cls| |
|
16277 |
|
16278 (cls := Smalltalk classNamed:aString) notNil ifTrue:[ |
|
16279 (self confirm:(resources string:'WARN_RENAME' with:aString with:cls category)) |
|
16280 ifFalse:[^ self] |
|
16281 ]. |
|
16282 |
|
16283 oldName := currentClass name. |
|
16284 oldSym := oldName asSymbol. |
|
16285 " |
|
16286 currentClass setName:aString. |
|
16287 newSym := aString asSymbol. |
|
16288 Smalltalk at:oldSym put:nil. |
|
16289 Smalltalk removeKey:oldSym. |
|
16290 Smalltalk at:newSym put:currentClass. |
|
16291 " |
|
16292 " |
|
16293 currentClass renameTo:aString. |
|
16294 " |
|
16295 Smalltalk renameClass:currentClass to:aString. |
|
16296 |
|
16297 self updateClassList. |
|
16298 self updateMethodCategoryListWithScroll:false. |
|
16299 self updateMethodListWithScroll:false. |
|
16300 self withWaitCursorDo:[ |
|
16301 Transcript showCr:('searching for users of ' , oldSym); endEntry. |
|
16302 SystemBrowser browseReferendsOf:oldSym warnIfNone:false |
|
16303 ] |
|
16304 ] |
|
16305 |
|
16306 "Created: 25.11.1995 / 13:02:53 / cg" |
|
16307 ! |
|
16308 |
|
16309 switchToClass:newClass |
|
16310 "switch to some other class; |
|
16311 keep instance protocol as it was ..." |
|
16312 |
|
16313 |cls meta| |
|
16314 |
|
16315 fullProtocol ifTrue:[^ self]. |
|
16316 |
|
16317 cls := newClass. |
|
16318 (meta := cls isMeta) ifTrue:[ |
|
16319 cls := cls soleInstance |
|
16320 ]. |
|
16321 currentClass notNil ifTrue:[ |
|
16322 currentClass removeDependent:self |
|
16323 ]. |
|
16324 currentClass := cls. |
|
16325 showInstance ifTrue:[ |
|
16326 actualClass := acceptClass := cls. |
|
16327 ] ifFalse:[ |
|
16328 actualClass := acceptClass := cls class. |
|
16329 ]. |
|
16330 |
|
16331 currentClass notNil ifTrue:[ |
|
16332 currentClass addDependent:self. |
|
16333 ]. |
|
16334 self normalLabel. |
|
16335 |
|
16336 "Modified: 1.9.1995 / 01:04:05 / claus" |
|
16337 ! |
|
16338 |
|
16339 switchToClassNameMatching:aMatchString |
|
16340 |classNames thisName box| |
|
16341 |
|
16342 classNames := OrderedCollection new. |
|
16343 Smalltalk allBehaviorsDo:[:aClass | |
|
16344 thisName := aClass name. |
|
16345 (aMatchString match:thisName) ifTrue:[ |
|
16346 classNames add:thisName |
|
16347 ] |
|
16348 ]. |
|
16349 (classNames size == 0) ifTrue:[^ nil]. |
|
16350 (classNames size == 1) ifTrue:[ |
|
16351 ^ self switchToClassNamed:(classNames at:1) |
|
16352 ]. |
|
16353 |
|
16354 box := self listBoxTitle:'select class to switch to:' |
|
16355 okText:'ok' |
|
16356 list:classNames sort. |
|
16357 box action:[:aString | self switchToClassNamed:aString]. |
|
16358 box showAtPointer |
|
16359 ! |
|
16360 |
|
16361 switchToClassNamed:aString |
|
16362 |meta str classSymbol theClass newCat element| |
|
16363 |
|
16364 meta := false. |
|
16365 str := aString. |
|
16366 classSymbol := aString asSymbolIfInterned. |
|
16367 classSymbol isNil ifTrue:[ |
|
16368 (aString endsWith:'class') ifTrue:[ |
|
16369 str := aString copyWithoutLast:5. |
|
16370 classSymbol := str asSymbolIfInterned. |
|
16371 classSymbol isNil ifTrue:[ |
|
16372 ^ self |
|
16373 ]. |
|
16374 meta := true |
|
16375 ]. |
|
16376 ]. |
|
16377 |
|
16378 theClass := Smalltalk at:classSymbol. |
|
16379 (theClass isNil and:[str endsWith:'class']) ifTrue:[ |
|
16380 str := str copyWithoutLast:5. |
|
16381 classSymbol := str asSymbolIfInterned. |
|
16382 classSymbol isNil ifTrue:[ |
|
16383 ^ self |
|
16384 ]. |
|
16385 meta := true. |
|
16386 theClass := Smalltalk at:classSymbol. |
|
16387 ]. |
|
16388 |
|
16389 theClass == currentClass ifTrue:[^ self]. |
|
16390 |
|
16391 theClass isBehavior ifTrue:[ |
|
16392 classCategoryListView notNil ifTrue:[ |
|
16393 currentClassHierarchy isNil ifTrue:[ |
|
16394 ((newCat := theClass category) ~= currentClassCategory) ifTrue:[ |
|
16395 currentClassCategory := newCat. |
|
16396 newCat isNil ifTrue:[ |
|
16397 element := '* no category *' |
|
16398 ] ifFalse:[ |
|
16399 element := newCat. |
|
16400 ]. |
|
16401 classCategoryListView selectElement:element. |
|
16402 "/ classCategoryListView makeSelectionVisible. |
|
16403 ] |
|
16404 ] |
|
16405 ]. |
|
16406 self updateClassList. |
|
16407 self switchToClass:theClass. |
|
16408 |
|
16409 classListView selectElement:str. |
|
16410 self instanceProtocol:meta not. |
|
16411 self classSelectionChanged |
|
16412 ] |
|
16413 |
|
16414 "Modified: 1.9.1995 / 01:41:35 / claus" |
|
16415 ! |
|
16416 |
|
16417 templateFor:className in:cat |
|
16418 "return a class definition template - be smart in what is offered initially" |
|
16419 |
|
16420 |aString name i| |
|
16421 |
|
16422 name := 'NewClass'. |
|
16423 i := 1. |
|
16424 [name knownAsSymbol and:[Smalltalk includesKey:name asSymbol]] whileTrue:[ |
|
16425 i := i + 1. |
|
16426 name := 'NewClass' , i printString |
|
16427 ]. |
|
16428 |
|
16429 aString := className , ' subclass:#' , name , ' |
|
16430 instanceVariableNames: '''' |
|
16431 classVariableNames: '''' |
|
16432 poolDictionaries: '''' |
|
16433 category: '''. |
|
16434 |
|
16435 cat notNil ifTrue:[ |
|
16436 aString := aString , cat |
|
16437 ]. |
|
16438 aString := aString , ''' |
|
16439 |
|
16440 |
|
16441 |
|
16442 |
|
16443 |
|
16444 " |
|
16445 Replace ''' , className , ''', ''', name , ''' and |
|
16446 the empty string arguments by true values. |
|
16447 |
|
16448 Install (or change) the class by ''accepting'', |
|
16449 either via the menu or the keyboard (usually CMD-A). |
|
16450 |
|
16451 To be nice to others (and yourself later), do not forget to |
|
16452 add some documentation; either under the classes documentation |
|
16453 protocol, or as a class comment. |
|
16454 " |
|
16455 '. |
|
16456 ^ aString |
|
16457 ! |
|
16458 |
|
16459 updateClassList |
|
16460 self updateClassListWithScroll:true |
|
16461 ! |
|
16462 |
|
16463 updateClassListWithScroll:scroll |
|
16464 |classes oldClassName| |
|
16465 |
|
16466 classListView notNil ifTrue:[ |
|
16467 " |
|
16468 refetch in case we are not up to date |
|
16469 " |
|
16470 (currentClass notNil and:[fullProtocol not]) ifTrue:[ |
|
16471 oldClassName := currentClass name. |
|
16472 currentClass := Smalltalk at:(oldClassName asSymbol). |
|
16473 ]. |
|
16474 |
|
16475 currentClassCategory notNil ifTrue:[ |
|
16476 classes := self listOfAllClassesInCategory:currentClassCategory |
|
16477 ] ifFalse:[ |
|
16478 currentClassHierarchy notNil ifTrue:[ |
|
16479 classes := self listOfClassHierarchyOf:currentClassHierarchy |
|
16480 ] |
|
16481 ]. |
|
16482 |
|
16483 classListView list = classes ifFalse:[ |
|
16484 scroll ifTrue:[ |
|
16485 classListView contents:classes |
|
16486 ] ifFalse:[ |
|
16487 classListView setContents:classes |
|
16488 ]. |
|
16489 oldClassName notNil ifTrue:[ |
|
16490 classListView setContents:classes. |
|
16491 classListView selectElement:oldClassName |
|
16492 ] ifFalse:[ |
|
16493 variableListView notNil ifTrue:[variableListView contents:nil] |
|
16494 ] |
|
16495 ]. |
|
16496 scroll ifTrue:[ |
|
16497 fullProtocol ifTrue:[ |
|
16498 classListView scrollToBottom |
|
16499 ] |
|
16500 ] |
|
16501 ] |
|
16502 ! ! |
|
16503 |
|
16504 !BrowserView methodsFor:'class-method list menu'! |
|
16505 |
|
16506 classMethodFileOutAll |
|
16507 "fileout all methods into one source file" |
|
16508 |
|
16509 |list classString selectorString cls mth outStream fileName append |
|
16510 fileBox| |
|
16511 |
|
16512 append := false. |
|
16513 fileBox := FileSaveBox |
|
16514 title:(resources string:'save methodss in:') |
|
16515 okText:(resources string:'save') |
|
16516 abortText:(resources string:'cancel') |
|
16517 action:[:fName | fileName := fName]. |
|
16518 fileBox appendAction:[:fName | fileName := fName. append := true]. |
|
16519 fileBox initialText:'some_methods.st'. |
|
16520 Project notNil ifTrue:[ |
|
16521 fileBox directory:Project currentProjectDirectory |
|
16522 ]. |
|
16523 fileBox showAtPointer. |
|
16524 |
|
16525 fileName notNil ifTrue:[ |
|
16526 " |
|
16527 if file exists, save original in a .sav file |
|
16528 " |
|
16529 fileName asFilename exists ifTrue:[ |
|
16530 fileName asFilename copyTo:(fileName , '.sav') |
|
16531 ]. |
|
16532 append ifTrue:[ |
|
16533 outStream := FileStream appendingOldFileNamed:fileName |
|
16534 ] ifFalse:[ |
|
16535 outStream := FileStream newFileNamed:fileName. |
|
16536 ]. |
|
16537 outStream isNil ifTrue:[ |
|
16538 ^ self warn:'cannot create: %1' with:fileName |
|
16539 ]. |
|
16540 self withWaitCursorDo:[ |
|
16541 list := classMethodListView list. |
|
16542 list do:[:line | |
|
16543 self busyLabel:'writing: ' with:line. |
|
16544 |
|
16545 classString := self classFromClassMethodString:line. |
|
16546 selectorString := self selectorFromClassMethodString:line. |
|
16547 |
|
16548 ((classString ~= 'Metaclass') and:[classString endsWith:'class']) ifTrue:[ |
|
16549 classString := classString copyWithoutLast:5 "copyTo:(classString size - 5)". |
|
16550 cls := (Smalltalk at:classString asSymbol). |
|
16551 cls := cls class |
|
16552 ] ifFalse:[ |
|
16553 cls := (Smalltalk at:classString asSymbol). |
|
16554 ]. |
|
16555 |
|
16556 cls isNil ifTrue:[ |
|
16557 self warn:'oops class %1 is gone' with:classString |
|
16558 ] ifFalse:[ |
|
16559 mth := cls compiledMethodAt:(selectorString asSymbol). |
|
16560 Class fileOutErrorSignal handle:[:ex | |
|
16561 |box| |
|
16562 box := YesNoBox |
|
16563 title:('fileOut error: ' |
|
16564 , ex errorString |
|
16565 , '\\continue anyway ?') withCRs |
|
16566 yesText:'continue' |
|
16567 noText:'abort'. |
|
16568 box confirm ifTrue:[ |
|
16569 ex proceed |
|
16570 ]. |
|
16571 self normalLabel. |
|
16572 ^ self |
|
16573 ] do:[ |
|
16574 cls fileOutMethod:mth on:outStream. |
|
16575 ] |
|
16576 ] |
|
16577 ]. |
|
16578 outStream close. |
|
16579 self normalLabel. |
|
16580 ] |
|
16581 ] |
|
16582 ! |
|
16583 |
|
16584 classMethodMenu |
|
16585 |labels selectors| |
|
16586 |
|
16587 labels := #( |
|
16588 'fileOut' |
|
16589 'fileOut all' |
|
16590 'printOut' |
|
16591 '-' |
|
16592 'spawn' |
|
16593 'spawn class' |
|
16594 'spawn full protocol' |
|
16595 'spawn hierarchy' |
|
16596 '-' |
|
16597 'senders ...' |
|
16598 'implementors ...' |
|
16599 'globals ...' |
|
16600 "/ '-' |
|
16601 "/ 'breakpoint' |
|
16602 "/ 'trace' |
|
16603 "/ 'trace sender' |
|
16604 '-' |
|
16605 'remove' |
|
16606 ). |
|
16607 |
|
16608 selectors := #( |
|
16609 methodFileOut |
|
16610 classMethodFileOutAll |
|
16611 methodPrintOut |
|
16612 nil |
|
16613 methodSpawn |
|
16614 classSpawn |
|
16615 classSpawnFullProtocol |
|
16616 classSpawnHierarchy |
|
16617 nil |
|
16618 methodSenders |
|
16619 methodImplementors |
|
16620 methodGlobalReferends |
|
16621 "/ nil |
|
16622 "/ methodBreakPoint |
|
16623 "/ methodTrace |
|
16624 "/ methodTraceSender |
|
16625 nil |
|
16626 methodRemove |
|
16627 ). |
|
16628 |
|
16629 ^ PopUpMenu labels:(resources array:labels) |
|
16630 selectors:selectors |
|
16631 ! ! |
|
16632 |
|
16633 !BrowserView methodsFor:'class-method stuff'! |
|
16634 |
|
16635 classFromClassMethodString:aString |
|
16636 "helper for classMethod-list - extract class name from the string" |
|
16637 |
|
16638 "/ |pos| |
|
16639 "/ |
|
16640 "/ pos := aString indexOf:(Character space). |
|
16641 "/ ^ aString copyTo:(pos - 1) |
|
16642 |
|
16643 ^ aString upTo:Character space |
|
16644 ! |
|
16645 |
|
16646 classMethodSelection:lineNr |
|
16647 "user clicked on a class/method line - show code" |
|
16648 |
|
16649 |cls string classString selectorString meta| |
|
16650 |
|
16651 string := classMethodListView selectionValue. |
|
16652 classString := self classFromClassMethodString:string. |
|
16653 selectorString := self selectorFromClassMethodString:string. |
|
16654 ((classString ~= 'Metaclass') and:[classString endsWith:'class']) ifTrue:[ |
|
16655 classString := classString copyWithoutLast:5 "copyTo:(classString size - 5)". |
|
16656 meta := true. |
|
16657 ] ifFalse:[ |
|
16658 meta := false. |
|
16659 ]. |
|
16660 self switchToClass:(Smalltalk at:classString asSymbol). |
|
16661 meta ifTrue:[cls := currentClass class] ifFalse:[cls := currentClass]. |
|
16662 actualClass := acceptClass := cls. |
|
16663 |
|
16664 currentClass isNil ifTrue:[ |
|
16665 self warn:'oops class is gone' |
|
16666 ] ifFalse:[ |
|
16667 currentClassCategory := currentClass category. |
|
16668 currentSelector := selectorString asSymbol. |
|
16669 currentMethod := actualClass compiledMethodAt:currentSelector. |
|
16670 currentMethod isNil ifTrue:[ |
|
16671 self warn:'oops method is gone' |
|
16672 ] ifFalse:[ |
|
16673 currentMethodCategory := currentMethod category. |
|
16674 ]. |
|
16675 |
|
16676 self methodSelectionChanged |
|
16677 ]. |
|
16678 |
|
16679 self setDoitActionForClass |
|
16680 |
|
16681 "Modified: 31.8.1995 / 11:56:02 / claus" |
|
16682 ! |
|
16683 |
|
16684 selectorFromClassMethodString:aString |
|
16685 "helper for classMethod-list - extract selector from the string" |
|
16686 |
|
16687 |pos| |
|
16688 |
|
16689 pos := aString indexOf:(Character space). |
|
16690 ^ aString copyFrom:(pos + 1) |
|
16691 ! ! |
|
16692 |
|
16693 !BrowserView methodsFor:'help'! |
|
16694 |
|
16695 helpTextFor:aComponent |
|
16696 |s| |
|
16697 |
|
16698 aComponent == classCategoryListView ifTrue:[ |
|
16699 s := 'HELP_CCAT_LIST' |
|
16700 ]. |
|
16701 aComponent == classListView ifTrue:[ |
|
16702 fullProtocol ifTrue:[ |
|
16703 s := 'HELP_PCLASS_LIST' |
|
16704 ] ifFalse:[ |
|
16705 currentClassHierarchy notNil ifTrue:[ |
|
16706 s := 'HELP_HCLASS_LIST' |
|
16707 ] ifFalse:[ |
|
16708 s := 'HELP_CLASS_LIST' |
|
16709 ] |
|
16710 ] |
|
16711 ]. |
|
16712 aComponent == methodCategoryListView ifTrue:[ |
|
16713 s := 'HELP_MCAT_LIST' |
|
16714 ]. |
|
16715 aComponent == methodListView ifTrue:[ |
|
16716 s := 'HELP_METHOD_LIST' |
|
16717 ]. |
|
16718 aComponent == variableListView ifTrue:[ |
|
16719 s := 'HELP_VAR_LIST' |
|
16720 ]. |
|
16721 aComponent == codeView ifTrue:[ |
|
16722 fullClass ifTrue:[ |
|
16723 s := 'HELP_FULLCODE_VIEW' |
|
16724 ] ifFalse:[ |
|
16725 s := 'HELP_CODE_VIEW' |
|
16726 ] |
|
16727 ]. |
|
16728 (aComponent == instanceToggle |
|
16729 or:[aComponent == classToggle]) ifTrue:[ |
|
16730 s := 'HELP_INST_CLASS_TOGGLE' |
|
16731 ]. |
|
16732 aComponent == classMethodListView ifTrue:[ |
|
16733 s := 'HELP_CLSMTHOD_LIST' |
|
16734 ]. |
|
16735 s notNil ifTrue:[ |
|
16736 ^ resources string:s |
|
16737 ]. |
|
16738 ^ nil |
|
16739 |
|
16740 "Modified: 31.8.1995 / 19:11:39 / claus" |
|
16741 ! ! |
|
16742 |
|
16743 !BrowserView methodsFor:'initialize / release'! |
|
16744 |
|
16745 autoSearch:aString |
|
16746 "used with class-method list browsing. If true, |
|
16747 selecting an entry from the list will automatically |
|
16748 search for the searchstring in the codeView" |
|
16749 |
|
16750 self setSearchPattern:aString. |
|
16751 autoSearch := aString |
|
16752 ! |
|
16753 |
|
16754 destroy |
|
16755 "relese dependant - destroy popups" |
|
16756 |
|
16757 Smalltalk removeDependent:self. |
|
16758 currentClass notNil ifTrue:[ |
|
16759 currentClass removeDependent:self. |
|
16760 currentClass := nil |
|
16761 ]. |
|
16762 super destroy |
|
16763 ! |
|
16764 |
|
16765 initialize |
|
16766 super initialize. |
|
16767 |
|
16768 showInstance := true. |
|
16769 fullClass := false. |
|
16770 fullProtocol := false. |
|
16771 aspect := nil. |
|
16772 |
|
16773 "inform me, when Smalltalk changes" |
|
16774 Smalltalk addDependent:self |
|
16775 ! |
|
16776 |
|
16777 realize |
|
16778 |v checkBlock| |
|
16779 |
|
16780 super realize. |
|
16781 |
|
16782 checkBlock := [:lineNr | self checkSelectionChangeAllowed]. |
|
16783 |
|
16784 v := classCategoryListView. |
|
16785 v notNil ifTrue:[ |
|
16786 v action:[:lineNr | self classCategorySelection:lineNr]. |
|
16787 v selectConditionBlock:checkBlock. |
|
16788 v ignoreReselect:false. |
|
16789 v contents:(self listOfAllClassCategories). |
|
16790 " |
|
16791 tell classCategoryListView to ask for the menu |
|
16792 " |
|
16793 v menuHolder:self; menuPerformer:self; menuMessage:#classCategoryMenu. |
|
16794 ]. |
|
16795 |
|
16796 v := classListView. |
|
16797 v notNil ifTrue:[ |
|
16798 v action:[:lineNr | self classSelection:lineNr]. |
|
16799 v selectConditionBlock:checkBlock. |
|
16800 v ignoreReselect:false. |
|
16801 " |
|
16802 tell classListView to ask for the menu |
|
16803 " |
|
16804 v menuHolder:self; menuPerformer:self; menuMessage:#classMenu. |
|
16805 ]. |
|
16806 |
|
16807 v := methodCategoryListView. |
|
16808 v notNil ifTrue:[ |
|
16809 v action:[:lineNr | self methodCategorySelection:lineNr]. |
|
16810 v selectConditionBlock:checkBlock. |
|
16811 v ignoreReselect:false. |
|
16812 " |
|
16813 tell methodCategoryListView to ask for the menu |
|
16814 " |
|
16815 v menuHolder:self; menuPerformer:self; menuMessage:#methodCategoryMenu. |
|
16816 ]. |
|
16817 |
|
16818 v := methodListView. |
|
16819 v notNil ifTrue:[ |
|
16820 v action:[:lineNr | self methodSelection:lineNr]. |
|
16821 v selectConditionBlock:checkBlock. |
|
16822 v ignoreReselect:false. |
|
16823 " |
|
16824 tell methodListView to ask for the menu |
|
16825 " |
|
16826 v menuHolder:self; menuPerformer:self; menuMessage:#methodMenu. |
|
16827 ]. |
|
16828 |
|
16829 v := classMethodListView. |
|
16830 v notNil ifTrue:[ |
|
16831 v action:[:lineNr | self classMethodSelection:lineNr]. |
|
16832 v selectConditionBlock:checkBlock. |
|
16833 v ignoreReselect:false. |
|
16834 " |
|
16835 tell classMethodListView to ask for the menu |
|
16836 " |
|
16837 v menuHolder:self; menuPerformer:self; menuMessage:#classMethodMenu. |
|
16838 ]. |
|
16839 |
|
16840 v := variableListView. |
|
16841 v notNil ifTrue:[ |
|
16842 v action:[:lineNr | self variableSelection:lineNr]. |
|
16843 v ignoreReselect:false. |
|
16844 v toggleSelect:true. |
|
16845 v menuHolder:self; menuPerformer:self; menuMessage:#variableListMenu. |
|
16846 ]. |
|
16847 |
|
16848 " |
|
16849 normal browsers show the top at first; |
|
16850 hierarchy and fullProtocol browsers better show the end |
|
16851 initially |
|
16852 " |
|
16853 currentClassHierarchy notNil ifTrue:[ |
|
16854 classListView scrollToBottom. |
|
16855 ] |
|
16856 ! |
|
16857 |
|
16858 terminate |
|
16859 (self checkSelectionChangeAllowed) ifTrue:[ |
|
16860 super terminate |
|
16861 ] |
|
16862 ! |
|
16863 |
|
16864 title:someString |
|
16865 myLabel := someString. |
|
16866 self label:someString. |
|
16867 ! ! |
|
16868 |
|
16869 !BrowserView methodsFor:'initialize subviews'! |
|
16870 |
|
16871 createClassListViewIn:frame |
|
16872 "setup the classlist subview, with its toggles" |
|
16873 |
|
16874 |v panel| |
|
16875 |
|
16876 self createTogglesIn:frame. |
|
16877 |
|
16878 " |
|
16879 oldstyle had no variableList ... |
|
16880 " |
|
16881 "/ v := ScrollableView for:SelectionInListView in:frame. |
|
16882 "/ v origin:(0.0 @ 0.0) |
|
16883 "/ extent:[frame width |
|
16884 "/ @ |
|
16885 "/ (frame height |
|
16886 "/ - ViewSpacing |
|
16887 "/ - instanceToggle height |
|
16888 "/ - instanceToggle borderWidth |
|
16889 "/ + v borderWidth)]. |
|
16890 "/ |
|
16891 "/ classListView := v scrolledView |
|
16892 |
|
16893 panel := VariableVerticalPanel |
|
16894 origin:(0.0 @ 0.0) |
|
16895 corner:[frame width |
|
16896 @ |
|
16897 (frame height |
|
16898 - ViewSpacing |
|
16899 - instanceToggle height |
|
16900 "-" "+ instanceToggle borderWidth " |
|
16901 + v borderWidth)] |
|
16902 in:frame. |
|
16903 |
|
16904 v := ScrollableView for:SelectionInListView in:panel. |
|
16905 v origin:(0.0 @ 0.0) corner:(1.0 @ 0.7). |
|
16906 classListView := v scrolledView. |
|
16907 |
|
16908 |
|
16909 v := ScrollableView for:SelectionInListView in:panel. |
|
16910 v origin:(0.0 @ 0.7) corner:(1.0 @ 1.0). |
|
16911 |
|
16912 variableListView := v scrolledView. |
|
16913 ! |
|
16914 |
|
16915 createCodeViewIn:aView |
|
16916 "setup the code view" |
|
16917 |
|
16918 ^ self createCodeViewIn:aView at:0.25 |
|
16919 ! |
|
16920 |
|
16921 createCodeViewIn:aView at:relY |
|
16922 "setup the code view" |
|
16923 |v| |
|
16924 |
|
16925 v := HVScrollableView for:CodeView miniScrollerH:true miniScrollerV:false in:aView. |
|
16926 v origin:(0.0 @ relY) corner:(1.0 @ 1.0). |
|
16927 codeView := v scrolledView |
|
16928 ! |
|
16929 |
|
16930 createTogglesIn:aFrame |
|
16931 "create and setup the class/instance toggles" |
|
16932 |
|
16933 |h halfSpace classAction instanceAction| |
|
16934 |
|
16935 classAction := [self instanceProtocol:false]. |
|
16936 instanceAction := [self instanceProtocol:true]. |
|
16937 |
|
16938 halfSpace := ViewSpacing // 2. |
|
16939 |
|
16940 instanceToggle := Toggle label:(resources at:'instance') in:aFrame. |
|
16941 h := instanceToggle heightIncludingBorder. |
|
16942 instanceToggle origin:(0.0 @ 1.0) corner:(0.5 @ 1.0). |
|
16943 instanceToggle topInset:h negated. |
|
16944 |
|
16945 instanceToggle turnOn. |
|
16946 instanceToggle pressAction:instanceAction. |
|
16947 instanceToggle releaseAction:classAction. |
|
16948 |
|
16949 classToggle := Toggle label:(resources at:'class') in:aFrame. |
|
16950 h := classToggle heightIncludingBorder. |
|
16951 classToggle origin:(0.5 @ 1.0) corner:(1.0 @ 1.0). |
|
16952 classToggle topInset:h negated. |
|
16953 |
|
16954 classToggle turnOff. |
|
16955 classToggle pressAction:classAction. |
|
16956 classToggle releaseAction:instanceAction. |
|
16957 |
|
16958 styleSheet is3D ifTrue:[ |
|
16959 instanceToggle bottomInset:halfSpace. |
|
16960 classToggle bottomInset:halfSpace. |
|
16961 |
|
16962 instanceToggle leftInset:halfSpace. |
|
16963 classToggle leftInset:halfSpace. |
|
16964 instanceToggle rightInset:ViewSpacing - halfSpace. |
|
16965 classToggle rightInset:ViewSpacing - halfSpace. |
|
16966 ]. |
|
16967 ! |
|
16968 |
|
16969 focusSequence |
|
16970 |s| |
|
16971 |
|
16972 s := OrderedCollection new. |
|
16973 |
|
16974 classCategoryListView notNil ifTrue:[ |
|
16975 s add:classCategoryListView |
|
16976 ]. |
|
16977 |
|
16978 classListView notNil ifTrue:[ |
|
16979 s add:classListView |
|
16980 ]. |
|
16981 |
|
16982 "/ variableListView notNil ifTrue:[ |
|
16983 "/ s add:variableListView |
|
16984 "/ ]. |
|
16985 |
|
16986 instanceToggle notNil ifTrue:[ |
|
16987 s add:instanceToggle. |
|
16988 ]. |
|
16989 |
|
16990 methodCategoryListView notNil ifTrue:[ |
|
16991 s add:methodCategoryListView |
|
16992 ]. |
|
16993 |
|
16994 methodListView notNil ifTrue:[ |
|
16995 s add:methodListView |
|
16996 ]. |
|
16997 |
|
16998 classMethodListView notNil ifTrue:[ |
|
16999 s add:classMethodListView |
|
17000 ]. |
|
17001 |
|
17002 s add:codeView. |
|
17003 ^ s |
|
17004 ! |
|
17005 |
|
17006 setupForAll |
|
17007 "create subviews for a full browser" |
|
17008 |
|
17009 |vpanel hpanel frame v| |
|
17010 |
|
17011 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) |
|
17012 in:self. |
|
17013 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
17014 |
|
17015 v := HVScrollableView for:SelectionInListView |
|
17016 miniScrollerH:true miniScrollerV:false |
|
17017 in:hpanel. |
|
17018 v origin:(0.0 @ 0.0) corner:(0.25 @ 1.0). |
|
17019 classCategoryListView := v scrolledView. |
|
17020 |
|
17021 frame := View origin:(0.25 @ 0.0) corner:(0.5 @ 1.0) in:hpanel. |
|
17022 self createClassListViewIn:frame. |
|
17023 |
|
17024 v := HVScrollableView for:SelectionInListView miniScrollerH:true miniScrollerV:false in:hpanel. |
|
17025 v origin:(0.5 @ 0.0) corner:(0.75 @ 1.0). |
|
17026 methodCategoryListView := v scrolledView. |
|
17027 |
|
17028 v := HVScrollableView for:SelectionInListView miniScrollerH:true miniScrollerV:false in:hpanel. |
|
17029 v origin:(0.75 @ 0.0) corner:(1.0 @ 1.0). |
|
17030 methodListView := v scrolledView. |
|
17031 |
|
17032 self createCodeViewIn:vpanel |
|
17033 ! |
|
17034 |
|
17035 setupForClass:aClass |
|
17036 "create subviews for browsing a single class" |
|
17037 |
|
17038 |vpanel hpanel frame v| |
|
17039 |
|
17040 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
17041 corner:(1.0 @ 1.0) |
|
17042 in:self. |
|
17043 |
|
17044 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
17045 frame := View origin:(0.0 @ 0.0) corner:(0.5 @ 1.0)in:hpanel. |
|
17046 |
|
17047 self createTogglesIn:frame. |
|
17048 |
|
17049 v := ScrollableView for:SelectionInListView in:frame. |
|
17050 v origin:(0.0 @ 0.0) |
|
17051 extent:[frame width |
|
17052 @ |
|
17053 (frame height |
|
17054 - ViewSpacing |
|
17055 - instanceToggle height |
|
17056 - instanceToggle borderWidth |
|
17057 + v borderWidth)]. |
|
17058 methodCategoryListView := v scrolledView. |
|
17059 |
|
17060 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17061 v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0). |
|
17062 methodListView := v scrolledView. |
|
17063 |
|
17064 self createCodeViewIn:vpanel. |
|
17065 |
|
17066 self switchToClass:aClass. |
|
17067 actualClass := acceptClass := aClass. |
|
17068 self updateMethodCategoryList. |
|
17069 self updateMethodList. |
|
17070 self updateCodeView. |
|
17071 self classDefinition. |
|
17072 ! |
|
17073 |
|
17074 setupForClass:aClass methodCategory:aMethodCategory |
|
17075 "setup subviews to browse a method category" |
|
17076 |
|
17077 |vpanel v| |
|
17078 |
|
17079 vpanel := VariableVerticalPanel |
|
17080 origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) |
|
17081 in:self. |
|
17082 |
|
17083 v := ScrollableView for:SelectionInListView in:vpanel. |
|
17084 v origin:(0.0 @ 0.0) corner:(1.0 @ 0.25). |
|
17085 methodListView := v scrolledView. |
|
17086 |
|
17087 self createCodeViewIn:vpanel. |
|
17088 |
|
17089 currentClassCategory := aClass category. |
|
17090 self switchToClass:aClass. |
|
17091 actualClass := acceptClass := aClass. |
|
17092 currentMethodCategory := aMethodCategory. |
|
17093 self updateMethodList. |
|
17094 self updateCodeView. |
|
17095 ! |
|
17096 |
|
17097 setupForClass:aClass selector:selector |
|
17098 "setup subviews to browse a single method" |
|
17099 |
|
17100 |v| |
|
17101 |
|
17102 v := ScrollableView for:CodeView in:self. |
|
17103 v origin:(0.0 @ 0.0) corner:(1.0 @ 1.0). |
|
17104 codeView := v scrolledView. |
|
17105 |
|
17106 currentClassCategory := aClass category. |
|
17107 self switchToClass:aClass. |
|
17108 actualClass := acceptClass := aClass. |
|
17109 currentSelector := selector. |
|
17110 currentMethod := currentClass compiledMethodAt:selector. |
|
17111 currentMethodCategory := currentMethod category. |
|
17112 self updateCodeView |
|
17113 ! |
|
17114 |
|
17115 setupForClassCategory:aClassCategory |
|
17116 "setup subviews to browse a class category" |
|
17117 |
|
17118 |vpanel hpanel frame v| |
|
17119 |
|
17120 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
17121 corner:(1.0 @ 1.0) |
|
17122 in:self. |
|
17123 |
|
17124 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
17125 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
17126 |
|
17127 self createClassListViewIn:frame. |
|
17128 |
|
17129 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17130 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
17131 methodCategoryListView := v scrolledView. |
|
17132 |
|
17133 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17134 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
17135 methodListView := v scrolledView. |
|
17136 |
|
17137 self createCodeViewIn:vpanel. |
|
17138 |
|
17139 currentClassCategory := aClassCategory. |
|
17140 self updateClassList. |
|
17141 self updateMethodCategoryList. |
|
17142 self updateMethodList. |
|
17143 self updateCodeView |
|
17144 ! |
|
17145 |
|
17146 setupForClassHierarchy:aClass |
|
17147 "setup subviews to browse a class hierarchy" |
|
17148 |
|
17149 |vpanel hpanel frame v cls| |
|
17150 |
|
17151 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
17152 corner:(1.0 @ 1.0) |
|
17153 in:self. |
|
17154 |
|
17155 " |
|
17156 notice: we use a different ratio here |
|
17157 " |
|
17158 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.4) in:vpanel. |
|
17159 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
17160 |
|
17161 self createClassListViewIn:frame. |
|
17162 |
|
17163 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17164 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
17165 methodCategoryListView := v scrolledView. |
|
17166 |
|
17167 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17168 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
17169 methodListView := v scrolledView. |
|
17170 |
|
17171 self createCodeViewIn:vpanel at:0.4. |
|
17172 |
|
17173 cls := aClass. |
|
17174 cls isMeta ifTrue:[ |
|
17175 cls := cls soleInstance |
|
17176 ]. |
|
17177 currentClassHierarchy := currentClass := actualClass := cls. |
|
17178 self updateClassList. |
|
17179 classListView selectElement:aClass name; makeSelectionVisible. |
|
17180 self updateMethodCategoryList. |
|
17181 self updateMethodList. |
|
17182 self updateCodeView. |
|
17183 |
|
17184 aClass isMeta ifTrue:[ |
|
17185 self instanceProtocol:false |
|
17186 ]. |
|
17187 ! |
|
17188 |
|
17189 setupForClassList:aList |
|
17190 "setup subviews to browse classes from a list" |
|
17191 |
|
17192 |vpanel hpanel frame l v| |
|
17193 |
|
17194 vpanel := VariableVerticalPanel |
|
17195 origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:self. |
|
17196 |
|
17197 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
17198 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
17199 |
|
17200 self createClassListViewIn:frame. |
|
17201 |
|
17202 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17203 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
17204 methodCategoryListView := v scrolledView. |
|
17205 |
|
17206 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17207 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
17208 methodListView := v scrolledView. |
|
17209 |
|
17210 self createCodeViewIn:vpanel. |
|
17211 |
|
17212 l := (aList collect:[:entry | entry name]) asOrderedCollection. |
|
17213 classListView list:(l sort). |
|
17214 |
|
17215 self updateMethodCategoryList. |
|
17216 self updateMethodList. |
|
17217 self updateCodeView |
|
17218 ! |
|
17219 |
|
17220 setupForFullClass |
|
17221 "setup subviews to browse a class as full text" |
|
17222 |
|
17223 |vpanel hpanel v| |
|
17224 |
|
17225 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
17226 corner:(1.0 @ 1.0) |
|
17227 in:self. |
|
17228 |
|
17229 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel. |
|
17230 |
|
17231 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17232 v origin:(0.0 @ 0.0) corner:(0.5 @ 1.0). |
|
17233 classCategoryListView := v scrolledView. |
|
17234 classCategoryListView contents:(self listOfAllClassCategories). |
|
17235 |
|
17236 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17237 v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0). |
|
17238 classListView := v scrolledView. |
|
17239 |
|
17240 self createCodeViewIn:vpanel. |
|
17241 |
|
17242 fullClass := true. |
|
17243 self updateCodeView |
|
17244 ! |
|
17245 |
|
17246 setupForFullClassProtocol:aClass |
|
17247 "setup subviews to browse a classes full protocol" |
|
17248 |
|
17249 |vpanel hpanel frame v cls| |
|
17250 |
|
17251 vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) |
|
17252 corner:(1.0 @ 1.0) |
|
17253 in:self. |
|
17254 |
|
17255 " |
|
17256 notice: we use a different ratio here |
|
17257 " |
|
17258 hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.4) in:vpanel. |
|
17259 frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel. |
|
17260 |
|
17261 self createClassListViewIn:frame. |
|
17262 classListView multipleSelectOk:true. |
|
17263 classListView toggleSelect:true. |
|
17264 classListView strikeOut:true. |
|
17265 |
|
17266 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17267 v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0). |
|
17268 methodCategoryListView := v scrolledView. |
|
17269 |
|
17270 v := ScrollableView for:SelectionInListView in:hpanel. |
|
17271 v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0). |
|
17272 methodListView := v scrolledView. |
|
17273 |
|
17274 self createCodeViewIn:vpanel at:0.4. |
|
17275 |
|
17276 cls := aClass. |
|
17277 cls isMeta ifTrue:[ |
|
17278 cls := cls soleInstance |
|
17279 ]. |
|
17280 currentClassHierarchy := actualClass := acceptClass := currentClass := cls. |
|
17281 fullProtocol := true. |
|
17282 |
|
17283 self updateClassList. |
|
17284 self updateMethodCategoryList. |
|
17285 self updateMethodList. |
|
17286 self updateCodeView. |
|
17287 self updateVariableList. |
|
17288 aClass isMeta ifTrue:[ |
|
17289 self instanceProtocol:false |
|
17290 ]. |
|
17291 ! |
|
17292 |
|
17293 setupForList:aList |
|
17294 "setup subviews to browse methods from a list" |
|
17295 |
|
17296 |vpanel v| |
|
17297 |
|
17298 vpanel := VariableVerticalPanel |
|
17299 origin:(0.0 @ 0.0) |
|
17300 corner:(1.0 @ 1.0) |
|
17301 in:self. |
|
17302 |
|
17303 v := ScrollableView for:SelectionInListView in:vpanel. |
|
17304 v origin:(0.0 @ 0.0) corner:(1.0 @ 0.25). |
|
17305 classMethodListView := v scrolledView. |
|
17306 classMethodListView contents:aList. |
|
17307 |
|
17308 self createCodeViewIn:vpanel. |
|
17309 aList size == 1 ifTrue:[ |
|
17310 classMethodListView selection:1. |
|
17311 self classMethodSelection:1. |
|
17312 ]. |
|
17313 self updateCodeView |
|
17314 ! ! |
|
17315 |
|
17316 !BrowserView methodsFor:'method category list menu'! |
|
17317 |
|
17318 methodCategoryCopyCategory |
|
17319 "show the enter box to copy from an existing method category" |
|
17320 |
|
17321 |title box| |
|
17322 |
|
17323 showInstance ifTrue:[ |
|
17324 title := 'class to copy instance method category from:' |
|
17325 ] ifFalse:[ |
|
17326 title := 'class to copy class method category from:' |
|
17327 ]. |
|
17328 |
|
17329 box := self listBoxTitle:title |
|
17330 okText:'ok' |
|
17331 list:(Smalltalk allClasses collect:[:cls | cls name]) asArray sort. |
|
17332 |
|
17333 box action:[:aString | self copyMethodsFromClass:aString]. |
|
17334 box showAtPointer |
|
17335 ! |
|
17336 |
|
17337 methodCategoryCreateAccessMethods |
|
17338 "create access methods for all instvars" |
|
17339 |
|
17340 self checkClassSelected ifFalse:[^ self]. |
|
17341 |
|
17342 showInstance ifFalse:[ |
|
17343 self warn:'select instance - and try again'. |
|
17344 ^ self. |
|
17345 ]. |
|
17346 |
|
17347 self withWaitCursorDo:[ |
|
17348 |nm names source| |
|
17349 |
|
17350 (variableListView notNil |
|
17351 and:[(nm := variableListView selectionValue) notNil]) ifTrue:[ |
|
17352 names := Array with:nm |
|
17353 ] ifFalse:[ |
|
17354 names := currentClass instVarNames |
|
17355 ]. |
|
17356 names do:[:name | |
|
17357 "check, if method is not already present" |
|
17358 (currentClass implements:(name asSymbol)) ifFalse:[ |
|
17359 source := (name , '\ "return ' , name , '"\\ ^ ' , name) withCRs. |
|
17360 Compiler compile:source forClass:currentClass inCategory:'accessing'. |
|
17361 ] ifTrue:[ |
|
17362 Transcript showCr:'method ''', name , ''' already present' |
|
17363 ]. |
|
17364 (currentClass implements:((name , ':') asSymbol)) ifFalse:[ |
|
17365 source := (name , ':something\ "set ' , name , '"\\ ' , name , ' := something.') withCRs. |
|
17366 Compiler compile:source forClass:currentClass inCategory:'accessing'. |
|
17367 ] ifTrue:[ |
|
17368 Transcript showCr:'method ''', name , ':'' already present' |
|
17369 ]. |
|
17370 ]. |
|
17371 self updateMethodCategoryListWithScroll:false. |
|
17372 self updateMethodListWithScroll:false |
|
17373 ] |
|
17374 ! |
|
17375 |
|
17376 methodCategoryCreateDocumentationMethods |
|
17377 "create empty documentation methods" |
|
17378 |
|
17379 |cls histStream| |
|
17380 |
|
17381 self checkClassSelected ifFalse:[^ self]. |
|
17382 |
|
17383 cls := currentClass class. |
|
17384 |
|
17385 self withWaitCursorDo:[ |
|
17386 |nm names source| |
|
17387 |
|
17388 "/ add version method containing RCS template |
|
17389 "/ but only if not already present. |
|
17390 |
|
17391 (cls implements:#version) ifFalse:[ |
|
17392 Compiler compile: |
|
17393 'version |
|
17394 " |
|
17395 $' , 'Header$ |
|
17396 " |
|
17397 ' forClass:cls |
|
17398 inCategory:'documentation'. |
|
17399 ]. |
|
17400 |
|
17401 "/ add documentation method containing doc template |
|
17402 "/ but only if not already present. |
|
17403 |
|
17404 (cls implements:#documentation) ifFalse:[ |
|
17405 Compiler compile: |
|
17406 'documentation |
|
17407 " |
|
17408 documentation to be added. |
|
17409 " |
|
17410 ' forClass:cls |
|
17411 inCategory:'documentation'. |
|
17412 ]. |
|
17413 |
|
17414 "/ add examples method containing examples template |
|
17415 "/ but only if not already present. |
|
17416 |
|
17417 (cls implements:#examples) ifFalse:[ |
|
17418 Compiler compile: |
|
17419 'examples |
|
17420 " |
|
17421 examples to be added. |
|
17422 " |
|
17423 ' forClass:cls |
|
17424 inCategory:'documentation'. |
|
17425 ]. |
|
17426 |
|
17427 "/ add history method containing created-entry |
|
17428 "/ but only if not already present. |
|
17429 |
|
17430 (cls implements:#history) ifFalse:[ |
|
17431 histStream := ReadWriteStream on: String new. |
|
17432 histStream nextPutAll: 'history'; cr. |
|
17433 HistoryLine isBehavior ifTrue:[ |
|
17434 histStream nextPutAll: (HistoryLine newCreated printString); cr. |
|
17435 ] ifFalse:[ |
|
17436 histStream cr. |
|
17437 ]. |
|
17438 Compiler compile:(histStream contents) |
|
17439 forClass:cls |
|
17440 inCategory:'documentation'. |
|
17441 ]. |
|
17442 |
|
17443 self instanceProtocol:false. |
|
17444 self switchToMethodNamed:#documentation |
|
17445 "/ self updateMethodCategoryListWithScroll:false. |
|
17446 "/ self updateMethodListWithScroll:false |
|
17447 ] |
|
17448 ! |
|
17449 |
|
17450 methodCategoryFileOut |
|
17451 "fileOut all methods in the selected methodcategory of |
|
17452 the current class" |
|
17453 |
|
17454 self checkClassSelected ifFalse:[^ self]. |
|
17455 self whenMethodCategorySelected:[ |
|
17456 self busyLabel:'saving: %1' with:currentClass name , '-' , currentMethodCategory. |
|
17457 Class fileOutErrorSignal handle:[:ex | |
|
17458 self warn:'cannot create: %1' with:ex parameter. |
|
17459 ex return. |
|
17460 ] do:[ |
|
17461 actualClass fileOutCategory:currentMethodCategory. |
|
17462 ]. |
|
17463 self normalLabel. |
|
17464 ] |
|
17465 ! |
|
17466 |
|
17467 methodCategoryFileOutAll |
|
17468 "fileOut all methods in the selected methodcategory of |
|
17469 the current class" |
|
17470 |
|
17471 |
|
17472 self whenMethodCategorySelected:[ |
|
17473 |fileName outStream| |
|
17474 |
|
17475 fileName := currentMethodCategory , '.st'. |
|
17476 fileName replaceAll:Character space by:$_. |
|
17477 " |
|
17478 this test allows a smalltalk to be built without Projects/ChangeSets |
|
17479 " |
|
17480 Project notNil ifTrue:[ |
|
17481 fileName := Project currentProjectDirectory , fileName. |
|
17482 ]. |
|
17483 " |
|
17484 if file exists, save original in a .sav file |
|
17485 " |
|
17486 fileName asFilename exists ifTrue:[ |
|
17487 fileName asFilename copyTo:(fileName , '.sav') |
|
17488 ]. |
|
17489 outStream := FileStream newFileNamed:fileName. |
|
17490 outStream isNil ifTrue:[ |
|
17491 ^ self warn:'cannot create: %1' with:fileName |
|
17492 ]. |
|
17493 |
|
17494 self busyLabel:'saving: ' with:currentMethodCategory. |
|
17495 Class fileOutErrorSignal handle:[:ex | |
|
17496 self warn:'cannot create: %1' with:ex parameter. |
|
17497 ex return |
|
17498 ] do:[ |
|
17499 Smalltalk allBehaviorsDo:[:class | |
|
17500 |hasMethodsInThisCategory| |
|
17501 |
|
17502 hasMethodsInThisCategory := false. |
|
17503 class methodArray do:[:method | |
|
17504 method category = currentMethodCategory ifTrue:[ |
|
17505 hasMethodsInThisCategory := true |
|
17506 ] |
|
17507 ]. |
|
17508 hasMethodsInThisCategory ifTrue:[ |
|
17509 class fileOutCategory:currentMethodCategory on:outStream. |
|
17510 outStream cr |
|
17511 ]. |
|
17512 hasMethodsInThisCategory := false. |
|
17513 class class methodArray do:[:method | |
|
17514 method category = currentMethodCategory ifTrue:[ |
|
17515 hasMethodsInThisCategory := true |
|
17516 ] |
|
17517 ]. |
|
17518 hasMethodsInThisCategory ifTrue:[ |
|
17519 class class fileOutCategory:currentMethodCategory on:outStream. |
|
17520 outStream cr |
|
17521 ] |
|
17522 ]. |
|
17523 ]. |
|
17524 outStream close. |
|
17525 self normalLabel. |
|
17526 ]. |
|
17527 ! |
|
17528 |
|
17529 methodCategoryFindAnyMethod |
|
17530 |box| |
|
17531 |
|
17532 box := self enterBoxForSearchSelectorTitle:'method selector to search for:'. |
|
17533 box action:[:aString | self switchToAnyMethodNamed:aString]. |
|
17534 box showAtPointer |
|
17535 ! |
|
17536 |
|
17537 methodCategoryFindMethod |
|
17538 |box| |
|
17539 |
|
17540 box := self enterBoxForSearchSelectorTitle:'method selector to search for:'. |
|
17541 box action:[:aString | self switchToMethodNamed:aString]. |
|
17542 box showAtPointer |
|
17543 ! |
|
17544 |
|
17545 methodCategoryMenu |
|
17546 |labels selectors i| |
|
17547 |
|
17548 currentClass isNil ifTrue:[ |
|
17549 methodCategoryListView flash. |
|
17550 ^ nil |
|
17551 ]. |
|
17552 currentMethodCategory isNil ifTrue:[ |
|
17553 labels := #( |
|
17554 'find method here ...' |
|
17555 'find method ...' |
|
17556 '-' |
|
17557 'new category ...' |
|
17558 'copy category ...' |
|
17559 'create access methods' |
|
17560 ). |
|
17561 selectors := #( |
|
17562 methodCategoryFindMethod |
|
17563 methodCategoryFindAnyMethod |
|
17564 nil |
|
17565 methodCategoryNewCategory |
|
17566 methodCategoryCopyCategory |
|
17567 methodCategoryCreateAccessMethods |
|
17568 ). |
|
17569 ] ifFalse:[ |
|
17570 labels := #( |
|
17571 'fileOut' |
|
17572 'fileOut all' |
|
17573 'printOut' |
|
17574 '-' |
|
17575 'SPAWN_METHODCATEGORY' |
|
17576 'spawn category' |
|
17577 '-' |
|
17578 'find method here ...' |
|
17579 'find method ...' |
|
17580 '-' |
|
17581 'new category ...' |
|
17582 'copy category ...' |
|
17583 'create access methods' |
|
17584 'rename ...' |
|
17585 'remove' |
|
17586 ). |
|
17587 selectors := #( |
|
17588 methodCategoryFileOut |
|
17589 methodCategoryFileOutAll |
|
17590 methodCategoryPrintOut |
|
17591 nil |
|
17592 methodCategorySpawn |
|
17593 methodCategorySpawnCategory |
|
17594 nil |
|
17595 methodCategoryFindMethod |
|
17596 methodCategoryFindAnyMethod |
|
17597 nil |
|
17598 methodCategoryNewCategory |
|
17599 methodCategoryCopyCategory |
|
17600 methodCategoryCreateAccessMethods |
|
17601 methodCategoryRename |
|
17602 methodCategoryRemove |
|
17603 ). |
|
17604 ]. |
|
17605 |
|
17606 showInstance ifFalse:[ |
|
17607 labels := labels copy. |
|
17608 selectors := selectors copy. |
|
17609 i := labels indexOf:'create access methods'. |
|
17610 labels at:i put:'create documentation stubs'. |
|
17611 selectors at:i put:#methodCategoryCreateDocumentationMethods |
|
17612 ]. |
|
17613 |
|
17614 ^ PopUpMenu labels:(resources array:labels) |
|
17615 selectors:selectors |
|
17616 ! |
|
17617 |
|
17618 methodCategoryNewCategory |
|
17619 "show the enter box to add a new method category. |
|
17620 Offer existing superclass categories in box to help avoiding |
|
17621 useless typing." |
|
17622 |
|
17623 |someCategories existingCategories box| |
|
17624 |
|
17625 actualClass notNil ifTrue:[ |
|
17626 someCategories := actualClass allCategories |
|
17627 ] ifFalse:[ |
|
17628 " |
|
17629 mhmh - offer some typical categories ... |
|
17630 " |
|
17631 showInstance ifTrue:[ |
|
17632 someCategories := #('accessing' |
|
17633 'initialization' |
|
17634 'private' |
|
17635 'printing & storing' |
|
17636 'queries' |
|
17637 'testing' |
|
17638 ) |
|
17639 ] ifFalse:[ |
|
17640 someCategories := #( |
|
17641 'documentation' |
|
17642 'initialization' |
|
17643 'instance creation' |
|
17644 ). |
|
17645 ]. |
|
17646 ]. |
|
17647 someCategories sort. |
|
17648 |
|
17649 " |
|
17650 remove existing categories |
|
17651 " |
|
17652 existingCategories := methodCategoryListView list. |
|
17653 existingCategories notNil ifTrue:[ |
|
17654 someCategories := someCategories select:[:cat | (existingCategories includes:cat) not]. |
|
17655 ]. |
|
17656 |
|
17657 box := self listBoxTitle:'name of new method category:' |
|
17658 okText:'create' |
|
17659 list:someCategories. |
|
17660 box action:[:aString | self newMethodCategory:aString]. |
|
17661 box showAtPointer |
|
17662 |
|
17663 |
|
17664 |
|
17665 ! |
|
17666 |
|
17667 methodCategoryPrintOut |
|
17668 |printStream| |
|
17669 |
|
17670 self checkClassSelected ifFalse:[^ self]. |
|
17671 self whenMethodCategorySelected:[ |
|
17672 printStream := Printer new. |
|
17673 actualClass printOutCategory:currentMethodCategory on:printStream. |
|
17674 printStream close |
|
17675 ] |
|
17676 ! |
|
17677 |
|
17678 methodCategoryRemove |
|
17679 "show number of methods to remove and query user" |
|
17680 |
|
17681 |count t box| |
|
17682 |
|
17683 currentMethodCategory notNil ifTrue:[ |
|
17684 count := 0. |
|
17685 actualClass methodArray do:[:aMethod | |
|
17686 (aMethod category = currentMethodCategory) ifTrue:[ |
|
17687 count := count + 1 |
|
17688 ] |
|
17689 ]. |
|
17690 (count == 0) ifTrue:[ |
|
17691 currentMethodCategory := nil. |
|
17692 currentMethod := currentSelector := nil. |
|
17693 self updateMethodCategoryListWithScroll:false. |
|
17694 self updateMethodList |
|
17695 ] ifFalse:[ |
|
17696 (count == 1) ifTrue:[ |
|
17697 t := 'remove %1\(with 1 method) ?' |
|
17698 ] ifFalse:[ |
|
17699 t := 'remove %1\(with %2 methods) ?' |
|
17700 ]. |
|
17701 t := resources string:t with:currentMethodCategory with:count printString. |
|
17702 t := t withCRs. |
|
17703 |
|
17704 box := YesNoBox |
|
17705 title:t |
|
17706 yesText:(resources at:'remove') |
|
17707 noText:(resources at:'abort'). |
|
17708 box confirm ifTrue:[ |
|
17709 actualClass methodArray do:[:aMethod | |
|
17710 (aMethod category = currentMethodCategory) ifTrue:[ |
|
17711 actualClass |
|
17712 removeSelector:(actualClass selectorAtMethod:aMethod) |
|
17713 ] |
|
17714 ]. |
|
17715 currentMethodCategory := nil. |
|
17716 currentMethod := currentSelector := nil. |
|
17717 self updateMethodCategoryList. |
|
17718 self updateMethodList |
|
17719 ] |
|
17720 ] |
|
17721 ] |
|
17722 ! |
|
17723 |
|
17724 methodCategoryRename |
|
17725 "launch an enterBox to rename current method category" |
|
17726 |
|
17727 |box| |
|
17728 |
|
17729 self checkMethodCategorySelected ifFalse:[^ self]. |
|
17730 |
|
17731 box := self enterBoxTitle:(resources string:'rename method category %1 to:' with:currentMethodCategory) |
|
17732 okText:(resources at:'rename'). |
|
17733 box initialText:currentMethodCategory. |
|
17734 box action:[:aString | |
|
17735 actualClass renameCategory:currentMethodCategory to:aString. |
|
17736 currentMethodCategory := aString. |
|
17737 currentMethod := currentSelector := nil. |
|
17738 self updateMethodCategoryList. |
|
17739 self updateMethodListWithScroll:false |
|
17740 ]. |
|
17741 box showAtPointer |
|
17742 ! |
|
17743 |
|
17744 methodCategorySpawn |
|
17745 "create a new SystemBrowser browsing current method category" |
|
17746 |
|
17747 currentMethodCategory notNil ifTrue:[ |
|
17748 self withWaitCursorDo:[ |
|
17749 SystemBrowser browseClass:actualClass |
|
17750 methodCategory:currentMethodCategory |
|
17751 ] |
|
17752 ] |
|
17753 ! |
|
17754 |
|
17755 methodCategorySpawnCategory |
|
17756 "create a new SystemBrowser browsing all methods from all |
|
17757 classes with same category as current method category" |
|
17758 |
|
17759 self askAndBrowseMethodCategory:'category to browse methods:' |
|
17760 action:[:aString | |
|
17761 SystemBrowser browseMethodCategory:aString |
|
17762 ] |
|
17763 ! ! |
|
17764 |
|
17765 !BrowserView methodsFor:'method category stuff'! |
|
17766 |
|
17767 checkMethodCategorySelected |
|
17768 currentMethodCategory isNil ifTrue:[ |
|
17769 self warn:'select a method category first'. |
|
17770 ^ false |
|
17771 ]. |
|
17772 ^ true |
|
17773 ! |
|
17774 |
|
17775 copyMethodsFromClass:aClassName |
|
17776 |class box| |
|
17777 |
|
17778 currentClass notNil ifTrue:[ |
|
17779 class := Smalltalk classNamed:aClassName. |
|
17780 class isBehavior ifFalse:[ |
|
17781 self warn:'no class named %1' with:aClassName. |
|
17782 ^ self |
|
17783 ]. |
|
17784 |
|
17785 showInstance ifFalse:[ |
|
17786 class := class class |
|
17787 ]. |
|
17788 |
|
17789 "show enterbox for category to copy from" |
|
17790 |
|
17791 box := self enterBoxTitle:'name of category to copy from (matchpattern allowed, * for all):' |
|
17792 okText:'copy'. |
|
17793 box action:[:aString | self copyMethodsFromClass:class category:aString]. |
|
17794 box showAtPointer. |
|
17795 ] |
|
17796 ! |
|
17797 |
|
17798 copyMethodsFromClass:class category:category |
|
17799 currentClass notNil ifTrue:[ |
|
17800 Object abortSignal catch:[ |
|
17801 class methodArray do:[:aMethod | |
|
17802 |source| |
|
17803 |
|
17804 (category match:aMethod category) ifTrue:[ |
|
17805 source := aMethod source. |
|
17806 codeView contents:source. |
|
17807 codeView modified:false. |
|
17808 actualClass compilerClass |
|
17809 compile:source |
|
17810 forClass:actualClass |
|
17811 inCategory:aMethod category |
|
17812 notifying:codeView. |
|
17813 self updateMethodCategoryListWithScroll:false. |
|
17814 self updateMethodListWithScroll:false. |
|
17815 ] |
|
17816 ] |
|
17817 ] |
|
17818 ] |
|
17819 ! |
|
17820 |
|
17821 listOfAllMethodCategoriesInClass:aClass |
|
17822 "answer a list of all method categories of the argument, aClass" |
|
17823 |
|
17824 |newList| |
|
17825 |
|
17826 newList := Set new. |
|
17827 aClass methodArray do:[:aMethod | |
|
17828 |cat| |
|
17829 |
|
17830 cat := aMethod category. |
|
17831 cat isNil ifTrue:[ |
|
17832 cat := '* no category *' |
|
17833 ]. |
|
17834 newList add:cat |
|
17835 ]. |
|
17836 (newList size == 0) ifTrue:[^ nil]. |
|
17837 newList add:'* all *'. |
|
17838 ^ newList asOrderedCollection sort |
|
17839 ! |
|
17840 |
|
17841 listOfAllMethodCategoriesInFullProtocolHierarchy:aClass |
|
17842 "answer a list of all method categories of the argument, aClass, |
|
17843 and all of its superclasses. |
|
17844 Used with fullProtocol browsing." |
|
17845 |
|
17846 |newList| |
|
17847 |
|
17848 newList := Set new. |
|
17849 self classesInFullProtocolHierarchy:aClass do:[:c | |
|
17850 |cat| |
|
17851 |
|
17852 c methodArray do:[:aMethod | |
|
17853 cat := aMethod category. |
|
17854 cat isNil ifTrue:[ |
|
17855 cat := '* no category *' |
|
17856 ]. |
|
17857 newList add:cat |
|
17858 ] |
|
17859 ]. |
|
17860 (newList size == 0) ifTrue:[^ nil]. |
|
17861 newList add:'* all *'. |
|
17862 ^ newList asOrderedCollection sort |
|
17863 ! |
|
17864 |
|
17865 methodCategorySelection:lineNr |
|
17866 "user clicked on a method category line - show selectors" |
|
17867 |
|
17868 "/ |oldSelector| |
|
17869 |
|
17870 "/ oldSelector := currentSelector. |
|
17871 |
|
17872 (fullProtocol not and:[currentClass isNil]) ifTrue:[^ self]. |
|
17873 |
|
17874 currentMethodCategory := methodCategoryListView selectionValue. |
|
17875 self methodCategorySelectionChanged. |
|
17876 aspect := nil. |
|
17877 |
|
17878 "if there is only one method, show it right away" |
|
17879 methodListView list size == 1 ifTrue:[ |
|
17880 methodListView selection:1. |
|
17881 self methodSelection:1 |
|
17882 "/ ] ifFalse:[ |
|
17883 "/ oldSelector notNil ifTrue:[ |
|
17884 "/ methodListView selectElement:oldSelector. |
|
17885 "/ methodListView hasSelection ifTrue:[ |
|
17886 "/ self methodSelection:methodListView selection. |
|
17887 "/ ] |
|
17888 "/ ] |
|
17889 ] |
|
17890 |
|
17891 "Created: 23.11.1995 / 14:19:56 / cg" |
|
17892 ! |
|
17893 |
|
17894 methodCategorySelectionChanged |
|
17895 "method category selection has changed - update dependent views" |
|
17896 |
|
17897 self withWaitCursorDo:[ |
|
17898 currentMethod := currentSelector := nil. |
|
17899 |
|
17900 self updateMethodList. |
|
17901 self updateCodeView. |
|
17902 |
|
17903 currentMethodCategory notNil ifTrue:[ |
|
17904 methodCategoryListView selectElement:currentMethodCategory |
|
17905 ]. |
|
17906 |
|
17907 self setAcceptAndExplainActionsForMethod. |
|
17908 self hilightMethodsInMethodCategoryList:false inMethodList:true. |
|
17909 ] |
|
17910 |
|
17911 "Created: 23.11.1995 / 14:17:38 / cg" |
|
17912 "Modified: 23.11.1995 / 14:19:49 / cg" |
|
17913 ! |
|
17914 |
|
17915 newMethodCategory:aString |
|
17916 |categories| |
|
17917 |
|
17918 currentClass isNil ifTrue:[ |
|
17919 ^ self warn:'select/create a class first'. |
|
17920 ]. |
|
17921 categories := methodCategoryListView list. |
|
17922 categories isNil ifTrue:[categories := OrderedCollection new]. |
|
17923 (categories includes:aString) ifFalse:[ |
|
17924 categories add:aString. |
|
17925 categories sort. |
|
17926 methodCategoryListView contents:categories |
|
17927 ]. |
|
17928 currentMethodCategory := aString. |
|
17929 self methodCategorySelectionChanged |
|
17930 ! |
|
17931 |
|
17932 updateMethodCategoryList |
|
17933 self updateMethodCategoryListWithScroll:true |
|
17934 ! |
|
17935 |
|
17936 updateMethodCategoryListWithScroll:scroll |
|
17937 |categories| |
|
17938 |
|
17939 methodCategoryListView notNil ifTrue:[ |
|
17940 fullProtocol ifTrue:[ |
|
17941 currentClassHierarchy notNil ifTrue:[ |
|
17942 categories := self listOfAllMethodCategoriesInFullProtocolHierarchy:actualClass |
|
17943 ] |
|
17944 ] ifFalse:[ |
|
17945 currentClass notNil ifTrue:[ |
|
17946 categories := self listOfAllMethodCategoriesInClass:actualClass |
|
17947 ] |
|
17948 ]. |
|
17949 methodCategoryListView list = categories ifFalse:[ |
|
17950 scroll ifTrue:[ |
|
17951 methodCategoryListView contents:categories |
|
17952 ] ifFalse:[ |
|
17953 methodCategoryListView setContents:categories |
|
17954 ]. |
|
17955 currentMethodCategory notNil ifTrue:[ |
|
17956 methodCategoryListView selectElement:currentMethodCategory |
|
17957 ] |
|
17958 ] |
|
17959 ] |
|
17960 ! |
|
17961 |
|
17962 whenMethodCategorySelected:aBlock |
|
17963 self checkMethodCategorySelected ifTrue:[ |
|
17964 self withWaitCursorDo:aBlock |
|
17965 ] |
|
17966 ! ! |
|
17967 |
|
17968 !BrowserView methodsFor:'method list menu'! |
|
17969 |
|
17970 commonTraceHelperWith:aSelector |
|
17971 currentMethod := MessageTracer perform:aSelector with:currentMethod. |
|
17972 self updateMethodListWithScroll:false keepSelection:true. |
|
17973 currentClass changed:#methodDictionary with:currentSelector. |
|
17974 ! |
|
17975 |
|
17976 methodAproposSearch |
|
17977 "launch an enterBox for a keyword search" |
|
17978 |
|
17979 self askForSelectorTitle:'keyword to search for:' |
|
17980 openWith:#aproposSearch: |
|
17981 ! |
|
17982 |
|
17983 methodBreakPoint |
|
17984 "set a breakpoint on the current method" |
|
17985 |
|
17986 currentSelector notNil ifTrue:[ |
|
17987 currentMethod := actualClass compiledMethodAt:currentSelector. |
|
17988 currentMethod isWrapped ifFalse:[ |
|
17989 (currentMethod notNil and:[currentMethod isWrapped not]) ifTrue:[ |
|
17990 self commonTraceHelperWith:#trapMethod: |
|
17991 ] |
|
17992 ]. |
|
17993 ] |
|
17994 ! |
|
17995 |
|
17996 methodChangeCategory |
|
17997 "move the current method into another category - |
|
17998 nothing done here, but a query for the new category. |
|
17999 Remember the last category, to allow faster category change of a group of methods." |
|
18000 |
|
18001 |box txt| |
|
18002 |
|
18003 self checkMethodSelected ifFalse:[^ self]. |
|
18004 |
|
18005 actualClass isNil ifTrue:[ |
|
18006 box := self enterBoxTitle:'' okText:'change'. |
|
18007 ] ifFalse:[ |
|
18008 |someCategories| |
|
18009 |
|
18010 someCategories := actualClass categories sort. |
|
18011 box := self listBoxTitle:'' okText:'change' list:someCategories. |
|
18012 ]. |
|
18013 box title:('change category from ''' , currentMethod category , ''' to:'). |
|
18014 lastMethodCategory isNil ifTrue:[ |
|
18015 txt := currentMethod category. |
|
18016 ] ifFalse:[ |
|
18017 txt := lastMethodCategory |
|
18018 ]. |
|
18019 box initialText:txt. |
|
18020 box action:[:aString | |
|
18021 lastMethodCategory := aString. |
|
18022 |
|
18023 currentMethod category:aString asSymbol. |
|
18024 actualClass changed. |
|
18025 currentMethod changed:#category. |
|
18026 actualClass updateRevisionString. |
|
18027 actualClass addChangeRecordForMethodCategory:currentMethod category:aString. |
|
18028 self updateMethodCategoryListWithScroll:false. |
|
18029 self updateMethodListWithScroll:false |
|
18030 ]. |
|
18031 box showAtPointer |
|
18032 |
|
18033 "Created: 29.10.1995 / 19:59:22 / cg" |
|
18034 ! |
|
18035 |
|
18036 methodDecompile |
|
18037 "decompile the current methods bytecodes. |
|
18038 The Decompiler is delivered as an extra, and not normally |
|
18039 avaliable with the system." |
|
18040 |
|
18041 self checkMethodSelected ifFalse:[^ self]. |
|
18042 Decompiler notNil ifTrue:[ |
|
18043 Autoload autoloadFailedSignal handle:[:ex | |
|
18044 ex return |
|
18045 ] do:[ |
|
18046 Decompiler autoload. |
|
18047 ]. |
|
18048 ]. |
|
18049 Decompiler isLoaded ifFalse:[ |
|
18050 Smalltalk |
|
18051 fileIn:'/phys/clam/claus/work/libcomp/not_delivered/Decomp.st' |
|
18052 logged:false. |
|
18053 ]. |
|
18054 Decompiler isLoaded ifFalse:[ |
|
18055 ^ self warn:'No decompiler available'. |
|
18056 ]. |
|
18057 |
|
18058 Decompiler decompile:currentMethod. |
|
18059 ! |
|
18060 |
|
18061 methodFileOut |
|
18062 "file out the current method" |
|
18063 |
|
18064 self checkMethodSelected ifFalse:[^ self]. |
|
18065 |
|
18066 self busyLabel:'saving:' with:currentSelector. |
|
18067 Class fileOutErrorSignal handle:[:ex | |
|
18068 self warn:'cannot create: %1' with:ex parameter. |
|
18069 ex return |
|
18070 ] do:[ |
|
18071 actualClass fileOutMethod:currentMethod. |
|
18072 ]. |
|
18073 self normalLabel. |
|
18074 ! |
|
18075 |
|
18076 methodGlobalReferends |
|
18077 "launch an enterBox for global symbol to search for" |
|
18078 |
|
18079 self enterBoxForBrowseTitle:'global variable to browse users of:' |
|
18080 action:[:aString | |
|
18081 SystemBrowser browseReferendsOf:aString asSymbol |
|
18082 ] |
|
18083 ! |
|
18084 |
|
18085 methodImplementors |
|
18086 "launch an enterBox for selector to search for" |
|
18087 |
|
18088 self askForSelectorTitle:'selector to browse implementors of:' |
|
18089 openWith:#browseImplementorsOf: |
|
18090 ! |
|
18091 |
|
18092 methodInspect |
|
18093 "inspect the current method" |
|
18094 |
|
18095 self checkMethodSelected ifFalse:[^ self]. |
|
18096 (actualClass compiledMethodAt:currentSelector) inspect. |
|
18097 ! |
|
18098 |
|
18099 methodLocalAproposSearch |
|
18100 "launch an enterBox for a local keyword search" |
|
18101 |
|
18102 self askForSelectorTitle:'keyword to search for:' |
|
18103 openWith:#aproposSearch:in: |
|
18104 and:(currentClass withAllSubclasses) |
|
18105 ! |
|
18106 |
|
18107 methodLocalImplementors |
|
18108 "launch an enterBox for selector to search for" |
|
18109 |
|
18110 self checkClassSelected ifFalse:[^ self]. |
|
18111 self askForSelectorTitle:'selector to browse local implementors of:' |
|
18112 openWith:#browseImplementorsOf:under: |
|
18113 and:currentClass |
|
18114 ! |
|
18115 |
|
18116 methodLocalSenders |
|
18117 "launch an enterBox for selector to search for in current class & subclasses" |
|
18118 |
|
18119 self checkClassSelected ifFalse:[^ self]. |
|
18120 self askForSelectorTitle:'selector to browse local senders of:' |
|
18121 openWith:#browseCallsOn:under: |
|
18122 and:currentClass |
|
18123 ! |
|
18124 |
|
18125 methodLocalStringSearch |
|
18126 "launch an enterBox for string to search for" |
|
18127 |
|
18128 self checkClassSelected ifFalse:[^ self]. |
|
18129 self askForSelectorTitle:'string to search for in local methods:' |
|
18130 openWith:#browseForString:in: |
|
18131 and:(currentClass withAllSubclasses) |
|
18132 ! |
|
18133 |
|
18134 methodLocalSuperSends |
|
18135 "launch a browser showing super sends in current class & subclasses" |
|
18136 |
|
18137 self checkClassSelected ifFalse:[^ self]. |
|
18138 self withSearchCursorDo:[ |
|
18139 SystemBrowser browseSuperCallsUnder:currentClass |
|
18140 ] |
|
18141 |
|
18142 "Created: 23.11.1995 / 12:03:57 / cg" |
|
18143 "Modified: 23.11.1995 / 14:12:15 / cg" |
|
18144 ! |
|
18145 |
|
18146 methodMakePrivate |
|
18147 "make the current method private. |
|
18148 EXPERIMENTAL" |
|
18149 |
|
18150 self methodPrivacy:#private |
|
18151 ! |
|
18152 |
|
18153 methodMakeProtected |
|
18154 "make the current method protected. |
|
18155 EXPERIMENTAL" |
|
18156 |
|
18157 self methodPrivacy:#protected |
|
18158 ! |
|
18159 |
|
18160 methodMakePublic |
|
18161 "make the current method public. |
|
18162 EXPERIMENTAL" |
|
18163 |
|
18164 self methodPrivacy:#public |
|
18165 ! |
|
18166 |
|
18167 methodMenu |
|
18168 "return a popupmenu as appropriate for the methodList" |
|
18169 |
|
18170 |m labels selectors |
|
18171 newLabels newSelectors |
|
18172 mthdLabels mthdSelectors |
|
18173 brkLabels brkSelectors |
|
18174 fileLabels fileSelectors |
|
18175 searchLabels searchSelectors |
|
18176 sepLocalLabels sepLocalSelectors |
|
18177 localSearchLabels localSearchSelectors| |
|
18178 |
|
18179 device ctrlDown ifTrue:[ |
|
18180 "/ 'secret' developpers menu |
|
18181 |
|
18182 currentMethod isNil ifTrue:[ |
|
18183 methodListView flash. |
|
18184 ^ nil |
|
18185 ]. |
|
18186 labels := #( |
|
18187 'inspect method' |
|
18188 'compile to machine code' |
|
18189 'decompile' |
|
18190 '-' |
|
18191 'make private' |
|
18192 'make protected' |
|
18193 'make public' |
|
18194 ). |
|
18195 selectors := #( |
|
18196 methodInspect |
|
18197 methodSTCCompile |
|
18198 methodDecompile |
|
18199 nil |
|
18200 methodMakePrivate |
|
18201 methodMakeProtected |
|
18202 methodMakePublic |
|
18203 ) |
|
18204 ] ifFalse:[ |
|
18205 |
|
18206 sepLocalLabels := sepLocalSelectors := #(). |
|
18207 |
|
18208 searchLabels := #( |
|
18209 'senders ...' |
|
18210 'implementors ...' |
|
18211 'globals ...' |
|
18212 'string search ...' |
|
18213 'apropos ...' |
|
18214 ). |
|
18215 searchSelectors := #( |
|
18216 methodSenders |
|
18217 methodImplementors |
|
18218 methodGlobalReferends |
|
18219 methodStringSearch |
|
18220 methodAproposSearch |
|
18221 ). |
|
18222 |
|
18223 currentClass notNil ifTrue:[ |
|
18224 localSearchLabels := #( |
|
18225 '-' |
|
18226 'local senders ...' |
|
18227 'local implementors ...' |
|
18228 'local super sends ...' |
|
18229 'local string search ...' |
|
18230 'local apropos ...' |
|
18231 ). |
|
18232 localSearchSelectors := #( |
|
18233 nil |
|
18234 methodLocalSenders |
|
18235 methodLocalImplementors |
|
18236 methodLocalSuperSends |
|
18237 methodLocalStringSearch |
|
18238 methodLocalAproposSearch |
|
18239 ). |
|
18240 ] ifFalse:[ |
|
18241 localSearchLabels := localSearchSelectors := #() |
|
18242 ]. |
|
18243 |
|
18244 currentMethodCategory notNil ifTrue:[ |
|
18245 sepLocalLabels := #('-'). sepLocalSelectors := #(nil). |
|
18246 |
|
18247 newLabels := #( |
|
18248 'new method' |
|
18249 ). |
|
18250 |
|
18251 newSelectors := #( |
|
18252 methodNewMethod |
|
18253 ). |
|
18254 ] ifFalse:[ |
|
18255 newLabels := newSelectors := #() |
|
18256 ]. |
|
18257 |
|
18258 currentMethod notNil ifTrue:[ |
|
18259 fileLabels := #( |
|
18260 'fileOut' |
|
18261 'printOut' |
|
18262 '-' |
|
18263 'SPAWN_METHOD' |
|
18264 '-' |
|
18265 ). |
|
18266 |
|
18267 fileSelectors := #( |
|
18268 methodFileOut |
|
18269 methodPrintOut |
|
18270 nil |
|
18271 methodSpawn |
|
18272 nil |
|
18273 ). |
|
18274 |
|
18275 sepLocalLabels := #('-'). sepLocalSelectors := #(nil). |
|
18276 |
|
18277 mthdLabels := #( |
|
18278 'change category ...' |
|
18279 'remove' |
|
18280 ). |
|
18281 |
|
18282 mthdSelectors := #( |
|
18283 methodChangeCategory |
|
18284 methodRemove |
|
18285 ). |
|
18286 |
|
18287 currentMethod isWrapped ifTrue:[ |
|
18288 brkLabels := #( |
|
18289 'remove break/trace' |
|
18290 '-' |
|
18291 ). |
|
18292 |
|
18293 brkSelectors := #( |
|
18294 methodRemoveBreakOrTrace |
|
18295 nil |
|
18296 ) |
|
18297 ] ifFalse:[ |
|
18298 brkLabels := #( |
|
18299 'breakpoint' |
|
18300 'trace' |
|
18301 'trace sender' |
|
18302 '-' |
|
18303 ). |
|
18304 |
|
18305 brkSelectors := #( |
|
18306 methodBreakPoint |
|
18307 methodTrace |
|
18308 methodTraceSender |
|
18309 nil |
|
18310 ) |
|
18311 ] |
|
18312 ] ifFalse:[ |
|
18313 fileLabels := fileSelectors := #(). |
|
18314 brkLabels := brkSelectors := #(). |
|
18315 mthdLabels := mthdSelectors := #(). |
|
18316 ]. |
|
18317 |
|
18318 |
|
18319 |
|
18320 labels := |
|
18321 fileLabels , |
|
18322 searchLabels , |
|
18323 localSearchLabels , |
|
18324 sepLocalLabels , |
|
18325 brkLabels , |
|
18326 newLabels , |
|
18327 mthdLabels. |
|
18328 |
|
18329 selectors := |
|
18330 fileSelectors , |
|
18331 searchSelectors , |
|
18332 localSearchSelectors , |
|
18333 sepLocalSelectors , |
|
18334 brkSelectors , |
|
18335 newSelectors , |
|
18336 mthdSelectors. |
|
18337 |
|
18338 " |
|
18339 labels := #( |
|
18340 'fileOut' |
|
18341 'printOut' |
|
18342 '-' |
|
18343 'SPAWN_METHOD' |
|
18344 '-' |
|
18345 'senders ...' |
|
18346 'implementors ...' |
|
18347 'globals ...' |
|
18348 'string search ...' |
|
18349 'apropos ...' |
|
18350 '-' |
|
18351 'local senders ...' |
|
18352 'local implementors ...' |
|
18353 'local string search ...' |
|
18354 'local apropos ...' |
|
18355 '-' |
|
18356 'breakpoint' |
|
18357 'trace' |
|
18358 'trace sender' |
|
18359 '-' |
|
18360 'new method' |
|
18361 'change category ...' |
|
18362 'remove' |
|
18363 ). |
|
18364 selectors := #( |
|
18365 methodFileOut |
|
18366 methodPrintOut |
|
18367 nil |
|
18368 methodSpawn |
|
18369 nil |
|
18370 methodSenders |
|
18371 methodImplementors |
|
18372 methodGlobalReferends |
|
18373 methodStringSearch |
|
18374 methodAproposSearch |
|
18375 nil |
|
18376 methodLocalSenders |
|
18377 methodLocalImplementors |
|
18378 methodLocalStringSearch |
|
18379 methodLocalAproposSearch |
|
18380 nil |
|
18381 methodBreakPoint |
|
18382 methodTrace |
|
18383 methodTraceSender |
|
18384 nil |
|
18385 methodNewMethod |
|
18386 methodChangeCategory |
|
18387 methodRemove |
|
18388 ) |
|
18389 " |
|
18390 ]. |
|
18391 m := PopUpMenu |
|
18392 labels:(resources array:labels) |
|
18393 selectors:selectors. |
|
18394 |
|
18395 currentMethod notNil ifTrue:[ |
|
18396 currentMethod isPrivate ifTrue:[ |
|
18397 m disable:#methodMakePrivate |
|
18398 ]. |
|
18399 currentMethod isProtected ifTrue:[ |
|
18400 m disable:#methodMakeProtected |
|
18401 ]. |
|
18402 currentMethod isPublic ifTrue:[ |
|
18403 m disable:#methodMakePublic |
|
18404 ]. |
|
18405 ]. |
|
18406 currentMethod notNil ifTrue:[ |
|
18407 (currentMethod code notNil |
|
18408 or:[Compiler canCreateMachineCode not]) ifTrue:[ |
|
18409 m disable:#methodSTCCompile |
|
18410 ]. |
|
18411 currentMethod byteCode isNil ifTrue:[ |
|
18412 m disable:#methodDecompile |
|
18413 ]. |
|
18414 ]. |
|
18415 ^ m |
|
18416 |
|
18417 "Created: 23.11.1995 / 12:02:29 / cg" |
|
18418 ! |
|
18419 |
|
18420 methodNewMethod |
|
18421 "prepare for definition of a new method - put a template into |
|
18422 code view and define accept-action to compile it" |
|
18423 |
|
18424 currentClass isNil ifTrue:[ |
|
18425 ^ self warn:'select/create a class first'. |
|
18426 ]. |
|
18427 currentMethodCategory isNil ifTrue:[ |
|
18428 ^ self warn:'select/create a method category first'. |
|
18429 ]. |
|
18430 |
|
18431 currentMethod := currentSelector := nil. |
|
18432 |
|
18433 methodListView deselect. |
|
18434 codeView contents:(self template). |
|
18435 codeView modified:false. |
|
18436 |
|
18437 self setAcceptAndExplainActionsForMethod. |
|
18438 ! |
|
18439 |
|
18440 methodPrintOut |
|
18441 "print out the current method" |
|
18442 |
|
18443 |printStream| |
|
18444 |
|
18445 self checkMethodSelected ifFalse:[^ self]. |
|
18446 |
|
18447 printStream := Printer new. |
|
18448 actualClass printOutSource:(currentMethod source) on:printStream. |
|
18449 printStream close |
|
18450 ! |
|
18451 |
|
18452 methodPrivacy:how |
|
18453 "change the current methods privacy. |
|
18454 EXPERIMENTAL" |
|
18455 |
|
18456 self checkMethodSelected ifFalse:[^ self]. |
|
18457 currentMethod isPublic ifFalse:[ |
|
18458 currentMethod privacy:how. |
|
18459 actualClass updateRevisionString. |
|
18460 actualClass addChangeRecordForMethodPrivacy:currentMethod. |
|
18461 self updateMethodListWithScroll:false keepSelection:true. |
|
18462 ] |
|
18463 |
|
18464 "Created: 29.10.1995 / 20:00:00 / cg" |
|
18465 ! |
|
18466 |
|
18467 methodRemove |
|
18468 "remove the current method" |
|
18469 |
|
18470 self checkMethodSelected ifFalse:[^ self]. |
|
18471 actualClass removeSelector:(actualClass selectorAtMethod:currentMethod). |
|
18472 currentMethod := currentSelector := nil. |
|
18473 self updateMethodListWithScroll:false |
|
18474 ! |
|
18475 |
|
18476 methodRemoveBreakOrTrace |
|
18477 "turn off tracing of the current method" |
|
18478 |
|
18479 (currentMethod notNil and:[currentMethod isWrapped]) ifTrue:[ |
|
18480 self commonTraceHelperWith:#unwrapMethod: |
|
18481 ] |
|
18482 ! |
|
18483 |
|
18484 methodSTCCompile |
|
18485 "compile the current method to machine code. |
|
18486 This is not supported on all machines, and never supported in |
|
18487 the demo version." |
|
18488 |
|
18489 |prev| |
|
18490 |
|
18491 self checkMethodSelected ifFalse:[^ self]. |
|
18492 prev := Compiler stcCompilation:#always. |
|
18493 [ |
|
18494 codeView accept. |
|
18495 ] valueNowOrOnUnwindDo:[ |
|
18496 Compiler stcCompilation:prev |
|
18497 ]. |
|
18498 ! |
|
18499 |
|
18500 methodSenders |
|
18501 "launch an enterBox for selector to search for" |
|
18502 |
|
18503 self askForSelectorTitle:'selector to browse senders of:' |
|
18504 openWith:#browseAllCallsOn: |
|
18505 ! |
|
18506 |
|
18507 methodSpawn |
|
18508 "create a new SystemBrowser browsing current method, |
|
18509 or if the current selection is of the form 'class>>selector', spawan |
|
18510 a browser on that method." |
|
18511 |
|
18512 |s sel selSymbol clsName clsSymbol cls isMeta w| |
|
18513 |
|
18514 classMethodListView notNil ifTrue:[ |
|
18515 s := classMethodListView selectionValue. |
|
18516 clsName := self classFromClassMethodString:s. |
|
18517 sel := self selectorFromClassMethodString:s. |
|
18518 isMeta := false |
|
18519 ]. |
|
18520 |
|
18521 self extractClassAndSelectorFromSelectionInto:[:c :s :m | |
|
18522 clsName := c. |
|
18523 sel := s. |
|
18524 isMeta := m |
|
18525 ]. |
|
18526 |
|
18527 (sel notNil and:[clsName notNil]) ifTrue:[ |
|
18528 (clsName knownAsSymbol and:[sel knownAsSymbol]) ifTrue:[ |
|
18529 clsSymbol := clsName asSymbol. |
|
18530 (Smalltalk includesKey:clsSymbol) ifTrue:[ |
|
18531 cls := Smalltalk at:clsSymbol. |
|
18532 isMeta ifTrue:[ |
|
18533 cls := cls class |
|
18534 ]. |
|
18535 cls isBehavior ifFalse:[ |
|
18536 cls := cls class |
|
18537 ]. |
|
18538 cls isBehavior ifTrue:[ |
|
18539 selSymbol := sel asSymbol. |
|
18540 self withWaitCursorDo:[ |
|
18541 (cls implements:selSymbol) ifFalse:[ |
|
18542 cls := cls class. |
|
18543 ]. |
|
18544 (cls implements:selSymbol) ifTrue:[ |
|
18545 SystemBrowser browseClass:cls selector:selSymbol. |
|
18546 ^ self |
|
18547 ]. |
|
18548 w := ' does not implement #' , sel |
|
18549 ] |
|
18550 ] ifFalse:[ |
|
18551 w := ' is not a class' |
|
18552 ] |
|
18553 ] ifFalse:[ |
|
18554 w := ' is unknown' |
|
18555 ] |
|
18556 ] ifFalse:[ |
|
18557 w := ' and/or ' , sel , ' are unknown' |
|
18558 ]. |
|
18559 self warn:(clsName , w). |
|
18560 ^ self |
|
18561 ]. |
|
18562 |
|
18563 self checkMethodSelected ifFalse:[ |
|
18564 self warn:'select a method first'. |
|
18565 ^ self |
|
18566 ]. |
|
18567 |
|
18568 self withWaitCursorDo:[ |
|
18569 w := currentMethod who. |
|
18570 SystemBrowser browseClass:(w at:1) selector:(w at:2) |
|
18571 ] |
|
18572 ! |
|
18573 |
|
18574 methodStringSearch |
|
18575 "launch an enterBox for string to search for" |
|
18576 |
|
18577 self askForSelectorTitle:'string to search for in sources:' |
|
18578 openWith:#browseForString: |
|
18579 ! |
|
18580 |
|
18581 methodTrace |
|
18582 "turn on tracing of the current method" |
|
18583 |
|
18584 currentClass notNil ifTrue:[ |
|
18585 currentSelector notNil ifTrue:[ |
|
18586 currentMethod := actualClass compiledMethodAt:currentSelector |
|
18587 ] |
|
18588 ]. |
|
18589 |
|
18590 (currentMethod notNil and:[currentMethod isWrapped not]) ifTrue:[ |
|
18591 self commonTraceHelperWith:#traceMethod: |
|
18592 ] |
|
18593 ! |
|
18594 |
|
18595 methodTraceSender |
|
18596 "turn on tracing of the current method" |
|
18597 |
|
18598 (currentMethod notNil and:[currentMethod isWrapped not]) ifTrue:[ |
|
18599 self commonTraceHelperWith:#traceMethodSender: |
|
18600 ] |
|
18601 ! ! |
|
18602 |
|
18603 !BrowserView methodsFor:'method stuff'! |
|
18604 |
|
18605 checkMethodSelected |
|
18606 currentMethod isNil ifTrue:[ |
|
18607 self warn:'select a method first'. |
|
18608 ^ false |
|
18609 ]. |
|
18610 ^ true |
|
18611 ! |
|
18612 |
|
18613 listOfAllSelectorsInCategory:aCategory inFullProtocolHierarchyOfClass:aClass |
|
18614 "answer a list of all selectors in a given method category |
|
18615 of the argument, aClass and its superclasses. |
|
18616 Used with fullProtocol browsing." |
|
18617 |
|
18618 |newList| |
|
18619 |
|
18620 newList := Set new. |
|
18621 self classesInFullProtocolHierarchy:aClass do:[:c | |
|
18622 |searchCategory| |
|
18623 |
|
18624 (aCategory = '* all *') ifTrue:[ |
|
18625 newList addAll:(c selectorArray) |
|
18626 ] ifFalse:[ |
|
18627 (aCategory = '* no category *') ifTrue:[ |
|
18628 searchCategory := nil |
|
18629 ] ifFalse:[ |
|
18630 searchCategory := aCategory |
|
18631 ]. |
|
18632 c methodArray with:c selectorArray do:[:aMethod :selector | |
|
18633 (aMethod category = searchCategory) ifTrue:[ |
|
18634 newList add:selector |
|
18635 ] |
|
18636 ] |
|
18637 ]. |
|
18638 ]. |
|
18639 (newList size == 0) ifTrue:[^ nil]. |
|
18640 ^ newList asOrderedCollection sort |
|
18641 ! |
|
18642 |
|
18643 listOfAllSelectorsInCategory:aCategory ofClass:aClass |
|
18644 "answer a list of all selectors in a given method category |
|
18645 of the argument, aClass" |
|
18646 |
|
18647 |newList searchCategory all p| |
|
18648 |
|
18649 all := (aCategory = '* all *'). |
|
18650 (aCategory = '* no category *') ifTrue:[ |
|
18651 searchCategory := nil |
|
18652 ] ifFalse:[ |
|
18653 searchCategory := aCategory |
|
18654 ]. |
|
18655 newList := OrderedCollection new. |
|
18656 aClass methodArray with:aClass selectorArray do:[:aMethod :selector | |
|
18657 |sel how| |
|
18658 |
|
18659 (all or:[aMethod category = searchCategory]) ifTrue:[ |
|
18660 sel := selector. |
|
18661 (p := aMethod privacy) ~~ #public ifTrue:[ |
|
18662 how := ' (* ' , p , ' *)'. |
|
18663 ]. |
|
18664 aMethod isWrapped ifTrue:[ |
|
18665 how := ' !!' |
|
18666 ]. |
|
18667 aMethod isInvalid ifTrue:[ |
|
18668 how := ' (** not executable **)' |
|
18669 ]. |
|
18670 aMethod isLazyMethod ifTrue:[ |
|
18671 "/ how := ' (lazy)' |
|
18672 ] ifFalse:[ |
|
18673 (aMethod code isNil |
|
18674 and:[aMethod byteCode isNil]) ifTrue:[ |
|
18675 how := ' (** unloaded **)' |
|
18676 ] |
|
18677 ]. |
|
18678 how notNil ifTrue:[sel := sel , how]. |
|
18679 newList add:sel |
|
18680 ] |
|
18681 ]. |
|
18682 (newList size == 0) ifTrue:[^ nil]. |
|
18683 ^ newList sort |
|
18684 |
|
18685 "Modified: 28.8.1995 / 21:53:34 / claus" |
|
18686 ! |
|
18687 |
|
18688 methodSelection:lineNr |
|
18689 "user clicked on a method line - show code" |
|
18690 |
|
18691 |selectorString selectorSymbol| |
|
18692 |
|
18693 (fullProtocol not and:[currentClass isNil]) ifTrue:[^ self]. |
|
18694 |
|
18695 selectorString := methodListView selectionValue. |
|
18696 " |
|
18697 kludge: extract real selector |
|
18698 " |
|
18699 selectorString := selectorString withoutSpaces upTo:(Character space). |
|
18700 selectorSymbol := selectorString asSymbol. |
|
18701 fullProtocol ifTrue:[ |
|
18702 currentMethod := currentSelector := nil. |
|
18703 " |
|
18704 search which class implements the selector |
|
18705 " |
|
18706 self classesInFullProtocolHierarchy:actualClass do:[:c | |
|
18707 (currentMethod isNil |
|
18708 and:[c implements:selectorSymbol]) ifTrue:[ |
|
18709 currentSelector := selectorSymbol. |
|
18710 currentMethod := c compiledMethodAt:selectorSymbol. |
|
18711 acceptClass := c |
|
18712 ] |
|
18713 ] |
|
18714 ] ifFalse:[ |
|
18715 currentSelector := selectorSymbol. |
|
18716 currentMethod := actualClass compiledMethodAt:selectorSymbol. |
|
18717 ]. |
|
18718 |
|
18719 methodCategoryListView notNil ifTrue:[ |
|
18720 currentMethod notNil ifTrue:[ |
|
18721 (currentMethodCategory = currentMethod category) ifFalse:[ |
|
18722 currentMethodCategory := currentMethod category. |
|
18723 methodCategoryListView selectElement:currentMethodCategory |
|
18724 ] |
|
18725 ] |
|
18726 ]. |
|
18727 |
|
18728 self methodSelectionChanged |
|
18729 ! |
|
18730 |
|
18731 methodSelectionChanged |
|
18732 "method selection has changed - update dependent views" |
|
18733 |
|
18734 self withWaitCursorDo:[ |
|
18735 |index cls| |
|
18736 |
|
18737 self updateCodeView. |
|
18738 aspect := nil. |
|
18739 self setAcceptAndExplainActionsForMethod. |
|
18740 |
|
18741 " |
|
18742 if there is any autoSearch string, do the search |
|
18743 " |
|
18744 autoSearch notNil ifTrue:[ |
|
18745 codeView searchFwd:autoSearch startingAtLine:1 col:0 ifAbsent:[] |
|
18746 ]. |
|
18747 |
|
18748 fullProtocol ifTrue:[ |
|
18749 " |
|
18750 remove any bold attribute from classList |
|
18751 " |
|
18752 1 to:classListView list size do:[:i | |
|
18753 classListView attributeAt:i remove:#bold. |
|
18754 ]. |
|
18755 " |
|
18756 boldify the class where this method is implemented |
|
18757 " |
|
18758 currentMethod notNil ifTrue:[ |
|
18759 cls := currentMethod who at:1. |
|
18760 index := classListView list indexOf:(cls name). |
|
18761 (index == 0 |
|
18762 and:[cls isMeta |
|
18763 and:[cls name endsWith:'class']]) ifTrue:[ |
|
18764 index := classListView list indexOf:(cls name copyWithoutLast:5). |
|
18765 ]. |
|
18766 index ~~ 0 ifTrue:[ |
|
18767 classListView attributeAt:index add:#bold. |
|
18768 ]. |
|
18769 currentClass := acceptClass := cls. |
|
18770 ] |
|
18771 ]. |
|
18772 ] |
|
18773 |
|
18774 "Created: 23.11.1995 / 14:17:44 / cg" |
|
18775 ! |
|
18776 |
|
18777 switchToAnyMethodNamed:aString |
|
18778 |aSelector classToStartSearch aClass nm| |
|
18779 |
|
18780 aSelector := aString asSymbol. |
|
18781 currentClass isNil ifTrue:[ |
|
18782 currentClassHierarchy notNil ifTrue:[ |
|
18783 classToStartSearch := currentClassHierarchy |
|
18784 ] |
|
18785 ] ifFalse:[ |
|
18786 classToStartSearch := currentClass |
|
18787 ]. |
|
18788 classToStartSearch notNil ifTrue:[ |
|
18789 showInstance ifFalse:[ |
|
18790 classToStartSearch := classToStartSearch class |
|
18791 ]. |
|
18792 aClass := classToStartSearch whichClassIncludesSelector:aSelector. |
|
18793 aClass notNil ifTrue:[ |
|
18794 nm := aClass name. |
|
18795 showInstance ifFalse:[ |
|
18796 ((nm ~= 'Metaclass') and:[nm endsWith:'class']) ifTrue:[ |
|
18797 nm := nm copyWithoutLast:5 "copyTo:(nm size - 5)" |
|
18798 ] |
|
18799 ]. |
|
18800 self switchToClassNamed:nm. |
|
18801 self switchToMethodNamed:aString |
|
18802 ] |
|
18803 ] |
|
18804 ! |
|
18805 |
|
18806 switchToMethodNamed:matchString |
|
18807 "switch (in the current class) to a method named matchString. |
|
18808 If there are more than one matches, switch to the first." |
|
18809 |
|
18810 |aSelector method cat index classToSearch selectors| |
|
18811 |
|
18812 currentClass notNil ifTrue:[ |
|
18813 showInstance ifTrue:[ |
|
18814 classToSearch := currentClass |
|
18815 ] ifFalse:[ |
|
18816 classToSearch := currentClass class |
|
18817 ]. |
|
18818 selectors := classToSearch selectorArray. |
|
18819 |
|
18820 ((matchString ~= '*') and:[matchString includesMatchCharacters]) ifTrue:[ |
|
18821 index := selectors findFirst:[:element | matchString match:element] |
|
18822 ] ifFalse:[ |
|
18823 index := selectors indexOf:matchString |
|
18824 ]. |
|
18825 |
|
18826 (index ~~ 0) ifTrue:[ |
|
18827 aSelector := selectors at:index. |
|
18828 method := classToSearch methodArray at:index. |
|
18829 cat := method category. |
|
18830 cat isNil ifTrue:[cat := '* all *']. |
|
18831 methodCategoryListView selectElement:cat. |
|
18832 currentMethodCategory := cat. |
|
18833 self updateMethodCategoryListWithScroll:false. |
|
18834 self methodCategorySelectionChanged. |
|
18835 |
|
18836 currentMethod := classToSearch compiledMethodAt:aSelector. |
|
18837 currentMethod notNil ifTrue:[ |
|
18838 currentSelector := aSelector. |
|
18839 methodListView selectElement:aSelector. |
|
18840 ]. |
|
18841 self methodSelectionChanged |
|
18842 ] |
|
18843 ] |
|
18844 ! |
|
18845 |
|
18846 template |
|
18847 "return a method definition template" |
|
18848 |
|
18849 ^ |
|
18850 'message selector and argument names |
|
18851 "comment stating purpose of message" |
|
18852 |
|
18853 |
|
18854 |temporaries| |
|
18855 statements |
|
18856 |
|
18857 |
|
18858 " |
|
18859 change above template into real code. |
|
18860 Then ''accept'' either via the menu |
|
18861 or via the keyboard (usually CMD-A). |
|
18862 |
|
18863 You do not need this template; you can also |
|
18864 select any existing methods code, change it, |
|
18865 and finally ''accept''. |
|
18866 " |
|
18867 ' |
|
18868 ! |
|
18869 |
|
18870 updateMethodList |
|
18871 self updateMethodListWithScroll:true keepSelection:false |
|
18872 ! |
|
18873 |
|
18874 updateMethodListWithScroll:scroll |
|
18875 self updateMethodListWithScroll:scroll keepSelection:false |
|
18876 ! |
|
18877 |
|
18878 updateMethodListWithScroll:scroll keepSelection:keep |
|
18879 |selectors scr first last selection| |
|
18880 |
|
18881 |
|
18882 methodListView notNil ifTrue:[ |
|
18883 selection := methodListView selection. |
|
18884 |
|
18885 currentMethodCategory notNil ifTrue:[ |
|
18886 fullProtocol ifTrue:[ |
|
18887 selectors := self listOfAllSelectorsInCategory:currentMethodCategory |
|
18888 inFullProtocolHierarchyOfClass:actualClass |
|
18889 ] ifFalse:[ |
|
18890 selectors := self listOfAllSelectorsInCategory:currentMethodCategory |
|
18891 ofClass:actualClass |
|
18892 ] |
|
18893 ]. |
|
18894 scr := scroll. |
|
18895 first := methodListView firstLineShown. |
|
18896 first ~~ 1 ifTrue:[ |
|
18897 last := methodListView lastLineShown. |
|
18898 selectors size <= (last - first + 1) ifTrue:[ |
|
18899 scr := true |
|
18900 ] |
|
18901 ]. |
|
18902 methodListView list = selectors ifFalse:[ |
|
18903 scr ifTrue:[ |
|
18904 methodListView contents:selectors |
|
18905 ] ifFalse:[ |
|
18906 methodListView setContents:selectors |
|
18907 ] |
|
18908 ]. |
|
18909 keep ifTrue:[ |
|
18910 methodListView selection:selection. |
|
18911 ] |
|
18912 ] |
|
18913 ! ! |
|
18914 |
|
18915 !BrowserView methodsFor:'misc'! |
|
18916 |
|
18917 instanceProtocol:aBoolean |
|
18918 "switch between instance and class protocol" |
|
18919 |
|
18920 |onToggle offToggle| |
|
18921 |
|
18922 showInstance ~~ aBoolean ifTrue:[ |
|
18923 self checkSelectionChangeAllowed ifTrue:[ |
|
18924 instanceToggle notNil ifTrue:[ |
|
18925 aBoolean ifTrue:[ |
|
18926 offToggle := classToggle. |
|
18927 onToggle := instanceToggle. |
|
18928 ] ifFalse:[ |
|
18929 onToggle := classToggle. |
|
18930 offToggle := instanceToggle. |
|
18931 ]. |
|
18932 onToggle turnOn. |
|
18933 offToggle turnOff. |
|
18934 ]. |
|
18935 showInstance := aBoolean. |
|
18936 |
|
18937 (variableListView notNil |
|
18938 and:[variableListView hasSelection]) ifTrue:[ |
|
18939 self unhilightMethodCategories. |
|
18940 self unhilightMethods. |
|
18941 variableListView deselect |
|
18942 ]. |
|
18943 |
|
18944 fullProtocol ifTrue:[ |
|
18945 showInstance ifTrue:[ |
|
18946 actualClass := currentClassHierarchy. |
|
18947 ] ifFalse:[ |
|
18948 actualClass := currentClassHierarchy class. |
|
18949 ]. |
|
18950 acceptClass := actualClass. |
|
18951 |
|
18952 self updateClassList. |
|
18953 self updateMethodCategoryListWithScroll:false. |
|
18954 self updateMethodListWithScroll:false. |
|
18955 self updateVariableList. |
|
18956 ^ self |
|
18957 ]. |
|
18958 currentClass notNil ifTrue:[ |
|
18959 self classSelectionChanged |
|
18960 ]. |
|
18961 codeView modified:false. |
|
18962 ] ifFalse:[ |
|
18963 aBoolean ifTrue:[ |
|
18964 onToggle := classToggle. |
|
18965 offToggle := instanceToggle |
|
18966 ] ifFalse:[ |
|
18967 offToggle := classToggle. |
|
18968 onToggle := instanceToggle. |
|
18969 ]. |
|
18970 onToggle turnOn. |
|
18971 offToggle turnOff. |
|
18972 ] |
|
18973 ] |
|
18974 ! |
|
18975 |
|
18976 processName |
|
18977 "the name of my process - for the processMonitor only" |
|
18978 |
|
18979 ^ 'System Browser'. |
|
18980 ! |
|
18981 |
|
18982 updateCodeView |
|
18983 |code| |
|
18984 |
|
18985 fullClass ifTrue:[ |
|
18986 currentClass notNil ifTrue:[ |
|
18987 code := currentClass source. |
|
18988 ] |
|
18989 ] ifFalse:[ |
|
18990 currentMethod notNil ifTrue:[ |
|
18991 (codeView acceptAction isNil |
|
18992 and:[actualClass notNil |
|
18993 and:[currentMethodCategory notNil]]) ifTrue:[ |
|
18994 self setAcceptAndExplainActionsForMethod. |
|
18995 ]. |
|
18996 |
|
18997 code := currentMethod source. |
|
18998 |
|
18999 ] |
|
19000 ]. |
|
19001 codeView contents:code. |
|
19002 codeView modified:false. |
|
19003 |
|
19004 self normalLabel. |
|
19005 |
|
19006 "Created: 23.11.1995 / 14:16:43 / cg" |
|
19007 "Modified: 23.11.1995 / 14:19:25 / cg" |
|
19008 ! ! |
|
19009 |
|
19010 !BrowserView methodsFor:'private'! |
|
19011 |
|
19012 askAndBrowseMethodCategory:title action:aBlock |
|
19013 "convenient method: setup enterBox with initial being current method category" |
|
19014 |
|
19015 |sel box| |
|
19016 |
|
19017 box := self enterBoxTitle:title okText:'browse'. |
|
19018 sel := codeView selection. |
|
19019 sel isNil ifTrue:[ |
|
19020 currentMethodCategory notNil ifTrue:[ |
|
19021 sel := currentMethodCategory |
|
19022 ] |
|
19023 ]. |
|
19024 sel notNil ifTrue:[ |
|
19025 box initialText:(sel asString withoutSpaces) |
|
19026 ]. |
|
19027 box action:[:aString | self withWaitCursorDo:[aBlock value:aString]]. |
|
19028 box showAtPointer |
|
19029 ! |
|
19030 |
|
19031 askForMethodCategory |
|
19032 |someCategories box txt| |
|
19033 |
|
19034 someCategories := actualClass categories sort. |
|
19035 box := self listBoxTitle:'accept in which method category ?' okText:'accept' list:someCategories. |
|
19036 |
|
19037 lastMethodCategory isNil ifTrue:[ |
|
19038 txt := 'new methods' |
|
19039 ] ifFalse:[ |
|
19040 txt := lastMethodCategory |
|
19041 ]. |
|
19042 box initialText:txt. |
|
19043 box action:[:aString | ^ aString ]. |
|
19044 box showAtPointer. |
|
19045 ^ nil |
|
19046 ! |
|
19047 |
|
19048 askForSelectorTitle:title |
|
19049 "convenient method: setup enterBox with text from codeView or selected |
|
19050 method for browsing based on a selector. Set action and launch box" |
|
19051 |
|
19052 |box| |
|
19053 |
|
19054 box := self enterBoxTitle:title okText:'browse'. |
|
19055 box initialText:(self selectorToSearchFor). |
|
19056 box action:[:aString | aString isEmpty ifTrue:[^ nil]. ^ aString]. |
|
19057 box showAtPointer. |
|
19058 ^ nil |
|
19059 ! |
|
19060 |
|
19061 askForSelectorTitle:title openWith:selector |
|
19062 "convenient method: setup enterBox with text from codeView or selected |
|
19063 method for browsing based on a selector. Set action and launch box" |
|
19064 |
|
19065 |string| |
|
19066 |
|
19067 string := self askForSelectorTitle:title. |
|
19068 string notNil ifTrue:[ |
|
19069 self withSearchCursorDo:[ |
|
19070 SystemBrowser perform:selector with:string |
|
19071 ] |
|
19072 ]. |
|
19073 |
|
19074 "Created: 23.11.1995 / 14:11:34 / cg" |
|
19075 ! |
|
19076 |
|
19077 askForSelectorTitle:title openWith:selector and:arg |
|
19078 "convenient method: setup enterBox with text from codeView or selected |
|
19079 method for browsing based on a selector. Set action and launch box" |
|
19080 |
|
19081 |string| |
|
19082 |
|
19083 string := self askForSelectorTitle:title. |
|
19084 string notNil ifTrue:[ |
|
19085 self withSearchCursorDo:[ |
|
19086 SystemBrowser perform:selector with:string with:arg |
|
19087 ] |
|
19088 ]. |
|
19089 |
|
19090 "Created: 23.11.1995 / 14:11:38 / cg" |
|
19091 ! |
|
19092 |
|
19093 busyLabel:what with:someArgument |
|
19094 "set the title for some warning" |
|
19095 |
|
19096 self label:('System Browser - ' , (resources string:what with:someArgument)) |
|
19097 ! |
|
19098 |
|
19099 checkSelectionChangeAllowed |
|
19100 "return true, if selection change is ok; |
|
19101 its not ok, if code has been changed. |
|
19102 in this case, return the result of a user query" |
|
19103 |
|
19104 |what m src v| |
|
19105 |
|
19106 currentMethod notNil ifTrue:[ |
|
19107 m := actualClass compiledMethodAt:currentSelector. |
|
19108 m notNil ifTrue:[ |
|
19109 (src := m source) = codeView contents ifFalse:[ |
|
19110 what := self checkSelectionChangeAllowedWithCompare:true. |
|
19111 what == #compare ifTrue:[ |
|
19112 v := DiffTextView |
|
19113 openOn:codeView contents label:'code here (to be accepted ?)' |
|
19114 and:src label:'methods actual code'. |
|
19115 v label:'comparing method versions'. |
|
19116 ^ false |
|
19117 ]. |
|
19118 ^ what |
|
19119 ] |
|
19120 ] |
|
19121 ]. |
|
19122 |
|
19123 ^ self checkSelectionChangeAllowedWithCompare:false |
|
19124 |
|
19125 "Created: 24.11.1995 / 11:03:33 / cg" |
|
19126 "Modified: 24.11.1995 / 11:05:49 / cg" |
|
19127 ! |
|
19128 |
|
19129 checkSelectionChangeAllowedWithCompare:compareOffered |
|
19130 "return true, if selection change is ok; |
|
19131 its not ok, if code has been changed. |
|
19132 in this case, return the result of a user query" |
|
19133 |
|
19134 |action labels values| |
|
19135 |
|
19136 codeView modified ifFalse:[ |
|
19137 ^ true |
|
19138 ]. |
|
19139 |
|
19140 compareOffered ifTrue:[ |
|
19141 labels := #('abort' 'compare' 'accept' 'continue'). |
|
19142 values := #(false #compare #accept true). |
|
19143 ] ifFalse:[ |
|
19144 labels := #('abort' 'accept' 'continue'). |
|
19145 values := #(false #accept true). |
|
19146 ]. |
|
19147 |
|
19148 action := OptionBox |
|
19149 request:(resources at:'text has not been accepted.\\Your modifications will be lost when continuing.') withCRs |
|
19150 label:(resources string:'Attention') |
|
19151 form:(WarningBox iconBitmap) |
|
19152 buttonLabels:(resources array:labels) |
|
19153 values:values |
|
19154 default:true. |
|
19155 action ~~ #accept ifTrue:[ |
|
19156 ^ action |
|
19157 ]. |
|
19158 codeView accept. |
|
19159 ^ true |
|
19160 |
|
19161 "Created: 24.11.1995 / 10:54:46 / cg" |
|
19162 ! |
|
19163 |
|
19164 classHierarchyDo:aBlock |
|
19165 "eavluate the 2-arg block for every class, |
|
19166 starting at Object; passing class and nesting level to the block." |
|
19167 |
|
19168 |classes s classDict l| |
|
19169 |
|
19170 classes := Smalltalk allClasses. |
|
19171 classDict := IdentityDictionary new:classes size. |
|
19172 classes do:[:aClass | |
|
19173 s := aClass superclass. |
|
19174 s notNil ifTrue:[ |
|
19175 l := classDict at:s ifAbsent:[nil]. |
|
19176 l isNil ifTrue:[ |
|
19177 l := OrderedCollection new:5. |
|
19178 classDict at:s put:l |
|
19179 ]. |
|
19180 l add:aClass |
|
19181 ] |
|
19182 ]. |
|
19183 self classHierarchyOf:Object level:0 do:aBlock using:classDict |
|
19184 ! |
|
19185 |
|
19186 classHierarchyOf:aClass level:level do:aBlock using:aDictionary |
|
19187 "evaluate the 2-arg block for every subclass of aClass, |
|
19188 passing class and nesting level to the block." |
|
19189 |
|
19190 |names subclasses| |
|
19191 |
|
19192 aBlock value:aClass value:level. |
|
19193 subclasses := aDictionary at:aClass ifAbsent:[nil]. |
|
19194 (subclasses size == 0) ifFalse:[ |
|
19195 names := subclasses collect:[:class | class name]. |
|
19196 names sortWith:subclasses. |
|
19197 subclasses do:[:aSubClass | |
|
19198 self classHierarchyOf:aSubClass level:(level + 1) do:aBlock using:aDictionary |
|
19199 ] |
|
19200 ] |
|
19201 ! |
|
19202 |
|
19203 classesInFullProtocolHierarchy:aClass do:aBlock |
|
19204 "evaluate aBlock for all non-striked out classes in |
|
19205 the hierarchy" |
|
19206 |
|
19207 |index| |
|
19208 |
|
19209 index := (classListView list size). |
|
19210 aClass withAllSuperclasses do:[:c | |
|
19211 (classListView isInSelection:index) ifFalse:[ |
|
19212 aBlock value:c |
|
19213 ]. |
|
19214 index := index - 1 |
|
19215 ] |
|
19216 |
|
19217 ! |
|
19218 |
|
19219 classesInHierarchy:aClass do:aBlock |
|
19220 |index| |
|
19221 |
|
19222 index := (classListView list size). |
|
19223 aClass withAllSuperclasses do:[:c | |
|
19224 (classListView isInSelection:index) ifFalse:[ |
|
19225 aBlock value:c |
|
19226 ]. |
|
19227 index := index - 1 |
|
19228 ] |
|
19229 |
|
19230 ! |
|
19231 |
|
19232 compileCode:someCode |
|
19233 (ReadStream on:someCode) fileIn |
|
19234 ! |
|
19235 |
|
19236 enterBoxForBrowseTitle:title action:aBlock |
|
19237 "convenient method: setup enterBox with text from codeView or selected |
|
19238 method for method browsing based on className/variable" |
|
19239 |
|
19240 |box| |
|
19241 |
|
19242 box := self enterBoxTitle:title okText:'browse'. |
|
19243 box initialText:(self stringToSearchFor). |
|
19244 box action:[:aString | |
|
19245 aString notEmpty ifTrue:[ |
|
19246 self withWaitCursorDo:[aBlock value:aString] |
|
19247 ]. |
|
19248 ]. |
|
19249 box showAtPointer |
|
19250 ! |
|
19251 |
|
19252 enterBoxForCodeSelectionTitle:title okText:okText |
|
19253 "convenient method: setup enterBox with text from codeview" |
|
19254 |
|
19255 |sel box| |
|
19256 |
|
19257 box := self enterBoxTitle:(resources string:title) okText:(resources string:okText). |
|
19258 sel := codeView selection. |
|
19259 sel notNil ifTrue:[ |
|
19260 box initialText:(sel asString withoutSeparators) |
|
19261 ]. |
|
19262 ^ box |
|
19263 ! |
|
19264 |
|
19265 enterBoxForSearchSelectorTitle:title |
|
19266 "convenient method: setup enterBox with text from codeView or selected |
|
19267 method for browsing based on a selector" |
|
19268 |
|
19269 |box| |
|
19270 |
|
19271 box := self enterBoxTitle:title okText:'search'. |
|
19272 box initialText:(self selectorToSearchFor). |
|
19273 ^ box |
|
19274 ! |
|
19275 |
|
19276 enterBoxTitle:title okText:okText |
|
19277 "convenient method: setup enterBox" |
|
19278 |
|
19279 |box| |
|
19280 |
|
19281 box := EnterBox new. |
|
19282 box title:(resources string:title) okText:(resources string:okText). |
|
19283 ^ box |
|
19284 ! |
|
19285 |
|
19286 extractClassAndSelectorFromSelectionInto:aBlock |
|
19287 "given a string which can be either 'class>>sel' or |
|
19288 'class sel', extract className and selector, and call aBlock with |
|
19289 the result." |
|
19290 |
|
19291 |sel clsName isMeta sep s| |
|
19292 |
|
19293 sel := codeView selection. |
|
19294 sel notNil ifTrue:[ |
|
19295 sel := sel asString withoutSeparators. |
|
19296 ('*>>*' match:sel) ifTrue:[ |
|
19297 sep := $> |
|
19298 ] ifFalse:[ |
|
19299 ('* *' match:sel) ifTrue:[ |
|
19300 sep := Character space |
|
19301 ] |
|
19302 ]. |
|
19303 sep notNil ifTrue:[ |
|
19304 " |
|
19305 extract class/sel from selection |
|
19306 " |
|
19307 s := ReadStream on:sel. |
|
19308 clsName := s upTo:sep. |
|
19309 [s peek == sep] whileTrue:[s next]. |
|
19310 sel := s upToEnd. |
|
19311 |
|
19312 (clsName endsWith:'class') ifTrue:[ |
|
19313 isMeta := true. |
|
19314 clsName := clsName copyWithoutLast:5 "copyTo:(clsName size - 5)" |
|
19315 ] ifFalse:[ |
|
19316 isMeta := false |
|
19317 ]. |
|
19318 ] |
|
19319 ]. |
|
19320 aBlock value:clsName value:sel value:isMeta |
|
19321 |
|
19322 |
|
19323 ! |
|
19324 |
|
19325 findClassOfVariable:aVariableName accessWith:aSelector |
|
19326 "this method returns the class, in which a variable |
|
19327 is defined; |
|
19328 needs either #instVarNames or #classVarNames as aSelector." |
|
19329 |
|
19330 |cls homeClass| |
|
19331 |
|
19332 " |
|
19333 first, find the class, where the variable is declared |
|
19334 " |
|
19335 cls := currentClass. |
|
19336 [cls notNil] whileTrue:[ |
|
19337 ((cls perform:aSelector) includes:aVariableName) ifTrue:[ |
|
19338 homeClass := cls. |
|
19339 cls := nil. |
|
19340 ] ifFalse:[ |
|
19341 cls := cls superclass |
|
19342 ] |
|
19343 ]. |
|
19344 homeClass isNil ifTrue:[ |
|
19345 "nope, must be one below ... (could optimize a bit, by searching down |
|
19346 for the declaring class ... |
|
19347 " |
|
19348 homeClass := currentClass |
|
19349 ] ifFalse:[ |
|
19350 "/ Transcript showCr:'starting search in ' , homeClass name. |
|
19351 ]. |
|
19352 ^ homeClass |
|
19353 ! |
|
19354 |
|
19355 listBoxForCodeSelectionTitle:title okText:okText |
|
19356 "convenient method: setup listBox with text from codeview" |
|
19357 |
|
19358 |sel box| |
|
19359 |
|
19360 box := self listBoxTitle:title okText:okText list:nil. |
|
19361 sel := codeView selection. |
|
19362 sel notNil ifTrue:[ |
|
19363 box initialText:(sel asString withoutSeparators) |
|
19364 ]. |
|
19365 ^ box |
|
19366 ! |
|
19367 |
|
19368 listBoxTitle:title okText:okText list:aList |
|
19369 "convenient method: setup a listBox & return it" |
|
19370 |
|
19371 |box| |
|
19372 |
|
19373 box := ListSelectionBox |
|
19374 title:(resources string:title) |
|
19375 okText:(resources string:okText) |
|
19376 action:nil. |
|
19377 box list:aList. |
|
19378 ^ box |
|
19379 ! |
|
19380 |
|
19381 normalLabel |
|
19382 "set the normal (inactive) window- and icon labels" |
|
19383 |
|
19384 |l il| |
|
19385 |
|
19386 myLabel notNil ifTrue:[ |
|
19387 "if I have been given an explicit label, |
|
19388 and its not the default, take that one" |
|
19389 |
|
19390 myLabel ~= 'System Browser' ifTrue:[ |
|
19391 l := il := myLabel |
|
19392 ] |
|
19393 ]. |
|
19394 l isNil ifTrue:[ |
|
19395 l := resources string:'System Browser'. |
|
19396 |
|
19397 currentClass notNil ifTrue:[ |
|
19398 l := l, ': ', currentClass name. |
|
19399 classListView isNil ifTrue:[ |
|
19400 currentSelector notNil ifTrue:[ |
|
19401 l := l , ' ' , currentSelector |
|
19402 ] |
|
19403 ]. |
|
19404 il := currentClass name |
|
19405 ] ifFalse:[ |
|
19406 il := l. |
|
19407 ] |
|
19408 ]. |
|
19409 self label:l. |
|
19410 self iconLabel:il. |
|
19411 ! |
|
19412 |
|
19413 selectorToSearchFor |
|
19414 "look in codeView and methodListView for a search-string when searching for selectors" |
|
19415 |
|
19416 |sel t| |
|
19417 |
|
19418 sel := codeView selection. |
|
19419 sel notNil ifTrue:[ |
|
19420 sel := sel asString. |
|
19421 t := Parser selectorInExpression:sel. |
|
19422 t notNil ifTrue:[ |
|
19423 sel := t |
|
19424 ]. |
|
19425 sel := sel withoutSpaces. |
|
19426 sel == #>> ifTrue:[ |
|
19427 "oops - thats probably not what we want here ..." |
|
19428 self extractClassAndSelectorFromSelectionInto:[:c :s :m | |
|
19429 sel := s |
|
19430 ] |
|
19431 ] |
|
19432 ] ifFalse:[ |
|
19433 methodListView notNil ifTrue:[ |
|
19434 sel := methodListView selectionValue |
|
19435 ] ifFalse:[ |
|
19436 classMethodListView notNil ifTrue:[ |
|
19437 sel := classMethodListView selectionValue. |
|
19438 sel notNil ifTrue:[ |
|
19439 sel := self selectorFromClassMethodString:sel |
|
19440 ] |
|
19441 ] |
|
19442 ]. |
|
19443 sel notNil ifTrue:[ |
|
19444 sel := sel withoutSpaces upTo:(Character space) |
|
19445 ] ifFalse:[ |
|
19446 sel := '' |
|
19447 ] |
|
19448 ]. |
|
19449 ^ sel |
|
19450 ! |
|
19451 |
|
19452 setAcceptAndExplainActionsForMethod |
|
19453 "tell the codeView what to do on accept and explain" |
|
19454 |
|
19455 codeView acceptAction:[:theCode | |
|
19456 |cat cls| |
|
19457 |
|
19458 codeView cursor:Cursor execute. |
|
19459 |
|
19460 (cat := currentMethodCategory) = '* all *' ifTrue:[ |
|
19461 "must check from which category this code came from ... |
|
19462 ... thanks to Arno for pointing this out" |
|
19463 |
|
19464 cat := self askForMethodCategory. |
|
19465 ]. |
|
19466 (cat notNil and:[cat notEmpty]) ifTrue:[ |
|
19467 fullProtocol ifTrue:[ |
|
19468 cls := acceptClass "/actualClass whichClassIncludesSelector:currentSelector. |
|
19469 ]. |
|
19470 cls isNil ifTrue:[ |
|
19471 cls := actualClass |
|
19472 ]. |
|
19473 |
|
19474 Object abortSignal catch:[ |
|
19475 lockUpdates := true. |
|
19476 |
|
19477 actualClass compilerClass |
|
19478 compile:theCode asString |
|
19479 forClass:cls |
|
19480 inCategory:cat |
|
19481 notifying:codeView. |
|
19482 |
|
19483 codeView modified:false. |
|
19484 self updateMethodListWithScroll:false. |
|
19485 currentMethod := actualClass compiledMethodAt:currentSelector. |
|
19486 ]. |
|
19487 lockUpdates := false. |
|
19488 ]. |
|
19489 codeView cursor:Cursor normal. |
|
19490 ]. |
|
19491 |
|
19492 codeView explainAction:[:theCode :theSelection | |
|
19493 self showExplanation:(Explainer |
|
19494 explain:theSelection |
|
19495 in:theCode |
|
19496 forClass:actualClass) |
|
19497 ]. |
|
19498 ! |
|
19499 |
|
19500 setDoitActionForClass |
|
19501 "tell the codeView what to do on doIt" |
|
19502 |
|
19503 "set self for doits. This allows accessing the current class |
|
19504 as self, and access to the class variables by name. |
|
19505 " |
|
19506 codeView doItAction:[:theCode | |
|
19507 |compiler| |
|
19508 |
|
19509 currentClass isNil ifTrue:[ |
|
19510 compiler := Compiler |
|
19511 ] ifFalse:[ |
|
19512 compiler := currentClass evaluatorClass |
|
19513 ]. |
|
19514 compiler |
|
19515 evaluate:theCode |
|
19516 in:nil |
|
19517 receiver:currentClass |
|
19518 notifying:codeView |
|
19519 logged:false |
|
19520 ifFail:nil |
|
19521 ]. |
|
19522 ! |
|
19523 |
|
19524 setSearchPattern:aString |
|
19525 codeView setSearchPattern:aString |
|
19526 ! |
|
19527 |
|
19528 showExplanation:someText |
|
19529 "show explanation from Parser" |
|
19530 |
|
19531 self information:someText |
|
19532 ! |
|
19533 |
|
19534 stringToSearchFor |
|
19535 "look in codeView and methodListView for a search-string when searching for classes/names" |
|
19536 |
|
19537 |sel| |
|
19538 |
|
19539 sel := codeView selection. |
|
19540 sel notNil ifTrue:[ |
|
19541 sel := sel asString withoutSpaces |
|
19542 ] ifFalse:[ |
|
19543 sel isNil ifTrue:[ |
|
19544 currentClass notNil ifTrue:[ |
|
19545 sel := currentClass name |
|
19546 ] |
|
19547 ]. |
|
19548 sel notNil ifTrue:[ |
|
19549 sel := sel withoutSpaces |
|
19550 ] ifFalse:[ |
|
19551 sel := '' |
|
19552 ] |
|
19553 ]. |
|
19554 ^ sel |
|
19555 ! |
|
19556 |
|
19557 warnLabel:what |
|
19558 "set the title for some warning" |
|
19559 |
|
19560 self label:('System Browser WARNING: ' , what) |
|
19561 ! |
|
19562 |
|
19563 withSearchCursorDo:aBlock |
|
19564 ^ self withCursor:(Cursor questionMark) do:aBlock |
|
19565 |
|
19566 "Created: 23.11.1995 / 14:11:14 / cg" |
|
19567 ! ! |
|
19568 |
|
19569 !BrowserView methodsFor:'unused'! |
|
19570 |
|
19571 listOfAllMethodCategoriesInHierarchy:aClass |
|
19572 "answer a list of all method categories of the argument, aClass, |
|
19573 and all of its superclasses" |
|
19574 |
|
19575 |newList cat| |
|
19576 |
|
19577 newList := Set new. |
|
19578 self classesInHierarchy:aClass do:[:c | |
|
19579 c methodArray do:[:aMethod | |
|
19580 cat := aMethod category. |
|
19581 cat isNil ifTrue:[ |
|
19582 cat := '* no category *' |
|
19583 ]. |
|
19584 newList add:cat |
|
19585 ] |
|
19586 ]. |
|
19587 (newList size == 0) ifTrue:[^ nil]. |
|
19588 newList add:'* all *'. |
|
19589 ^ newList asOrderedCollection sort |
|
19590 |
|
19591 ! |
|
19592 |
|
19593 listOfAllSelectorsInCategory:aCategory inHierarchyOfClass:aClass |
|
19594 "answer a list of all selectors in a given method category |
|
19595 of the argument, aClass and its superclasses" |
|
19596 |
|
19597 |newList| |
|
19598 |
|
19599 newList := Set new. |
|
19600 self classesInHierarchy:aClass do:[:c | |
|
19601 |searchCategory| |
|
19602 |
|
19603 (aCategory = '* all *') ifTrue:[ |
|
19604 newList addAll:(c selectorArray) |
|
19605 ] ifFalse:[ |
|
19606 (aCategory = '* no category *') ifTrue:[ |
|
19607 searchCategory := nil |
|
19608 ] ifFalse:[ |
|
19609 searchCategory := aCategory |
|
19610 ]. |
|
19611 c methodArray with:c selectorArray do:[:aMethod :selector | |
|
19612 (aMethod category = searchCategory) ifTrue:[ |
|
19613 newList add:selector |
|
19614 ] |
|
19615 ] |
|
19616 ]. |
|
19617 ]. |
|
19618 (newList size == 0) ifTrue:[^ nil]. |
|
19619 ^ newList asOrderedCollection sort |
|
19620 ! ! |
|
19621 |
|
19622 !BrowserView methodsFor:'variable list menu'! |
|
19623 |
|
19624 allClassOrInstVarRefsTitle:title access:access mods:modifications |
|
19625 "show an enterbox for instVar to search for" |
|
19626 |
|
19627 self doClassMenu:[:currentClass | |
|
19628 |box| |
|
19629 |
|
19630 box := self enterBoxForVariableSearch:title. |
|
19631 box action:[:aVariableName | |
|
19632 |homeClass| |
|
19633 |
|
19634 aVariableName isEmpty ifFalse:[ |
|
19635 self withSearchCursorDo:[ |
|
19636 homeClass := self findClassOfVariable:aVariableName accessWith:access. |
|
19637 access == #classVarNames ifTrue:[ |
|
19638 SystemBrowser |
|
19639 browseClassRefsTo:aVariableName |
|
19640 under:homeClass |
|
19641 modificationsOnly:modifications |
|
19642 ] ifFalse:[ |
|
19643 SystemBrowser |
|
19644 browseInstRefsTo:aVariableName |
|
19645 under:homeClass |
|
19646 modificationsOnly:modifications |
|
19647 ] |
|
19648 ] |
|
19649 ] |
|
19650 ]. |
|
19651 box showAtPointer |
|
19652 ] |
|
19653 |
|
19654 "Created: 23.11.1995 / 14:13:24 / cg" |
|
19655 ! |
|
19656 |
|
19657 allClassVarMods |
|
19658 "show an enterbox for classVar to search for" |
|
19659 |
|
19660 self allClassOrInstVarRefsTitle:'class variable to browse modifications of:' |
|
19661 access:#classVarNames |
|
19662 mods:true |
|
19663 ! |
|
19664 |
|
19665 allClassVarRefs |
|
19666 "show an enterbox for classVar to search for" |
|
19667 |
|
19668 self allClassOrInstVarRefsTitle:'class variable to browse references to:' |
|
19669 access:#classVarNames |
|
19670 mods:false |
|
19671 ! |
|
19672 |
|
19673 allInstVarMods |
|
19674 "show an enterbox for instVar to search for" |
|
19675 |
|
19676 self allClassOrInstVarRefsTitle:'instance variable to browse modifications of:' |
|
19677 access:#instVarNames |
|
19678 mods:true |
|
19679 ! |
|
19680 |
|
19681 allInstVarRefs |
|
19682 "show an enterbox for instVar to search for" |
|
19683 |
|
19684 self allClassOrInstVarRefsTitle:'instance variable to browse references to:' |
|
19685 access:#instVarNames |
|
19686 mods:false |
|
19687 ! |
|
19688 |
|
19689 classVarMods |
|
19690 "show an enterbox for classVar to search for" |
|
19691 |
|
19692 self classVarRefsOrModsTitle:'class variable to browse modifications of:' |
|
19693 mods:true |
|
19694 ! |
|
19695 |
|
19696 classVarRefs |
|
19697 "show an enterbox for classVar to search for" |
|
19698 |
|
19699 self classVarRefsOrModsTitle:'class variable to browse references to:' |
|
19700 mods:false |
|
19701 ! |
|
19702 |
|
19703 classVarRefsOrModsTitle:title mods:mods |
|
19704 "show an enterbox for classVar to search for" |
|
19705 |
|
19706 self doClassMenu:[:currentClass | |
|
19707 |box| |
|
19708 |
|
19709 box := self enterBoxForVariableSearch:title. |
|
19710 box action:[:aString | |
|
19711 aString notEmpty ifTrue:[ |
|
19712 self withSearchCursorDo:[ |
|
19713 SystemBrowser |
|
19714 browseClassRefsTo:aString |
|
19715 in:(Array with:currentClass) |
|
19716 modificationsOnly:mods |
|
19717 ] |
|
19718 ] |
|
19719 ]. |
|
19720 box showAtPointer |
|
19721 ] |
|
19722 |
|
19723 "Created: 23.11.1995 / 14:12:56 / cg" |
|
19724 ! |
|
19725 |
|
19726 enterBoxForVariableSearch:title |
|
19727 |box sel| |
|
19728 |
|
19729 box := self enterBoxForCodeSelectionTitle:title okText:'browse'. |
|
19730 variableListView notNil ifTrue:[ |
|
19731 codeView hasSelection ifFalse:[ |
|
19732 (sel := variableListView selectionValue) notNil ifTrue:[ |
|
19733 (sel startsWith:'---') ifFalse:[ |
|
19734 box initialText:sel |
|
19735 ] |
|
19736 ] |
|
19737 ] |
|
19738 ]. |
|
19739 ^ box |
|
19740 ! |
|
19741 |
|
19742 instVarMods |
|
19743 "show an enterbox for instVar to search for" |
|
19744 |
|
19745 self instVarRefsOrModsTitle:'instance variable to browse modifications of:' |
|
19746 mods:true |
|
19747 ! |
|
19748 |
|
19749 instVarRefs |
|
19750 "show an enterbox for instVar to search for" |
|
19751 |
|
19752 self instVarRefsOrModsTitle:'instance variable to browse references to:' |
|
19753 mods:false |
|
19754 ! |
|
19755 |
|
19756 instVarRefsOrModsTitle:title mods:mods |
|
19757 "show an enterbox for instvar to search for" |
|
19758 |
|
19759 self doClassMenu:[:currentClass | |
|
19760 |box| |
|
19761 |
|
19762 box := self enterBoxForVariableSearch:title. |
|
19763 box action:[:aString | |
|
19764 aString notEmpty ifTrue:[ |
|
19765 self withSearchCursorDo:[ |
|
19766 SystemBrowser |
|
19767 browseInstRefsTo:aString |
|
19768 in:(Array with:currentClass) |
|
19769 modificationsOnly:mods |
|
19770 ] |
|
19771 ] |
|
19772 ]. |
|
19773 box showAtPointer |
|
19774 ] |
|
19775 |
|
19776 "Created: 23.11.1995 / 14:12:40 / cg" |
|
19777 ! |
|
19778 |
|
19779 varTypeInfo |
|
19780 "show typical usage of a variable" |
|
19781 |
|
19782 |name idx classes values value msg cut names instCount subInstCount box |
|
19783 searchClass| |
|
19784 |
|
19785 name := variableListView selectionValue. |
|
19786 name isNil ifTrue:[^ self]. |
|
19787 |
|
19788 searchClass := actualClass whichClassDefinesInstVar:name. |
|
19789 |
|
19790 idx := searchClass instVarOffsetOf:name. |
|
19791 idx isNil ifTrue:[^ self]. |
|
19792 |
|
19793 classes := IdentitySet new. |
|
19794 values := IdentitySet new. |
|
19795 instCount := 0. |
|
19796 subInstCount := 0. |
|
19797 searchClass allSubInstancesDo:[:i | |
|
19798 |val| |
|
19799 |
|
19800 val := i instVarAt:idx. |
|
19801 val notNil ifTrue:[values add:val]. |
|
19802 classes add:val class. |
|
19803 (i isMemberOf:searchClass) ifTrue:[ |
|
19804 instCount := instCount + 1. |
|
19805 ] ifFalse:[ |
|
19806 subInstCount := subInstCount + 1 |
|
19807 ] |
|
19808 ]. |
|
19809 (instCount == 0 and:[subInstCount == 0]) ifTrue:[ |
|
19810 self warn:'there are currently no instances of ' , currentClass name. |
|
19811 ^ self |
|
19812 ]. |
|
19813 |
|
19814 instCount ~~ 0 ifTrue:[ |
|
19815 msg := 'in (currently: ' , instCount printString,') instances '. |
|
19816 subInstCount ~~ 0 ifTrue:[ |
|
19817 msg := msg , 'and ' |
|
19818 ] |
|
19819 ] ifFalse:[ |
|
19820 msg := 'in '. |
|
19821 ]. |
|
19822 subInstCount ~~ 0 ifTrue:[ |
|
19823 msg := msg , '(currently: ' , subInstCount printString, ') derived instances ' |
|
19824 ]. |
|
19825 msg := msg, 'of ' , searchClass name , ',\'. |
|
19826 msg := msg , name , ' '. |
|
19827 ((values size == 1) |
|
19828 or:[classes size == 1 and:[classes first == UndefinedObject]]) ifTrue:[ |
|
19829 values size == 1 ifTrue:[value := values first]. |
|
19830 (value isNumber or:[value isString]) ifTrue:[ |
|
19831 msg := msg , 'is always the same:\\ ' , |
|
19832 value class name , ' (' , value storeString , ')'. |
|
19833 ] ifFalse:[ |
|
19834 (value isNil or:[value == true or:[value == false]]) ifTrue:[ |
|
19835 msg := msg , 'is always:\\ ' , |
|
19836 value printString. |
|
19837 ] ifFalse:[ |
|
19838 msg := msg , 'is always the same:\\'. |
|
19839 msg := msg , ' ' , value class name. |
|
19840 value isLiteral ifTrue:[ |
|
19841 msg := msg , ' (' , value storeString , ')' |
|
19842 ] |
|
19843 ] |
|
19844 ] |
|
19845 ] ifFalse:[ |
|
19846 classes size == 1 ifTrue:[ |
|
19847 msg := msg , 'is always:\\'. |
|
19848 msg := msg , ' ' , classes first name , '\'. |
|
19849 ] ifFalse:[ |
|
19850 msg := msg , 'is one of:\\'. |
|
19851 classes := classes asOrderedCollection. |
|
19852 classes size > 20 ifTrue:[ |
|
19853 classes := classes copyFrom:1 to:20. |
|
19854 cut := true |
|
19855 ] ifFalse:[ |
|
19856 cut := false. |
|
19857 ]. |
|
19858 names := classes collect:[:cls | |
|
19859 |nm| |
|
19860 cls == UndefinedObject ifTrue:[ |
|
19861 'nil' |
|
19862 ] ifFalse:[ |
|
19863 cls == True ifTrue:[ |
|
19864 'true' |
|
19865 ] ifFalse:[ |
|
19866 cls == False ifTrue:[ |
|
19867 'false' |
|
19868 ] ifFalse:[ |
|
19869 cls name |
|
19870 ] |
|
19871 ] |
|
19872 ]. |
|
19873 ]. |
|
19874 names sort. |
|
19875 names do:[:nm | |
|
19876 msg := msg , ' ' , nm , '\'. |
|
19877 ]. |
|
19878 ] |
|
19879 ]. |
|
19880 |
|
19881 box := InfoBox title:msg withCRs. |
|
19882 box label:'variable type information'. |
|
19883 box showAtPointer |
|
19884 ! |
|
19885 |
|
19886 variableListMenu |
|
19887 |labels selectors| |
|
19888 |
|
19889 currentClass isNil ifTrue:[ |
|
19890 variableListView flash. |
|
19891 ^ nil |
|
19892 ]. |
|
19893 |
|
19894 labels := #( |
|
19895 'instvar refs ...' |
|
19896 'classvar refs ...' |
|
19897 'all instvar refs ...' |
|
19898 'all classvar refs ...' |
|
19899 '-' |
|
19900 'instvar mods ...' |
|
19901 'classvar mods ...' |
|
19902 'all instvar mods ...' |
|
19903 'all classvar mods ...' |
|
19904 ). |
|
19905 selectors := #( |
|
19906 instVarRefs |
|
19907 classVarRefs |
|
19908 allInstVarRefs |
|
19909 allClassVarRefs |
|
19910 nil |
|
19911 instVarMods |
|
19912 classVarMods |
|
19913 allInstVarMods |
|
19914 allClassVarMods |
|
19915 ). |
|
19916 |
|
19917 (showInstance and:[variableListView hasSelection]) ifTrue:[ |
|
19918 labels := labels , #( |
|
19919 '-' |
|
19920 'type information' |
|
19921 ). |
|
19922 selectors := selectors , #( |
|
19923 nil |
|
19924 varTypeInfo |
|
19925 ). |
|
19926 ]. |
|
19927 |
|
19928 ^ PopUpMenu labels:(resources array:labels) |
|
19929 selectors:selectors |
|
19930 ! |
|
19931 |
|
19932 variableSelection:lineNr |
|
19933 "variable selection changed" |
|
19934 |
|
19935 |name idx| |
|
19936 |
|
19937 name := variableListView selectionValue. |
|
19938 name isNil ifTrue:[ |
|
19939 self unhilightMethodCategories. |
|
19940 self unhilightMethods. |
|
19941 self autoSearch:nil. |
|
19942 ^ self |
|
19943 ]. |
|
19944 |
|
19945 " |
|
19946 first, check if the selected variable is really the one |
|
19947 we get - reselect if its hidden (for example, a class variable |
|
19948 with the same name could be defined in a subclass) |
|
19949 " |
|
19950 idx := variableListView list findLast:[:entry | entry = name]. |
|
19951 idx ~~ lineNr ifTrue:[ |
|
19952 "select it - user will see whats going on" |
|
19953 variableListView selection:idx |
|
19954 ]. |
|
19955 |
|
19956 "search for methods in the current category, which access the selected |
|
19957 variable, and highlight them" |
|
19958 |
|
19959 self hilightMethodsInMethodCategoryList:true inMethodList:true. |
|
19960 self autoSearch:name. |
|
19961 ! ! |
|
19962 |
|
19963 !BrowserView methodsFor:'variable stuff'! |
|
19964 |
|
19965 hilightMethodsInMethodCategoryList |
|
19966 "search for methods which access the selected |
|
19967 variable, and highlight them" |
|
19968 |
|
19969 self hilightMethodsInMethodCategoryList:true inMethodList:false |
|
19970 |
|
19971 |
|
19972 |
|
19973 ! |
|
19974 |
|
19975 hilightMethodsInMethodCategoryList:inCat inMethodList:inMethods |
|
19976 "search for methods which access the selected |
|
19977 variable, and highlight them" |
|
19978 |
|
19979 |name redefinedSelectors| |
|
19980 |
|
19981 variableListView isNil ifTrue:[^ self]. |
|
19982 |
|
19983 inCat ifTrue:[self unhilightMethodCategories]. |
|
19984 inMethods ifTrue:[self unhilightMethods]. |
|
19985 |
|
19986 actualClass isNil ifTrue:[^ self]. |
|
19987 (methodCategoryListView isNil |
|
19988 and:[methodListView isNil]) ifTrue:[^ self]. |
|
19989 |
|
19990 name := variableListView selectionValue. |
|
19991 name isNil ifTrue:[^ self]. |
|
19992 |
|
19993 self withSearchCursorDo:[ |
|
19994 |classes filter any| |
|
19995 |
|
19996 classes := Array with:actualClass. |
|
19997 currentClassHierarchy notNil ifTrue:[ |
|
19998 classes := classes , actualClass allSuperclasses. |
|
19999 redefinedSelectors := IdentitySet new. |
|
20000 ]. |
|
20001 |
|
20002 filter := SystemBrowser filterToSearchRefsTo:name classVars:showInstance not modificationsOnly:false. |
|
20003 |
|
20004 any := false. |
|
20005 " |
|
20006 highlight the method that ref this variable |
|
20007 " |
|
20008 classes do:[:someClass | |
|
20009 (fullProtocol |
|
20010 and:[classListView valueIsInSelection:(someClass name)]) ifFalse:[ |
|
20011 someClass methodArray with:someClass selectorArray |
|
20012 do:[:method :selector | |
|
20013 |
|
20014 (inCat |
|
20015 or:[methodListView list notNil |
|
20016 and:[methodListView list includes:selector]]) |
|
20017 ifTrue:[ |
|
20018 (redefinedSelectors isNil |
|
20019 or:[(redefinedSelectors includes:selector) not]) |
|
20020 ifTrue:[ |
|
20021 (filter value:someClass value:method value:selector) ifTrue:[ |
|
20022 |idx cat| |
|
20023 |
|
20024 (inCat |
|
20025 and:[methodCategoryListView notNil |
|
20026 and:[methodCategoryListView list notNil]]) ifTrue:[ |
|
20027 cat := method category. |
|
20028 " |
|
20029 highlight the methodCategory |
|
20030 " |
|
20031 idx := methodCategoryListView list indexOf:cat. |
|
20032 idx ~~ 0 ifTrue:[ |
|
20033 methodCategoryListView attributeAt:idx put:#bold. |
|
20034 ]. |
|
20035 ]. |
|
20036 |
|
20037 (inMethods |
|
20038 and:[methodListView notNil |
|
20039 and:[methodListView list notNil]]) ifTrue:[ |
|
20040 " |
|
20041 highlight the method |
|
20042 " |
|
20043 idx := methodListView list indexOf:selector. |
|
20044 idx ~~ 0 ifTrue:[ |
|
20045 methodListView attributeAt:idx put:#bold. |
|
20046 ]. |
|
20047 any := true |
|
20048 ]. |
|
20049 ]. |
|
20050 redefinedSelectors notNil ifTrue:[ |
|
20051 redefinedSelectors add:selector |
|
20052 ] |
|
20053 ] |
|
20054 ] |
|
20055 ] |
|
20056 ] |
|
20057 ]. |
|
20058 any ifTrue:[ |
|
20059 self setSearchPattern:name |
|
20060 ] |
|
20061 ] |
|
20062 |
|
20063 "Created: 23.11.1995 / 14:12:08 / cg" |
|
20064 ! |
|
20065 |
|
20066 hilightMethodsInMethodList |
|
20067 "search for methods which access the selected |
|
20068 variable, and highlight them" |
|
20069 |
|
20070 self hilightMethodsInMethodCategoryList:false inMethodList:true |
|
20071 |
|
20072 |
|
20073 |
|
20074 ! |
|
20075 |
|
20076 unhilightMethodCategories |
|
20077 "unhighlight items in method list" |
|
20078 |
|
20079 variableListView isNil ifTrue:[^ self]. |
|
20080 |
|
20081 methodCategoryListView notNil ifTrue:[ |
|
20082 1 to:methodCategoryListView list size do:[:entry | |
|
20083 methodCategoryListView attributeAt:entry put:nil. |
|
20084 ] |
|
20085 ]. |
|
20086 |
|
20087 |
|
20088 ! |
|
20089 |
|
20090 unhilightMethods |
|
20091 "unhighlight items in method list" |
|
20092 |
|
20093 variableListView isNil ifTrue:[^ self]. |
|
20094 |
|
20095 methodListView notNil ifTrue:[ |
|
20096 1 to:methodListView list size do:[:entry | |
|
20097 methodListView attributeAt:entry put:nil. |
|
20098 ]. |
|
20099 ]. |
|
20100 |
|
20101 |
|
20102 ! |
|
20103 |
|
20104 updateVariableList |
|
20105 |l subList last nameAccessSelector class oldSelection| |
|
20106 |
|
20107 variableListView isNil ifTrue:[^ self]. |
|
20108 |
|
20109 oldSelection := variableListView selectionValue. |
|
20110 |
|
20111 l := OrderedCollection new. |
|
20112 " |
|
20113 show classVars, if classProtocol is shown (instead of classInstance vars) |
|
20114 " |
|
20115 showInstance ifTrue:[ |
|
20116 nameAccessSelector := #instVarNames |
|
20117 ] ifFalse:[ |
|
20118 nameAccessSelector := #classVarNames |
|
20119 ]. |
|
20120 |
|
20121 "/ class := currentClass notNil ifTrue:[currentClass] ifFalse:[actualClass]. |
|
20122 "/ class isNil ifTrue:[class := currentClassHierarchy]. |
|
20123 class := currentClassHierarchy notNil ifTrue:[currentClassHierarchy] ifFalse:[currentClass]. |
|
20124 class withAllSuperclasses do:[:aClass | |
|
20125 |ignore| |
|
20126 |
|
20127 ignore := fullProtocol |
|
20128 and:[classListView valueIsInSelection:(aClass name asString)]. |
|
20129 ignore ifFalse:[ |
|
20130 subList := aClass perform:nameAccessSelector. |
|
20131 subList size ~~ 0 ifTrue:[ |
|
20132 l := l , (subList asOrderedCollection reverse). |
|
20133 l := l , (OrderedCollection with:'---- ' , aClass name , ' ---------'). |
|
20134 ] |
|
20135 ] |
|
20136 ]. |
|
20137 l reverse. |
|
20138 variableListView setAttributes:nil. |
|
20139 variableListView list:l. |
|
20140 l keysAndValuesDo:[:index :entry | |
|
20141 (entry startsWith:'---') ifTrue:[ |
|
20142 variableListView attributeAt:index put:#disabled. |
|
20143 last := index |
|
20144 ] |
|
20145 ]. |
|
20146 last notNil ifTrue:[variableListView scrollToLine:last]. |
|
20147 |
|
20148 oldSelection notNil ifTrue:[ |
|
20149 variableListView selectElement:oldSelection. |
|
20150 self hilightMethodsInMethodCategoryList:true inMethodList:true. |
|
20151 ] |
|
20152 ! ! |
|
20153 |
6015 !BrowserView class methodsFor:'documentation'! |
20154 !BrowserView class methodsFor:'documentation'! |
6016 |
20155 |
6017 version |
20156 version |
6018 ^ '$Header: /cvs/stx/stx/libtool/BrowserView.st,v 1.57 1995-12-07 10:17:26 cg Exp $'! ! |
20157 ^ '$Header: /cvs/stx/stx/libtool/BrowserView.st,v 1.58 1995-12-07 12:26:14 cg Exp $'! ! |
6019 BrowserView initialize! |
20158 BrowserView initialize! |