core/MetacelloVersionMethodSpec.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Tue, 18 Sep 2012 18:24:44 +0000
changeset 16 25ac697dc747
parent 14 f01fe37493e9
permissions -rw-r--r--
- Updated from branch master

"{ Package: 'stx:goodies/metacello/core' }"

MetacelloMethodSpec subclass:#MetacelloVersionMethodSpec
	instanceVariableNames:'imports'
	classVariableNames:''
	poolDictionaries:''
	category:'Metacello-Core-Constructors'
!


!MetacelloVersionMethodSpec methodsFor:'accessing'!

imports
	imports == nil ifTrue: [ imports := #() ].
	^ imports
!

imports: anObject
	imports := anObject
!

versionString: aStringOrSymbol

	aStringOrSymbol isSymbol ifTrue: [ self error: 'Version string ', aStringOrSymbol printString, ' for version method must be a String' ].
	super versionString: aStringOrSymbol
! !

!MetacelloVersionMethodSpec methodsFor:'adding'!

addMethodSection: attributeOrPath versionSpec: versionSpec
	| attribute methodSection index sections found |
	attributeOrPath isArray
		ifTrue: [ attribute := attributeOrPath last ]
		ifFalse: [ attribute := attributeOrPath ].
	methodSection := (MetacelloVersionMethodSection new)
		attribute: attribute;
		versionSpec: versionSpec;
		yourself.
	attributeOrPath isArray
		ifTrue: [ 
			index := 1.
			sections := self methodSections.
			found := true.
			[ found ]
				whileTrue: [ 
					found := false.
					sections
						do: [ :ms | 
							ms attribute == (attributeOrPath at: index)
								ifTrue: [ 
									index == (attributeOrPath size -1 )
										ifTrue: [ 
											ms methodSections add: methodSection.
											^ self ].
									sections := ms methodSections.
									index := index + 1.
									found := true ] ] ].
			self error: 'Method section for attribute: ' , (attributeOrPath at: index) printString , ' not found.' ]
		ifFalse: [ self methodSections add: methodSection ]
!

findMethodSection: attributeOrPath
	| attribute index sections found |
	attributeOrPath isArray
		ifTrue: [ attribute := attributeOrPath last ]
		ifFalse: [ attribute := attributeOrPath ].
	attributeOrPath isArray
		ifTrue: [ 
			index := 1.
			sections := self methodSections.
			found := true.
			[ found ]
				whileTrue: [ 
					found := false.
					sections
						do: [ :ms | 
							ms attribute == (attributeOrPath at: index)
								ifTrue: [ 
									index == (attributeOrPath size - 1)
										ifTrue: [ ^ ms ].
									sections := ms methodSections.
									index := index + 1.
									found := true ] ] ].
			self error: 'Method section for attribute: ' , (attributeOrPath at: index) printString , ' not found.' ]
		ifFalse: [ 
			^ self methodSections
				detect: [ :methodSection | methodSection attribute == attribute ]
				ifNone: [ self error: 'Method section for attribute: ' , attribute printString , ' not found.' ] ]
! !

!MetacelloVersionMethodSpec methodsFor:'method generation'!

methodSelectorAndPragma: aSelector imports: importList versionString: aString on: strm
	strm
		nextPutAll: aSelector asString , ' spec';
		cr;
		tab;
		nextPutAll: '<version: ' , aString printString.
	importList notEmpty
		ifTrue: [ 
			strm nextPutAll: ' imports: #('.
			importList
				do: [ :importVersionString | 
					strm
						nextPutAll: importVersionString printString;
						space ].
			strm nextPut: $) ].
	strm
		nextPutAll: '>';
		cr
!

methodSource
	| strm |
	strm := WriteStream on: String new.
	self
		methodSelectorAndPragma: self selector
		imports: self imports
		versionString: self versionString
		on: strm.
	self
		methodSection: self
		pre: [ :methodSection :indent | 
			strm
				cr;
				tab: indent;
				nextPutAll: 'spec for: #' , methodSection attribute asString printString , ' do: [';
				cr.
			methodSection versionSpec configMethodOn: strm last: methodSection methodSections isEmpty indent: indent + 1 ]
		last: false
		post: [ :methodSection :indent  :last | 
			strm nextPutAll: ' ].'.
			(last or: [ (indent = 1 or: [(methodSection methodSections isEmpty and: [ indent = 1 ])]) ])
				ifTrue: [ strm cr ] ]
		indent: 0.
	^ strm contents
! !

!MetacelloVersionMethodSpec methodsFor:'private'!

methodSection: methodSection pre: preBlock last: last post: postBlock indent: indent
	| list |
	methodSection ~~ self
		ifTrue: [ preBlock value: methodSection value: indent ].
	list := methodSection methodSections.
	1 to: list size
		do: [ :index | | ms | 
			ms := list at: index.
			self
				methodSection: ms
				pre: preBlock
				last: index ~= list size
				post: postBlock
				indent: indent + 1 ].
	methodSection ~~ self
		ifTrue: [ postBlock value: methodSection value: indent value: last ]
! !

!MetacelloVersionMethodSpec class methodsFor:'documentation'!

version_SVN
    ^ '$Id::                                                                                                                        $'
! !