Bug 35484

GemBuilder for Smalltalk/VA

5.3, 5.2.5

VA

5.3.1, 5.2.6

Misleading behavior on class modification without migration

GBS 5.2.5 includes a new feature, requiring that when you modify a
class, prior to migrating all instances you must commit the class
change.  If you answer "no" to this dialog, meaning do not commit
changes or migrate instances, the changes are saved in your image,
but the text pane remains dirty.  Selecting another element will
bring up a prompt asking you to save changes, giving a misleading
false impression that the class change was not saved to the image.

Workaround

You may ignore the "save changes" question; the behavior otherwise
is correct.

You may file in the following (which includes the fix for 35485 as
well as this bug) and save your image:

!GbxBrowser publicMethods !

acceptForoldClass: text

     "The user has changed the definition of the currently displayed class."
     "because of changes to listInstances: (abort preceeds any call to it) we do a commit before migrating.
          This change is only relevant against 64-bit servers, but is done against all servers to keep
          consistent behavior."

     | newClass symArray oldClass migrate commit |


     oldClass := self selectedNonMetaclass.

     "Change the segment to where this class lives so that the new class lives there as well."
     self gotoSegment: currentSeg.
     newClass := self session execute: text.

     "Get the dictionary and name of the new class.  If we didn't find it,
      that means a class was not compiled - error."
     symArray := userProfile remotePerform: #dictionaryAndSymbolOf: with: newClass.
     ((symArray = Onil) or: [ (newClass remotePerform: #isKindOf: with: OClass) = Ofalse ])
          ifTrue: [
               self gbsMessenger warn: 'Your definition did not create a new class'.
               self gotoDefaultSegment.
               ^false ].

     self session versionedOldClass: oldClass withNewClass: newClass.
     
     migrate :=  self gbsMessenger
                              choose: 'Commit Transaction and Migrate Instances?'
                              labels: #('Commit and Migrate' 'No')
                              values: #(true false)
                              default: true.
     self
          changed: #textAccepted.
     self
          changed: #className;
          gotoDefaultSegment;
          changed: #methodText.
     self selectClassNames: (OrderedCollection new add: ((newClass remotePerform: #name) asLocalSymbol); yourself) notifying: true.
     migrate ifFalse: [ ^false ].

     commit := self session commitTransaction.

     (commit == nil or: [commit == false])
          ifTrue: [^GbxDialog warn: 'Commit failed. Instances not migrated'].

     migrate ifTrue: [
          newClass gsclassHistory = oldClass gsclassHistory ifFalse: [
               self gbsMessenger warn: 'Your new class is not a version of the old\class.  Instances will not be migrated.' ]
          ifTrue: [
               System showBusyCursorWhile: [
                    self session migrateInstancesWithSubclassesOf: newClass ] ] ].

     self gbsMessenger commentAdd: 'done'.
     ^true! !

!GbxBrowserWindow publicMethods !

updateClasses
     | list |

(self extraAt: #removedClassPart) == true ifTrue: [ ^self ].

list := model classList.
list isNil ifTrue: [ list := Array new ].
self classList: list.
self updateClassList: (self subpartNamed: 'ClassView') items: list selection: (model formattedClassNames)!

updateClassList: listPart items: newItems selection: newSelection
"update the contents of the given list, and change the selection only as much as necessary.
The default list behavior is to leave items selected but not issue a select notification.
Returns the new selection set."
     | view |

"verify that the selected items are actually in the list, removing any bad ones"
newSelection copy do: [:e |
     (newItems includes: e) ifFalse: [
          (listPart widget selectedItems includes: e) ifTrue: [
               "check for a version number"
               listPart widget deselectItem: e. ].
          newSelection remove: e ].
          newItems do:[:newItem |
                    ((e asString, ' [*]') match: newItem) ifTrue:[
                         newSelection add: newItem.
                         ]]].
listPart items: newItems.
listPart selectedItems: newSelection.
"self log: 'new selection: ', newSelection printString."
^newSelection! !


Last updated: 8/27/06