[Pkg] DeltaStreams: DeltaStreams-Model-gk.15.mcz

squeak-dev-noreply at lists.squeakfoundation.org squeak-dev-noreply at lists.squeakfoundation.org
Sun Sep 6 12:19:36 UTC 2009


A new version of DeltaStreams-Model was added to project DeltaStreams:
http://www.squeaksource.com/DeltaStreams/DeltaStreams-Model-gk.15.mcz

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

Name: DeltaStreams-Model-gk.15
Author: gk
Time: 6 September 2009, 2:19:12 am
UUID: da6d637f-b42d-47b8-a736-3a1094abeddc
Ancestors: DeltaStreams-Model-gk.14

- Renamed revertable to reversable.
- normalize renamed to compress
- isReversable modified and commented.
- Refactorings
- Added DSDelta>>recordDoIts:
- Implemented DsDoIt change.


=============== Diff against DeltaStreams-Model-gk.14 ===============

Item was added:
+ ----- Method: DSDelta>>recordDoIts: (in category 'configuration') -----
+ recordDoIts: aBoolean
+ 	self propertyAt: #recordDoIt put: aBoolean!

Item was added:
+ ----- Method: DSDoIt>>applyUsing: (in category 'applying') -----
+ applyUsing: anApplier
+ 	"Apply this change to the image. Double dispatch."
+ 
+ 	anApplier applyDoIt: self!

Item was added:
+ ----- Method: DSDoIt>>antiDoIt: (in category 'accessing') -----
+ antiDoIt: aString 
+ 	"If you mark this DoIt to executeOnApply then you can also supply
+ 	an antiDoIt to use in the antiChange."
+ 
+ 	antiDoIt := aString!

Item was changed:
  ----- Method: DSChangeSequence>>moveClassNameChanges (in category 'applying') -----
  moveClassNameChanges
+ 	"Move all class name changes to the beginning as if they were made first.
+ 	NOTE: This code does not work yet, because all method changes need to do
+ 	class name replacing inside the source... I am not even sure this is a good idea."
- 	"Move all class name changes to the beginning as if they were made first."
  
+ 	| nameChanges map newChanges |
+ 	newChanges := OrderedCollection new.
- 	| nameChanges map |
  	nameChanges := OrderedCollection new.
  	map := Dictionary new.
  	changes reverseDo: [:change |
  		change isClassName
  			ifTrue: [
  				"Is there already a mapping in place?"
  				(map includesKey: change newName)
  					ifTrue: [
  						"Then we remap it using the even older name as key from now on"
  						map at: change oldName put: (map at: change newName).
  						map removeKey: change newName]
  					ifFalse: [
  						"Then we just add a mapping."
+ 						map at: change oldName put: change newName.
+ 						nameChanges add: change]]
- 						map at: change oldName put: change newName].
- 				nameChanges add: change ]
  			ifFalse: [
+ 				"Tell the change to refer to the newer names that we have collected"
+ 				change remapClassNames: map.
+ 				newChanges add: change]].
+ 	^nameChanges, newChanges!
- 				change remapClassNames: map]].
- 	changes removeAll: nameChanges.
- 	changes := nameChanges, changes!

Item was added:
+ ----- Method: DSDelta>>recordDoIts (in category 'configuration') -----
+ recordDoIts
+ 	^self propertyAt: #recordDoIt ifAbsent: [false]!

Item was added:
+ ----- Method: DSDoIt>>kind (in category 'properties') -----
+ kind
+ 	^self propertyAt: #kind!

Item was added:
+ ----- Method: DSDelta>>isReversable (in category 'testing') -----
+ isReversable
+ 	"It is reversable if all changes are reversable and this Delta is not explicitly flagged
+ 	as NON reversable. This still depends on any included DoIts being reversible,
+ 	and for that we depend on trusting the EXPLICIT marking of those DoIts claiming that
+ 	they are indeed reversable.
+ 	In other words, if this method returns true it SHOULD be reversable if:
+ 		- This Delta was the last change to the image.
+ 		- Any included DoIts do the right thing (depending on the author of them)
+ 		
+ 	In other words - a positive answer means that you are ABLE to try reverting it.
+ 	It does not mean that it will work, it just means that it COULD work."
+ 
+ 	^(self propertyAt: #reversable ifAbsent: [true]) and: [self changesReversable]!

Item was added:
+ ----- Method: DSDoIt>>contextWasNil (in category 'properties') -----
+ contextWasNil
+ 	^self propertyAt: #contextWasNil!

Item was added:
+ ----- Method: DSVisitor>>applyDoIt: (in category 'doit changes') -----
+ applyDoIt: aDoIt
+ 	"A generic DoIt code snippet."
+ 
+ 	^ self applyChange: aDoIt!

Item was changed:
+ ----- Method: DSDelta>>changes (in category 'changes') -----
- ----- Method: DSDelta>>changes (in category 'accessing') -----
  changes
  	^ changeSequence changes!

Item was added:
+ ----- Method: DSDelta>>isNotReversable (in category 'testing') -----
+ isNotReversable
+ 	"See #isReversable."
+ 
+ 	^self isReversable not!

Item was added:
+ ----- Method: DSDoIt>>contextWasNil: (in category 'private') -----
+ contextWasNil: aBoolean
+ 	self propertyAt: #contextWasNil put: aBoolean!

Item was added:
+ ----- Method: DSDoIt>>executeOnApply (in category 'configuration') -----
+ executeOnApply
+ 	^self propertyAt: #executeOnApply!

Item was added:
+ ----- Method: DSDelta>>compress (in category 'manipulate') -----
+ compress
+ 	"Modify changes so that they are compacted into the minimal form
+ 	still producing the equivalent end result. In other words - remove redundancy.
+ 	Fir we move all class rename changes to the beginning, but AFTER any DoIts.
+ 	Then we remove all redundant shadowed changes.
+ 	Finally we merge those we can merge."
+ 
+ 	changeSequence ifNotNil: [
+ 		changeSequence moveClassNameChanges; removeShadows; mergeChanges]!

Item was added:
+ ----- Method: DSDelta>>remove: (in category 'changes') -----
+ remove: aChange
+ 
+ 	| change |
+ 	change := self changes remove: change.
+ 	self grouper ifNotNil: [self grouper remove: change].
+ 	self changed: #changeList.
+ 	^ change!

Item was added:
+ ----- Method: DSDoIt>>remapClassNames: (in category 'private') -----
+ remapClassNames: map
+ 	"We really can't do it 100% for sure. We could of course warn the user."
+ 
+ !

Item was changed:
  ----- Method: DSDelta>>asAntiDelta (in category 'applying') -----
  asAntiDelta
  	"Return a new Delta that, when applied, reverts each change of this Delta
  	in reverse order. Each change should have enough information to create
  	an anti change from itself."
  
  	| anti |
+ 	self isReversable ifFalse: [self error: 'This delta is not reversable'].
+ 	anti := DSDelta name: 'Anti ' translated, self name.
- 	self isRevertable ifFalse: [DSDeltaNotRevertableException signal].
- 	anti := DSDelta name: 'undo ' translated, self name.
  	self propertiesDo: [:key :val | anti propertyAt: key put: val]. 
  	self changes reverseDo: [:each | anti add: each asAntiChange]. 
  	^anti!

Item was added:
+ ----- Method: DSDoIt>>isReversable (in category 'testing') -----
+ isReversable
+ 	"If this DoIt is marked to NOT execute (then it of course does nothing and is
+ 	trivially reversable) or if there is a supplied antiDoIt signifying that it indeed
+ 	can be reversed.
+ 	
+ 	NOTE: We trust the developer here. isReversable does NOT mean that it will work."
+ 
+ 	^self executeOnApply not or: [antiDoIt notNil]!

Item was added:
+ ----- Method: DSDelta>>hasDoIts (in category 'testing') -----
+ hasDoIts
+ 	"Do I include any DoIts? If I do it affects the trustworthiness of reversability."
+ 
+ 	^self changes anySatisfy: [:each | each isDoIt]!

Item was changed:
  DSChange subclass: #DSDoIt
+ 	instanceVariableNames: 'expression antiExpression contextWasNil kind status antiDoIt doIt'
- 	instanceVariableNames: 'code'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'DeltaStreams-Model-Base'!
+ 
+ !DSDoIt commentStamp: 'gk 9/5/2009 15:24' prior: 0!
+ A DSDoIt change is only recorded if you expressly configure the Delta to record them. While catching all doits this also creates redundant doits because for class definition changes the Delta will record both the event coming from ClassBuilder and then the doit itself too. Not sure exactly how we can prevent this in a NICE way
+ 
+ Currently DoIts are handled like this:
+ 	- We only record them if the Delta is configured to do that, see #recordDoits:
+ 	- We only apply them if they are marked explicitly to be applied, see #executeOnApply:
+ 	- We only consider a DoIt reversable if the antiDoIt if is set to something other than nil.
+ 	
+ Good rules to follow:
+ 	1. Do not record or use DoIts. :) If you really need to have a DoIt in your Delta, put it there manually.
+ 	2. If you record DoIts because you do not want to miss anything , prune them out before distributing the Delta.
+ 	3. If you still have a DoIt in your Delta that you intend to distribute, make sure that:
+ 		- It can cope with missing globals/classes!!
+ 		- It can be safely run multiple times without problems!!
+ 		- You marked it to be run on apply using #executeOnApply:. This is an EXPLICIT step for a reason.
+ 		- If it should do able to be REVERSED you need to supply an antiDoIt.
+ 		- Put DoIts preferrably first or last in the Delta to avoid strange situations. Remember that even if changes are ordered they may be applied atomically by an applier.
+ 
+ NOTE: A Delta containing any DoIt will be visualized as "dangerous" in the user interfaces so please avoid them unless you REALLY need them.!

Item was changed:
  ----- Method: DSClassSuperclassChange>>remapClassNames: (in category 'private') -----
  remapClassNames: map
  
  	super remapClassNames: map.
+ 	oldSuperclassName := map at: oldSuperclassName ifAbsent: [oldSuperclassName]!
- 	oldSuperclassName := map at: oldSuperclassName ifAbsent: [oldSuperclassName].
- 	newSuperclassName := map at: newSuperclassName ifAbsent: [newSuperclassName].!

Item was added:
+ ----- Method: DSDoIt class>>doIt: (in category 'accessing') -----
+ doIt: aString
+ 	^self doIt: aString antiDoIt: nil!

Item was added:
+ ----- Method: DSDoIt>>asAntiChange (in category 'anti') -----
+ asAntiChange
+ 	"We swap doIts."
+ 
+ 	^ (self antiChangeClass fromChange: self)
+ 		doIt: antiDoIt;
+ 		antiDoIt: doIt!

Item was added:
+ ----- Method: DSSystemEditorApplier>>applyDoIt: (in category 'doit changes') -----
+ applyDoIt: aDoIt
+ 	"A generic DoIt code snippet."
+ 
+ 	aDoIt executeOnApply ifTrue: [
+ 		Compiler evaluate: aDoIt doIt logged: true]!

Item was changed:
+ ----- Method: DSDelta>>classGroupsDo: (in category 'manipulate') -----
- ----- Method: DSDelta>>classGroupsDo: (in category 'applying') -----
  classGroupsDo: aBlock
  	"Execute a block for all groups of changes per class."
  
  	| groups coll |
  	groups := Dictionary new.
  	self changes do: [:each |
  		coll := groups at: each className ifAbsentPut: [SortedCollection new].
  		coll add: each].
  	groups values do: [:group | aBlock value: group]!

Item was added:
+ ----- Method: DSDoIt>>doIt: (in category 'accessing') -----
+ doIt: aString 
+ 	doIt := aString!

Item was added:
+ ----- Method: DSDelta>>changesReversable (in category 'testing') -----
+ changesReversable
+ 	"Are all changes reversable?"
+ 
+ 	^self changes allSatisfy: [:change | change isReversable]!

Item was added:
+ ----- Method: DSDoIt>>executeOnApply: (in category 'configuration') -----
+ executeOnApply: aBoolean
+ 	self propertyAt: #executeOnApply put: aBoolean!

Item was added:
+ ----- Method: DSDoIt class>>doIt:antiDoIt: (in category 'accessing') -----
+ doIt: aString antiDoIt: anotherString
+ 	^self new doIt: aString; antiDoIt: anotherString!

Item was added:
+ ----- Method: DSChange>>isReversable (in category 'testing') -----
+ isReversable
+ 	"By default we answer yes."
+ 
+ 	^true!

Item was changed:
  DSAnnotatedObject subclass: #DSDelta
  	instanceVariableNames: 'uuid changeSequence'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'DeltaStreams-Model-Base'!
  
+ !DSDelta commentStamp: 'gk 9/5/2009 15:06' prior: 0!
- !DSDelta commentStamp: 'gk 9/2/2009 19:02' prior: 0!
  A Delta is much like a ChangeSet but improved and simplified. It can capture changes like a ChangeSet does (see #event:), but unlike ChangeSets multiple Deltas can be logging changes at the same time. A Delta maintains an ordered collection of change objects that is a true log unlike a ChangeSet which tries to normalize changes on the fly and does not maintain an order.
  
  Also - each change object carries more information than a record in a ChangeSet does - and they know how to produce their anti change which in turn gives a Delta the ability to produce its own anti Delta. Such an anti Delta can be used to revert a Delta.
- 
- Instance variables:
- 
- changeSequence - an instance of DSChangeSequence.
- uuid - created when I am first instantiated, never changed.
- 
- Standard properties:
  
+ Deltas can be filed out in a file using Tirade format and the file extension 'd' and 'd.gz' for GZIP compression. One file can contain multiple Deltas, the file name is not used for anything in the Delta.
+ 
+ Instance variables:
+ 
+ changeSequence - an instance of DSChangeSequence.
+ uuid - created when I am first instantiated, never changed.
+ 
- #revertable - if missing we presume true. Can be used to explicitly flag a Delta as revertable/not revertable.
  !

Item was added:
+ ----- Method: DSDoIt>>kind: (in category 'private') -----
+ kind: aSymbol
+ 	self propertyAt: #kind put: aSymbol!

Item was removed:
- ----- Method: DSVisitorWrapper>>applyChange: (in category 'basic') -----
- applyChange: change
- 	^ change applyUsing: visitor!

Item was removed:
- Exception subclass: #DSDeltaNotRevertableException
- 	instanceVariableNames: ''
- 	classVariableNames: ''
- 	poolDictionaries: ''
- 	category: 'DeltaStreams-Model-Base'!

Item was removed:
- ----- Method: DSDelta>>changesRevertable (in category 'testing') -----
- changesRevertable
- 	"Are all changes per definition revertable?"
- 
- 	^self changes allSatisfy: [:change | change isRevertable]!

Item was removed:
- ----- Method: DSVisitorWrapper class>>on: (in category 'as yet unclassified') -----
- on: aVisitor
- 	^ self new visitor: aVisitor!

Item was removed:
- ----- Method: DSChange>>isRevertable (in category 'testing') -----
- isRevertable
- 	"By default we answer yes."
- 
- 	^true!

Item was removed:
- ----- Method: DSDelta>>removeChange: (in category 'changes') -----
- removeChange: aChange
- 
- 	| change |
- 	change := self changes remove: change.
- 	self grouper ifNotNil: [self grouper remove: change].
- 	self changed: #changeList.
- 	^ change!

Item was removed:
- ----- Method: DSDelta>>addClassChange:from: (in category 'applying') -----
- addClassChange: changeClass from: event
- 	"Extract all relevant information from the event
- 	to create and add a class change of given class name."
- 
- 	| class metaclass |
- 	class := event itemClass theNonMetaClass.
- 	metaclass := event itemClass theMetaClass.
- 	^self add: (
- 		self className: class name
- 			changeClass: changeClass
- 			superclassName: class superclass name
- 			instVarNames: class instVarNames
- 			classVarNames: class classVarNames asArray
- 			poolDictionaryNames: class poolDictionaryNames
- 			category: class category
- 			type: class typeOfClass
- 			classInstVarNames: metaclass instVarNames
- 			comment: class organization classComment asString
- 			stamp: class organization commentStamp)!

Item was removed:
- DSVisitor subclass: #DSVisitorWrapper
- 	instanceVariableNames: 'visitor'
- 	classVariableNames: ''
- 	poolDictionaries: ''
- 	category: 'DeltaStreams-Model-Visitors'!
- 
- !DSVisitorWrapper commentStamp: 'mtf 9/29/2007 14:15' prior: 0!
- My instances intercept change requests and act on them and optionally forward them to the wrapped visitor. we can be chained and composed together!

Item was removed:
- ----- Method: DSDelta>>addMethodChange:from: (in category 'applying') -----
- addMethodChange: changeClass from: event
- 	"Extract all relevant information from the event
- 	to create and add a method change of given class name."
- 
- 	| method selector class category |
- 	category := event itemProtocol.
- 	method := event item "Method".
- 	"Do not ask me why we need to do it like the next three lines..."
- 	selector := event itemSelector.
- 	selector ifNil: [selector := event itemMethod sourceSelector].
- 	selector ifNil: [selector := event itemMethod selector].
- 	class := event itemClass.
- 	^self add: (
- 		self className: class name
- 			selector: selector
- 			change: changeClass
- 			category: category
- 			source: method getSource asString
- 			stamp: method timeStamp)!

Item was removed:
- ----- Method: DSVisitorWrapper>>chain: (in category 'initialize-release') -----
- chain: aVisitor
- 	chain := aVisitor.
- 	visitor chain: aVisitor!

Item was removed:
- ----- Method: DSVisitorWrapper>>visitor: (in category 'initialize-release') -----
- visitor: aVisitor
- 	visitor := aVisitor.
- 	aVisitor chain: self!

Item was removed:
- ----- Method: DSDelta>>isRevertable (in category 'testing') -----
- isRevertable
- 	"It is revertable if all changes are per definition revertable
- 	and this Delta is flagged as revertable."
- 
- 	^(self propertyAt: #revertable ifAbsent: [true]) and: [self changesRevertable]!

Item was removed:
- ----- Method: DSDelta>>normalize (in category 'applying') -----
- normalize
- 	"Modify changes so that they are compacted into the minimal form
- 	still producing the equivalent end result. In other words - remove redundancy."
- 
- 	changeSequence ifNotNil: [
- 		changeSequence moveClassNameChanges; removeShadows; mergeChanges]!



More information about the Packages mailing list