"{ Package: 'stx:goodies/metacello/core' }"
Object subclass:#MetacelloSpec
instanceVariableNames:'project loader mutable'
classVariableNames:''
poolDictionaries:''
category:'Metacello-Core-Specs'
!
!MetacelloSpec class methodsFor:'instance creation'!
for: aVersionMap
^(self platformClass new)
for: aVersionMap;
yourself
! !
!MetacelloSpec class methodsFor:'accessing'!
platformClass
^self
! !
!MetacelloSpec methodsFor:'accessing'!
loader
loader == nil
ifTrue: [ | prjctLoader |
(prjctLoader := self project loader) == nil
ifTrue: [ self loader: (self project loaderClass on: self) ]
ifFalse: [ self loader: prjctLoader ]].
^loader
!
loader: aLoader
"We're interested in propogating the loader state, _except_ for the spec"
self shouldBeMutable.
loader := aLoader copy.
loader spec: self
! !
!MetacelloSpec methodsFor:'copying'!
postCopy
super postCopy.
mutable := nil.
loader ~~ nil
ifTrue: [ self loader: loader ].
! !
!MetacelloSpec methodsFor:'doits'!
doItBlock: selector
selector == nil ifTrue: [ ^nil ].
selector numArgs = 0
ifTrue: [ ^[ self project configuration perform: selector ] ].
selector numArgs = 1
ifTrue: [ ^[:aLoader | self project configuration perform: selector with: aLoader ] ].
selector numArgs = 2
ifTrue: [ ^[:aLoader :pkgSpec | self project configuration perform: selector with: aLoader with: pkgSpec ] ].
^nil
!
postLoadDoIt
"noop unless non-nil value returned"
^nil
!
postLoadDoItBlock
^self doItBlock: self postLoadDoIt value
!
preLoadDoIt
"noop unless non-nil value returned"
^nil
!
preLoadDoItBlock
^self doItBlock: self preLoadDoIt value
! !
!MetacelloSpec methodsFor:'importing'!
mergeImportLoads: aLoadList
self error: 'import: can only be used with baseline project specs'
! !
!MetacelloSpec methodsFor:'initialization'!
for: aProject
self shouldBeMutable.
project := aProject
! !
!MetacelloSpec methodsFor:'merging'!
aboutToCopy
!
mergeMap
^Dictionary new.
!
mergeSpec: aSpec
| newSpec nonOverridable |
self validateMergeForSpec: aSpec.
newSpec := self copy.
nonOverridable := self nonOverridable.
aSpec mergeMap
keysAndValuesDo: [ :key :value |
(nonOverridable includes: key)
ifFalse: [
value ~~ nil
ifTrue: [ newSpec instVarNamed: key asString put: value ] ] ].
^ newSpec
!
nonOverridable
^#()
!
validateMergeForSpec: aSpec
aSpec class = self class
ifFalse: [
self
error:
'The project spec ' , self name printString , ' in project ' , self project label , ' has incompatible specs. '
, aSpec class name asString , ' and ' , self class name asString , ' are not compatible.' ]
! !
!MetacelloSpec methodsFor:'mutability'!
copyOnWrite: aBlock
"assume that only registered projects are immutable ... otherwise you'll get an error"
| copy |
copy := self copy.
aBlock value: copy.
^ copy
!
immutable
mutable := false
!
isMutable
mutable ifNil: [ ^ true ].
^ mutable
!
mutable
mutable := true
!
shouldBeMutable
self isMutable
ifTrue: [ ^ self ].
self error: 'Not allowed to modify an immutable object'
! !
!MetacelloSpec methodsFor:'printing'!
configMethodOn: aStream
self configMethodOn: aStream indent: 0
!
configMethodOn: aStream indent: indent
self subclassResponsibility
!
label
^self printString
!
printOn: aStream
self configMethodOn: aStream indent: 0
! !
!MetacelloSpec methodsFor:'querying'!
answers
^#()
!
project
^project
! !
!MetacelloSpec methodsFor:'spec creation'!
addMember
^MetacelloAddMemberSpec for: self project
!
copyMember
^MetacelloCopyMemberSpec for: self project
!
mergeMember
^MetacelloMergeMemberSpec for: self project
!
removeMember
^MetacelloRemoveMemberSpec for: self project
! !
!MetacelloSpec class methodsFor:'documentation'!
version_SVN
^ '$Id:: $'
! !