core/MetacelloSpec.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' }"

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::                                                                                                                        $'
! !