'From Croquet1.0beta of 11 April 2006 [latest update: #1] on 19 May 2010 at 11:38:56 am'!!ClassDescription methodsFor: 'fileIn/Out' stamp: 'eem 5/19/2010 11:05'!printMethodChunkHistorically: selector on: outStream moveSource: moveSource toFile: fileIndex	"Copy all source codes historically for the method associated with selector onto the 	fileStream.  If moveSource true, then also set the source code pointer of the method."	| preamble method newPos sourceFile category changeList prior |	category := self organization categoryOfElement: selector.	preamble := self name , ' methodsFor: ', category asString printString.	method := self methodDict at: selector.	((method fileIndex = 0	or: [(SourceFiles at: method fileIndex) == nil])	or: [method filePosition = 0])	ifTrue: [		outStream cr; nextPut: $!!; nextChunkPut: preamble; cr.		outStream nextChunkPut: (			self decompilerClass new 				decompile: selector in: self method: method) decompileString.		outStream nextChunkPut: ' '; cr]	ifFalse: [		changeList := ChangeSet directAncestryOfVersions: (ChangeSet															scanVersionsOf: method 															class: self 															meta: self isMeta															category: category 															selector: selector).		newPos := prior := nil.		sourceFile := SourceFiles readOnlyCopyAt: method fileIndex.		changeList reverseDo: [ :chgRec |			chgRec fileIndex = fileIndex ifTrue: [				outStream copyPreamble: preamble from: sourceFile at: chgRec position.				prior ifNotNil:					[outStream						position: outStream position - 2;						nextPutAll: ' prior: ';						print: (SourceFiles 								sourcePointerFromFileIndex: prior fileIndex 								andPosition: prior position);						nextPut: $!!; cr].				"Copy the method chunk"				newPos := outStream position.				outStream copyMethodChunkFrom: sourceFile at: chgRec position.				sourceFile skipSeparators.      "The following chunk may have ]style["				sourceFile peek == $] ifTrue: [					outStream cr; copyMethodChunkFrom: sourceFile].				outStream nextChunkPut: ' '; cr.				chgRec position: newPos].			prior := chgRec].		moveSource ifTrue:			[method setSourcePosition: newPos inFile: fileIndex]].	^ outStream! !!ChangeRecord methodsFor: 'access' stamp: 'eem 5/19/2010 10:50'!position: anInteger	"Set the position.  Dangerous!!  Used in condenseChanges implementation by a very knowledgeable client!!"	position := anInteger! !!ChangeSet class methodsFor: 'scanning' stamp: 'eem 5/19/2010 10:08'!directAncestryOfVersions: changeRecords	"Take a sequence of ChangeRecords as answered by scanVersionsOf:class:meta:category:selector:	 and answer a filtered subsequence consisting only of direct ancestors.  For example, if the input is		eem 7/7/2009 20:06	7 July 2009 8:06 pm		eem 6/18/2009 19:21	18 June 2009 7:21 pm		eem 5/5/2009 12:16	5 May 2009 12:16 pm		eem 6/18/2009 19:19	18 June 2009 7:19 pm		eem 6/18/2009 18:57	18 June 2009 6:57 pm		eem 5/5/2009 12:16	5 May 2009 12:16 pm		eem 6/18/2009 18:17	18 June 2009 6:17 pm		eem 6/18/2009 18:14	18 June 2009 6:14 pm		eem 6/18/2009 18:06	18 June 2009 6:06 pm		eem 5/5/2009 12:16	5 May 2009 12:16 pm		eem 5/4/2009 19:19	4 May 2009 7:19 pm	the output should be		eem 7/7/2009 20:06	7 July 2009 8:06 pm		eem 6/18/2009 19:21	18 June 2009 7:21 pm		eem 5/5/2009 12:16	5 May 2009 12:16 pm		eem 5/4/2009 19:19	4 May 2009 7:19 pm"	| filtered i last |	filtered := OrderedCollection new.	i := 1.	[i <= changeRecords size] whileTrue:		[filtered addLast: (changeRecords at: i).		 last := changeRecords findLast: [:chgRec| filtered last stamp = chgRec stamp] startingAt: i.		 i := last = 0 ifTrue: [i + 1] ifFalse: [last + 1]].	^filtered! !!SequenceableCollection methodsFor: 'enumerating' stamp: 'eem 5/19/2010 09:57'!findLast: aBlock startingAt: i	"Return the index of my last element with index >= i for which aBlock evaluates as true."	| index |	index := self size + 1.	[(index := index - 1) >= i] whileTrue:		[(aBlock value: (self at: index)) ifTrue: [^index]].	^ 0! !!ClassDescription methodsFor: 'fileIn/Out' stamp: 'eem 5/18/2010 20:43'!fileOutChangedMessages: aSet on: aFileStream moveSource: moveSource toFile: fileIndex 	"File a description of the messages of this class that have been 	changed (i.e., are entered into the argument, aSet) onto aFileStream.  If 	moveSource, is true, then set the method source pointer to the new file position.	Note when this method is called with moveSource=true, it is condensing the	.changes file, and should only write a preamble for every method."	| org list done |	done := Set new. "avoid duplicates when saving"	(org := self organization) categories do: [:cat | 		list := (org listAtCategoryNamed: cat) select: [:sel | aSet includes: sel].		list := list reject:[:sel| done includes: sel].		(moveSource or: [(cat beginsWith: '*') and: [cat endsWith: '-override']]) ifTrue:[			list do:[:sel |				"(done includes: sel) ifTrue:[self error: sel, 'duplicate method']."				self printMethodChunkHistorically: sel on: aFileStream					moveSource: moveSource toFile: fileIndex]		] ifFalse: [			list do:[:sel |				"(done includes: sel) ifTrue:[self error: sel, 'duplicate method']."				self printMethodChunk: sel withPreamble: true on: aFileStream					moveSource: moveSource toFile: fileIndex].		].		done addAll: list.	].! !  !ChangeRecord methodsFor: 'access' stamp: 'eem 5/18/2010 20:25'!fileIndex	SourceFiles withIndexDo: [:sf :i| sf name = file name ifTrue: [^i]].	^nil! !!ClassDescription methodsFor: 'fileIn/Out' stamp: 'eem 5/18/2010 19:24'!printMethodChunk: selector withPreamble: doPreamble on: outStream		moveSource: moveSource toFile: fileIndex	"Copy the source code for the method associated with selector onto the fileStream.  If moveSource true, then also set the source code pointer of the method."	| preamble method oldPos newPos sourceFile endPos |	doPreamble 		ifTrue: [preamble := self name , ' methodsFor: ' ,					(self organization categoryOfElement: selector) asString printString]		ifFalse: [preamble := ''].	method := self methodDict at: selector ifAbsent:		[outStream nextPutAll: selector; cr.		outStream tab; nextChunkPut: '** ERROR!!  THIS SCRIPT IS MISSING ** ' translated; cr; cr.		outStream nextPutAll: '  '.		^ outStream].	(method fileIndex = 0	 or: [(SourceFiles at: method fileIndex) == nil	 or: [(oldPos := method filePosition) = 0]])		ifTrue:		["The source code is not accessible.  We must decompile unless condensing..."		moveSource ifFalse:			[preamble size > 0 ifTrue: [outStream cr; nextPut: $!!; nextChunkPut: preamble; cr].			 outStream nextChunkPut: (self decompilerClass new decompile: selector											in: self method: method) decompileString]]		ifFalse:		[sourceFile := SourceFiles at: method fileIndex.		preamble size > 0			ifTrue:    "Copy the preamble"				[outStream copyPreamble: preamble from: sourceFile at: oldPos]			ifFalse:				[sourceFile position: oldPos].		"Copy the method chunk"		newPos := outStream position.		outStream copyMethodChunkFrom: sourceFile.		sourceFile skipSeparators.      "The following chunk may have ]style["		sourceFile peek == $] ifTrue: [			outStream cr; copyMethodChunkFrom: sourceFile].		moveSource ifTrue:    "Set the new method source pointer"			[endPos := outStream position.			method checkOKToAdd: endPos - newPos at: newPos.			method setSourcePosition: newPos inFile: fileIndex]].	preamble size > 0 ifTrue: [outStream nextChunkPut: ' '].	^ outStream cr! !!CProtoObject class methodsFor: 'class definition' stamp: 'eem 5/18/2010 19:23'!printMethodChunk: selector withPreamble: doPreamble on: outStream		moveSource: moveSource toFile: fileIndex	"Copy the source code for the method associated with selector onto the fileStream.  If moveSource true, then also set the source code pointer of the method."	| preamble method oldPos newPos sourceFile endPos |	doPreamble 		ifTrue: [preamble := self printString , ' methodsFor: ' ,					(self organization categoryOfElement: selector) asString printString]		ifFalse: [preamble := ''].	method := self methodDict at: selector ifAbsent:		[outStream nextPutAll: selector; cr.		outStream tab; nextChunkPut: '** ERROR!!  THIS SCRIPT IS MISSING ** ' translated; cr; cr.		outStream nextPutAll: '  '.		^ outStream].	(method fileIndex = 0	 or: [(SourceFiles at: method fileIndex) == nil	 or: [(oldPos := method filePosition) = 0]])		ifTrue:		["The source code is not accessible.  We must decompile unless condensing..."		moveSource ifFalse:			[preamble size > 0 ifTrue: [outStream cr; nextPut: $!!; nextChunkPut: preamble; cr].			 outStream nextChunkPut: (self decompilerClass new decompile: selector											in: self method: method) decompileString]]		ifFalse:		[sourceFile := SourceFiles at: method fileIndex.		preamble size > 0			ifTrue:    "Copy the preamble"				[outStream copyPreamble: preamble from: sourceFile at: oldPos]			ifFalse:				[sourceFile position: oldPos].		"Copy the method chunk"		newPos := outStream position.		outStream copyMethodChunkFrom: sourceFile.		sourceFile skipSeparators.      "The following chunk may have ]style["		sourceFile peek == $] ifTrue:			[outStream cr; copyMethodChunkFrom: sourceFile].		moveSource ifTrue:    "Set the new method source pointer"			[endPos := outStream position.			method checkOKToAdd: endPos - newPos at: newPos.			method setSourcePosition: newPos inFile: fileIndex]].	preamble size > 0 ifTrue: [outStream nextChunkPut: ' '].	^ outStream cr! !