System-Changes

ChangeRecord
A ChangeRecord represents a change recorded on a file in fileOut format.
It includes a type (more needs to be done here), and additional information
for certain types such as method defs which need class and category.
asMethodDefinition
category
class:category:method:sourceFiles:
This should be enough to find all the information for a method, or method deletion
file:position:type:
file:position:type:class:category:meta:stamp:
fileIn
File the receiver in. If I represent a method or a class-comment, file the method in and make a note of it in the recent-submissions list; if I represent a do-it, then, well, do it.
fileIndex
fileName
fileOutOn:
File the receiver out on the given file stream
headerFor:
isMetaClassChange
methodClass
methodClassName
methodSelector
originalChangeSetForSelector:
Returns the original changeset which contained this method version. If it is contained in the .sources file, return #sources. If it is in neither (e.g. its changeset was deleted), return nil. (The selector is passed in purely as an optimization.)
position
prior
readStamp
Get the time stamp of this method off the file
stamp
stamp:
string
text
timeStamp
Answer a TimeStamp that corresponds to my (text) stamp
type
ChangeSet
ChangeSets keep track of the changes made to a system, so they can be written on a file as source code (a "fileOut"). Every project has an associated changeSet. For simple projects, a different changeSet may be designated to capture changes at any time.
This implementation of ChangeSet is capable of remembering and manipulating methods for which the classes are not present in the system. However at the present time, this capability is not used in normal rearranging and fileOuts, but only for invoking and revoking associated with isolation layers.
For isolated projects (see Project class comment), the changeSet binding is semi-permanent. Every project exists in an isolation layer defined by its closest enclosing parent (or itself) that is isolated. If a project is not isolated, then changes reported to its designated changeSet must also be reported to the permanent changeSet for that layer, designated in the isolated project. This ensures that that outer project will be able to revert all changes upon exit.
Note that only certain changes may be reverted. Classes may not be added, removed, renamed or reshaped except in the layer in which they are defined because these operations on non-local classes are not revertable.
If a Squeak Project is established as being isolated, then its associated changeSet will be declared to be revertable. In this case all changes stored can be reverted. The changeSet associated with an isolated project is tied to that project, and cannot be edited in a changeSorter.
------
name - a String used to name the changeSet, and thus any associated project or fileOut.
preamble and postscript: two strings that serve as prefix (useful for documentation) and suffix (useful for doits) to the fileout of the changeSet.
revertable - a Boolean
If this variable is true, then all of the changes recorded by this changeSet can be reverted.
isolationSet - a ChangeSet or nil
The isolationSet is the designated changeSet for an isolation layer. If this changeSet is an isolationSet, then this variable will be nil. If not, then it points to the isolationSet for this layer, and all changes reported here will also be reported to the isolationSet.
isolatedProject - a Project or nil
If this is an isolationSet, then this variable points to the project with which it is associated.
changeRecords - Dictionary {class name -> a ClassChangeRecord}.
These classChangeRecords (qv) remember all of the system changes.
structures - Dictionary {#Rectangle -> #(<classVersionInteger> 'origin' 'corner')}.
Of the names of the instances variables before any changes for all classes in classChanges, and all of their superclasses. In the same format used in SmartRefStream. Inst var names are strings.
superclasses - Dictionary {#Rectangle -> #Object}.
Of all classes in classChanges, and all of their superclasses.
Structures and superclasses save the instance variable names of this class and all of its superclasses. Later we can tell how it changed and write a conversion method. The conversion method is used when old format objects are brought in from the disk from ImageSegment files (.extSeg) or SmartRefStream files (.obj .morph .bo .sp).
NOTE: It should be fairly simple, by adding a bit more information to the classChangeRecords, to reconstruct the information now stored in 'structures' and 'superclasses'. This would be a welcome simplification.
absorbClass:from:
Absorb into the receiver all the changes found in the class in the other change set.
*** Classes renamed in otherChangeSet may have problems
absorbMethod:class:from:
Absorb into the receiver all the changes for the method in the class in the other change set.
absorbStructureOfClass:from:
Absorb into the receiver all the structure and superclass info in the other change set. Used to write conversion methods.
addClass:
Include indication that a new class was created.
addCoherency:
SqR! 19980923: If I recreate the class then don't remove it
adoptSelector:forClass:
Adopt the given selector/class combination as a change in the receiver
allChangeSetNames
allChangeSets
allChangeSets:
allChangeSetsWithClass:selector:
askAddedInstVars:
Ask the author whether these newly added inst vars need to be non-nil
askRemovedInstVars:
Ask the author whether these newly removed inst vars need to have their info saved
askRenames:addTo:using:
Go through the renamed classes. Ask the user if it could be in a project. Add a method in SmartRefStream, and a conversion method in the new class.
assimilateAllChangesFoundIn:
Make all changes in otherChangeSet take effect on self as if they happened just now.
assurePostscriptExists
Make sure there is a StringHolder holding the postscript.
assurePreambleExists
Make sure there is a StringHolder holding the preamble; if it's found to have reverted to empty contents, put up the template
assuredChangeSetNamed:
atClass:add:
atClass:includes:
atSelector:class:
atSelector:class:put:
author
basicNewChangeSet:
basicNewNamed:
beIsolationSetFor:
browseChangedMessages
buildAggregateChangeSet
buildMessageForMailOutWithUser:
prepare the message
changeClass:from:
Remember that a class definition has been changed. Record the original structure, so that a conversion method can be built.
changeRecorderFor:
changeSet:containsClass:
changeSetsNamedSuchThat:
changed:with:
Allow objects to depend on the ChangeSet class instead of a particular instance
of ChangeSet (which may be switched using projects).
changedClassNames
Answer a OrderedCollection of the names of changed or edited classes.
DOES include removed classes. Sort alphabetically.
changedClasses
Answer an OrderedCollection of changed or edited classes.
Does not include removed classes. Sort alphabetically by name.
changedMessageList
Used by a message set browser to access the list view information.
changedMessageListAugmented
Even added classes have all messages in changedMessageList.
checkForAlienAuthorship
Check to see if there are any methods in the receiver that have author full name other than that of the current author, and open a browser on all found
checkForAnyAlienAuthorship
Check to see if there are any versions of any methods in the receiver that have author full name other than that of the current author, and open a browser on all found
checkForConversionMethods
See if any conversion methods are needed
checkForSlips
Return a collection of method refs with possible debugging code in them.
checkForUnclassifiedMethods
Open a message list browser on all methods in the current change set that have not been categorized,
checkForUncommentedClasses
Check to see if any classes involved in this change set do not have class comments. Open up a browser showing all such classes.
checkForUncommentedMethods
Check to see if there are any methods in the receiver that have no comments, and open a browser on all found
checkForUnsentMessages
Check the change set for unsent messages, and if any are found, open
up a message-list browser on them
chooseSubjectPrefixForEmail
classChangeAt:
Return what we know about class changes to this class.
classRemoves
clear
Reset the receiver to be empty.
commentClass:
Include indication that a class comment has been changed.
compileAll:from:
If I have changes for this class, recompile them
containsClass:
containsMethodAtPosition:
Answer whether the receiver contains the method logged at the given file position
convertApril2000:using:
These variables are automatically stored into the new instance:
('name' 'preamble' 'postscript' 'structures' 'superclasses' ).
This method is for additional changes.
It initializes the isolation variables, and then duplicates the logic fo
assimilateAllChangesFoundIn:.
countOfChangeSetsWithClass:andSelector:
current
currentChangeSetString
defaultChangeSetDirectory
defaultChangeSetDirectory:
defaultName
deleteChangeSetsNumberedLowerThan:
doWeFileOut:given:cache:
doesAnyChangeSetHaveClass:andSelector:
editPostscript
edit the receiver's postscript, in a separate window.
editPreamble
edit the receiver's preamble, in a separate window.
event:
Hook for SystemChangeNotifier
existingOrNewChangeSetNamed:
expungeEmptyClassChangeEntries
fatDefForClass:
fileIntoNewChangeSet:
fileOut
File out the receiver, to a file whose name is a function of the
change-set name and a unique numeric tag.
fileOutChangeSetsNamed:
fileOutChangesFor:on:
Write out all the method changes for this class.
fileOutClassDefinition:on:
Write out class definition for the given class on the given stream, if the class definition was added or changed.
fileOutOn:
Write out all the changes the receiver knows about
fileOutPSFor:on:
Write out removals and initialization for this class.
fileOutPostscriptOn:
If the receiver has a postscript, put it out onto the stream.
fileOutPreambleOn:
If the receiver has a preamble, put it out onto the stream.
fileReaderServicesForFile:suffix:
forgetAllChangesFoundIn:
Remove from the receiver all method changes found in aChangeSet. The intention is facilitate the process of factoring a large set of changes into disjoint change sets. To use: in a change sorter, copy over all the changes you want into some new change set, then use the subtract-other-side feature to subtract those changes from the larger change set, and continue in this manner.
forgetChangesForClass:in:
See forgetAllChangesFoundIn:. Used in culling changeSets.
gatherChangeSets
getRecentLocatorWithPrompt:
hasAnyChangeForSelector:
Answer whether the receiver has any change under the given selector, whether it be add, change, or remove, for any class
hasPostscript
hasPreamble
highestNumberedChangeSet
initialize
Initialize the receiver to be empty.
invoke
Do the first part of the invoke operation -- no particular hurry.
isEmpty
Answer whether the receiver contains any elements.
isMoribund
Answer whether the receiver is obsolete and about to die; part of an effort to get such guys cleared out from the change sorter. 2/7/96 sw
isolatedProject
Return the isolated project for which I am the changeSet.
isolationSet:
lookForSlips
Scan the receiver for changes that the user may regard as slips to be remedied
mailOut
Email a compressed version of this changeset to the squeak-dev list, so that it can be shared with everyone. (You will be able to edit the email before it is sent.)
messageListForChangesWhich:ifNone:
methodChanges
methodChangesAtClass:
Return an old-style dictionary of method change types.
methodInfoFromRemoval:
methodsWithAnyInitialsOtherThan:
Return a collection of method refs whose author appears to be different from the given one, even historically
methodsWithInitialsOtherThan:
Return a collection of method refs whose author appears to be different from the given one
methodsWithoutClassifications
Return a collection representing methods in the receiver which have not been categorized
methodsWithoutComments
Return a collection representing methods in the receiver which have no precode comments
mostRecentChangeSetWithChangeForClass:selector:
name
The name of this changeSet.
2/7/96 sw: If name is nil, we've got garbage. Help to identify.
name:
named:
new
newChangeSet
newChangeSet:
newChanges:
newChangesFromStream:named:
noChanges
noteClassForgotten:
Remove from structures if class is not a superclass of some other one we are remembering
noteClassStructure:
Save the instance variable names of this class and all of its superclasses. Later we can tell how it changed and write a conversion method. The conversion method is used when old format objects are brought in from the disk from ImageSegment files (.extSeg) or SmartRefStream files (.obj .morph .bo .sp).
noteNewMethod:forClass:selector:priorMethod:
noteRemovalOf:
The class is about to be removed from the system.
Adjust the receiver to reflect that fact.
objectForDataStream:
I am about to be written on an object file. Write a path to me in the other system instead.
okayToRemove
okayToRemoveInforming:
Answer whether it is okay to remove the receiver. If aBoolean is true, inform the receiver if it is not okay
oldNameFor:
postscript
Answer the string representing the postscript.
postscript:
Answer the string representing the postscript.
postscriptHasDependents
postscriptString
Answer the string representing the postscript.
postscriptString:
Establish aString as the new contents of the postscript.
preamble
Answer the string representing the preamble
preamble:
Establish aString as the new contents of the preamble.
preambleString
Answer the string representing the preamble
preambleString:
Establish aString as the new contents of the preamble.
preambleTemplate
Answer a string that will form the default contents for a change set's preamble.
Just a first stab at what the content should be.
printOn:
2/7/96 sw: provide the receiver's name in the printout
printOnStream:
2/7/96 sw: provide the receiver's name in the printout
promoteToTop:
promptForDefaultChangeSetDirectoryIfNecessary
removeChangeSet:
removeChangeSetsNamedSuchThat:
removeClassAndMetaClassChanges:
Remove all memory of changes associated with this class and its metaclass. 7/18/96 sw
removeClassChanges:
Remove all memory of changes associated with this class
removeEmptyUnnamedChangeSets
removePostscript
removePreamble
removeSelector:class:priorMethod:lastMethodInfo:
Include indication that a method has been forgotten.
info is a pair of the source code pointer and message category
for the method that was removed.
removeSelectorChanges:class:
Remove all memory of changes associated with the argument, selector, in
this class.
renameClass:from:to:
Include indication that a class has been renamed.
reorganizeClass:
Include indication that a class was reorganized.
resetCurrentToNewUnnamedChangeSet
revoke
Do the first part of the revoke operation -- this must be very simple.
scanCategory:
scanFile:category:class:meta:stamp:
scanFile:from:to:
scanVersionsOf:class:meta:category:selector:
secondaryChangeSet
selectorsInClass:
Used by a ChangeSorter to access the list methods.
serviceFileIntoNewChangeSet
services
setPreambleToSay:
Make aString become the preamble of this change set
structures
summaryString
Answer the string summarizing this changeSet
summaryStringDelta:
Answer the string summarizing this changeSet
superclassOrder:
superclasses
traitsOrder:
trimHistory
Drop non-essential history: methods added and then removed, as well as rename and reorganization of newly-added classes.
uninstall
uniqueNameLike:
verboseFileOut
File out the receiver, to a file whose name is a function of the change-set name and either of the date & time or chosen to have a unique numeric tag, depending on the preference 'changeSetVersionNumbers'
veryDeepCopyWith:
Return self; this is NOT the way to launch new change sets! Having this method here allows Change Sorters to be in parts bins
wither
The receiver is to be clobbered. Clear it out. 2/7/96 sw
zapHistory
Much stronger than trimHistory, but it should still leave the changeSet in good shape.
Must not be done on revertable changeSets
ChangeSet allInstancesDo: [:cs | cs zapHistory].
ChangesOrganizer
Changes organizer
allChangeSetNames
allChangeSets
allChangeSetsWithClass:selector:
assuredChangeSetNamed:
basicNewChangeSet:
belongsInAdditions:
belongsInAll:
belongsInMyInitials:
belongsInNumbered:
belongsInProjectsInRelease:
belongsInRecentUpdates:
buildAggregateChangeSet
changeSet:containsClass:
changeSetCategoryNamed:
changeSetNamed:
changeSetNamesInReleaseImage
changeSetNamesInThreeOh
changeSetsNamedSuchThat:
countOfChangeSetsWithClass:andSelector:
deleteChangeSetsNumberedLowerThan:
doesAnyChangeSetHaveClass:andSelector:
existingOrNewChangeSetNamed:
fileOutChangeSetsNamed:
gatherChangeSets
highestNumberedChangeSet
initialization
initializeChangeSetCategories
mostRecentChangeSetWithChangeForClass:selector:
newChangeSet
newChangeSet:
newChangesFromStream:named:
promoteToTop:
recentUpdateMarker
recentUpdateMarker:
removeChangeSet:
removeChangeSetsNamedSuchThat:
removeEmptyUnnamedChangeSets
reorderChangeSets
secondaryChangeSet
ClassChangeRecord
A ClassChangeRecorder keeps track of most substantive changes premissible in a project, isolated or not.
Structure:
inForce a boolean
Tells whether these changes are in effect.
true for all changeSets in and above the current project.
It should be sufficient only to record this for the changeSet
as a whole, but this redundancy could help in error recovery.
classIsLocal a boolean
True if and only if this class is defined in this layer of the
project structure.
changeTypes an identitySet
Summarizes which changes have been made in this class.
Values include #comment, #reorganize, #rename,
and the four more summarized below.
thisName a string
Retains the class name for this layer.
priorName a string
Preserves the prior name.
thisComment a text
Retains the class comment for this layer.
priorComment a text
Preserves the prior comment.
thisOrganization a classOrganizer
Retains the class organization for this layer.
priorOrganization a classOrganizer
Preserves the prior organization.
thisMD a methodDictionary
Used to prepare changes for nearly atomic invocation
of this layer (see below).
priorMD a methodDictionary
Preserves the state of an altered class as it exists in the next
outer layer of the project structure.
methodChanges a dictionary of classChangeRecords
Retains all the method changes for this layer.
Four of the possible changeTypes are maintained in a mutually exclusive set, analogously to MethodChangeRecords. Here is a simple summary of the relationship between these four changeType symbols and the recording of prior state
| prior == nil | prior not nil
--------- |---------------------------- |--------------------
add | add | change
--------- |---------------------------- |--------------------
remove | addedThenRemoved | remove
A classChangeRecorder is notified of changes by the method
noteMethodChange: <ClassChangeRecord>.
ClassChangeRecorders are designed to invoke a set of changes relative to the definition of a class in an prior layer. It is important that both invocation and revocation of these changes take place in a nearly atomic fashion so that interdependent changes will be adopted as a whole, and so that only one flush of the method cache should be necessary. A further reason for revocation to be simple is that it may be requested as an attempt to recover from an error in a project that is failing.
allChangeTypes
assimilateAllChangesIn:
atSelector:ifAbsent:
atSelector:put:
changedSelectors
Return a set of the changed or removed selectors.
checkCoherence
If I recreate the class then don't remove it
compileAll:from:
Something about this class has changed. Locally retained methods must be recompiled.
NOTE: You might think that if this changeSet is in force, then we can just note
the new methods but a lower change set may override and be in force which
would mean that only the overriding copies go recompiled. Just do it.
findOrMakeMethodChangeAt:priorMethod:
forgetChangesIn:
See forgetAllChangesFoundIn:. Used in culling changeSets.
forgetClassRemoval
hasNoChanges
includesChangeType:
infoFromRemoval:
initFor:revertable:
invokePhase1
invokePhase2
isClassRemoval
NOTE: there are other removals with changeType #addedThenRemoved,
but this message is used to write out removals in fileOut, and those
cases should not be written out.
methodChangeTypes
Return an old-style dictionary of method change types.
methodChanges
noteChangeType:
noteChangeType:fromClass:
noteNewMethod:selector:priorMethod:
noteNewName:
notePriorDefinition:
noteRemoveSelector:priorMethod:lastMethodInfo:
priorDefinition
priorName
realClass
Return the actual class (or meta), as determined from my name.
removeSelector:
Remove all memory of changes associated with the argument, selector, in this class.
revokePhase1
revokePhase2
thisName
trimHistory
Drop non-essential history.
zapHistory
Drop all recorded information not needed to simply keep track of what has been changed.
Saves a lot of space.
MethodChangeRecord
MethodChangeRecords are used to record method changes. Here is a simple summary of the relationship between the changeType symbol and the recording of prior state
| prior == nil | prior not nil
--------- |---------------------------- |--------------------
add | add | change
--------- |---------------------------- |--------------------
remove | addedThenRemoved | remove
Structure:
changeType symbol -- as summarized above
currentMethod method
This is the current version of the method.
It can be used to assert this change upon entry to a layer.
infoFromRemoval -- an array of size 2.
The first element is the source index of the last version of the method.
The second element is the category in which it was defined, so it
can be put back there if re-accepted from a version browser.
Note that the above states each have an associated revoke action:
add --> remove
change --> change back
remove --> add back
addedThenRemoved --> no change
However all of these are accomplished trivially by restoring the original method dictionary.
changeType
currentMethod
methodInfoFromRemoval
Return an array with the source index of the last version of the method,
and the category in which it was defined (so it can be put back there if
re-accepted from a version browser).
noteChangeType:
noteMethodInfoFromRemoval:
Store an array with the source index of the last version of the method,
and the category in which it was defined (so it can be put back there if
re-accepted from a version browser).
noteNewMethod:
NEVER do this. It is evil.
printOn:
Append to the argument, aStream, a sequence of characters that
identifies the receiver.
priorMethod:
We do not save original versions of changed methods because we only
revoke changes at the level of entire classes, and that is done by
restoration of the entire methodDictionary.
storeDataOn:
Store myself on a DataStream. Answer self. This is a low-level DataStream/ReferenceStream method. See also objectToStoreOnDataStream. NOTE: This method must send 'aDataStream beginInstance:size:' and then (nextPut:/nextPutWeak:) its subobjects. readDataFrom:size: reads back what we write here.