[Pkg] The Trunk: System-mt.1228.mcz

commits at source.squeak.org commits at source.squeak.org
Sun Apr 18 16:49:09 UTC 2021


Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.1228.mcz

==================== Summary ====================

Name: System-mt.1228
Author: mt
Time: 18 April 2021, 6:49:05.736254 pm
UUID: 513db764-6353-204e-9724-18519504a7b5
Ancestors: System-ul.1227

Adds queries to enumerate actual domain objects for changed classes or methods.

Adds change stamps for class changes and method removal.

Note that I followed the not-so-good practice of using "Utilities changeStamp" to assure a single kind of timestamp (to sort later). In the future, we should change all this to DateAndTime and deprecate TimeStamp.

=============== Diff against System-ul.1227 ===============

Item was changed:
  ----- Method: ChangeSet>>changedClasses (in category 'class changes') -----
  changedClasses
- 	"Answer an OrderedCollection of changed or edited classes.
- 	Does not include removed classes.  Sort alphabetically by name."
  
+ 	^ Array streamContents: [:stream |
+ 			self changedClassesDo: [:class |
+ 				stream nextPut: class]]!
- 	"Much faster to sort names first, then convert back to classes.  Because metaclasses reconstruct their name at every comparison in the sorted collection.
- 	8/91 sw chgd to filter out non-existent classes (triggered by problems with class-renames"
- 
- 	^ self changedClassNames
- 		collect: [:className | Smalltalk classNamed: className]
- 		thenSelect: [:aClass | aClass notNil]!

Item was added:
+ ----- Method: ChangeSet>>changedClassesDo: (in category 'class changes') -----
+ changedClassesDo: block
+ 	"Answer an OrderedCollection of changed or edited classes.
+ 	Does not include removed classes.  Sort alphabetically by name."
+ 
+ 	"Much faster to sort names first, then convert back to classes.  Because metaclasses reconstruct their name at every comparison in the sorted collection.
+ 	8/91 sw chgd to filter out non-existent classes (triggered by problems with class-renames"
+ 
+ 	self flag: #environmentsMissing.
+ 	self changedClassNames do: [:className | | record class changeTypes dateAndTime category |
+ 		record := changeRecords at: className.
+ 		class := (Smalltalk classNamed: className) ifNil: [
+ 			PseudoClass new
+ 				name: className;
+ 				definition: record priorDefinition;
+ 				yourself].
+ 		changeTypes := record allChangeTypes.
+ 		dateAndTime := [TimeStamp fromMethodTimeStamp: record timeStamp]
+ 			ifError: [TimeStamp epoch].
+ 		category := [class category] ifError: ['unknown'].
+ 		block
+ 			cull: class
+ 			cull: changeTypes
+ 			cull: dateAndTime
+ 			cull: category].!

Item was added:
+ ----- Method: ChangeSet>>changedMethods (in category 'method changes') -----
+ changedMethods
+ 
+ 	^ Array streamContents: [:stream |
+ 			self changedMethodsDo: [:class |
+ 				stream nextPut: class]]!

Item was added:
+ ----- Method: ChangeSet>>changedMethodsDo: (in category 'method changes') -----
+ changedMethodsDo: block
+ 
+ 	self flag: #environmentsMissing.
+ 	changeRecords keysAndValuesDo: [:className :classRecord |
+ 		(Smalltalk classNamed: className) ifNotNil: [:class |
+ 			classRecord methodChanges keysAndValuesDo: [:selector :methodRecord |
+ 				| method category sourcePointer dateAndTime |
+ 				(class includesSelector: selector)
+ 					ifTrue: [
+ 						method := class compiledMethodAt: selector.
+ 						category := class organization categoryOfElement: selector.
+ 						sourcePointer := method sourcePointer.
+ 						dateAndTime := method timeStamp]
+ 					ifFalse: [ "Method was removed. Try to reconstruct information."
+ 						methodRecord methodInfoFromRemoval ifNotNil: [:spec |
+ 							sourcePointer := spec first.
+ 							category := spec second.
+ 							method := CompiledMethod toReturnSelfTrailerBytes:
+ 								(CompiledMethodTrailer new sourcePointer: sourcePointer).
+ 							method methodClass: class; selector: selector.
+ 							dateAndTime := spec size > 2 ifTrue: [spec third]]].
+ 				method ifNotNil: [
+ 					dateAndTime := [TimeStamp fromMethodTimeStamp: dateAndTime]
+ 							ifError: [TimeStamp epoch].
+ 					block
+ 						cull: method
+ 						cull: methodRecord changeType
+ 						cull: dateAndTime
+ 						cull: category]]]].!

Item was added:
+ ----- Method: ChangeSet>>classChanges (in category 'accessing') -----
+ classChanges
+ 
+ 	^ changeRecords keys select:
+ 		[:className | (changeRecords at: className) allChangeTypes notEmpty]!

Item was changed:
  ----- Method: ChangeSet>>event: (in category 'change logging') -----
  event: anEvent
  	"Hook for SystemChangeNotifier"
  	anEvent itemKind = SystemChangeNotifier classKind ifTrue: [
  		anEvent isRemoved 
  			ifTrue: [self noteRemovalOf: anEvent item].
  		anEvent isAdded 
  			ifTrue: [self addClass: anEvent item].
  		anEvent isModified 
  			ifTrue: [anEvent anyChanges ifTrue: [self changeClass: anEvent item from: anEvent oldItem]].
  		anEvent isCommented 
  			ifTrue: [self commentClass: anEvent item].
  		anEvent isRenamed 
  			ifTrue: [self renameClass: anEvent item from: anEvent oldName to: anEvent newName].
  		anEvent isReorganized
  			ifTrue: [self reorganizeClass: anEvent item].
  		anEvent isRecategorized
  			ifTrue: [self changeClass: anEvent item from: anEvent item].
  	].
  
  	anEvent itemKind = SystemChangeNotifier methodKind ifTrue: [
  		anEvent isAdded
  			ifTrue: [self noteNewMethod: anEvent item forClass: anEvent itemClass selector: anEvent itemSelector priorMethod: nil].
  		anEvent isModified
  			ifTrue: [self noteNewMethod: anEvent item forClass: anEvent itemClass selector: anEvent itemSelector priorMethod: anEvent oldItem].
  		anEvent isRemoved
+ 			ifTrue: [self removeSelector: anEvent itemSelector class: anEvent itemClass priorMethod: anEvent item lastMethodInfo: {anEvent item sourcePointer. anEvent itemProtocol. Utilities changeStamp}].
- 			ifTrue: [self removeSelector: anEvent itemSelector class: anEvent itemClass priorMethod: anEvent item lastMethodInfo: {anEvent item sourcePointer. anEvent itemProtocol}].
  		anEvent isRecategorized
  			ifTrue: [self reorganizeClass: anEvent itemClass].
  	].!

Item was changed:
  Object subclass: #ClassChangeRecord
+ 	instanceVariableNames: 'inForce revertable changeTypes thisDefinition priorDefinition thisName priorName thisOrganization priorOrganization thisComment priorComment thisMD priorMD methodChanges timeStamp'
- 	instanceVariableNames: 'inForce revertable changeTypes thisDefinition priorDefinition thisName priorName thisOrganization priorOrganization thisComment priorComment thisMD priorMD methodChanges'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'System-Changes'!
  
  !ClassChangeRecord commentStamp: 'fbs 9/6/2013 17:32' prior: 0!
  A ClassChangeRecorder keeps track of most substantive changes permissible 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.!

Item was changed:
  ----- Method: ClassChangeRecord>>noteChangeType:fromClass: (in category 'all changes') -----
  noteChangeType: changeSymbol fromClass: class
  
+ 	timeStamp := Utilities changeStamp.
  	(changeSymbol = #new or: [changeSymbol = #add]) ifTrue:
  		[changeTypes add: #add.
  		changeTypes remove: #change ifAbsent: [].
  		revertable := false.
  		^ self].
  	changeSymbol = #change ifTrue:
  		[(changeTypes includes: #add) ifTrue: [^ self].
  		^ changeTypes add: changeSymbol].
  	changeSymbol == #addedThenRemoved ifTrue:
  		[^ self].  "An entire class was added but then removed"
  	changeSymbol = #comment ifTrue:
  		[^ changeTypes add: changeSymbol].
  	changeSymbol = #reorganize ifTrue:
  		[^ changeTypes add: changeSymbol].
  	changeSymbol = #rename ifTrue:
  		[^ changeTypes add: changeSymbol].
  	(changeSymbol beginsWith: 'oldName: ') ifTrue:
  		["Must only be used when assimilating other changeSets"
  		(changeTypes includes: #add) ifTrue: [^ self].
  		priorName := changeSymbol copyFrom: 'oldName: ' size + 1 to: changeSymbol size.
  		^ changeTypes add: #rename].
  	changeSymbol = #remove ifTrue:
  		[(changeTypes includes: #add)
  			ifTrue: [changeTypes add: #addedThenRemoved]
  			ifFalse: [changeTypes add: #remove].
  		^ changeTypes removeAllFoundIn: #(add change comment reorganize)].
  
  	self error: 'Unrecognized changeType'!

Item was added:
+ ----- Method: ClassChangeRecord>>timeStamp (in category 'accessing') -----
+ timeStamp
+ 
+ 	^ timeStamp!



More information about the Packages mailing list