Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions src/Molecule-Tests/MolCompleteComponentOverloadImpl.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,6 @@ MolCompleteComponentOverloadImpl class >> usedComponentServices [
MolUsedServices2 }
]

{ #category : #events }
MolCompleteComponentOverloadImpl >> event [
^ #event
]

{ #category : #events }
MolCompleteComponentOverloadImpl >> event2 [

^ #event2
]

{ #category : #'component accessing' }
MolCompleteComponentOverloadImpl >> getMolUsedEvents2Notifier [
^self eventsNotifiers at: MolUsedEvents2 ifAbsent: [^MolNotFoundEventsNotifier new interface: MolUsedEvents2 name: nil].
Expand Down Expand Up @@ -161,26 +150,3 @@ MolCompleteComponentOverloadImpl >> getMolUsedServicesProvider [
servicesProvider := MolComponentManager default locatorServices searchServicesProviderFor: MolUsedServices named: servicesSymbol.
^servicesProvider
]

{ #category : #parameters }
MolCompleteComponentOverloadImpl >> parameter [
^ #parameter
]

{ #category : #'parameters 2' }
MolCompleteComponentOverloadImpl >> parameter2 [

^ #parameter2
]

{ #category : #service }
MolCompleteComponentOverloadImpl >> service [
"test"
^ #service
]

{ #category : #'service 2' }
MolCompleteComponentOverloadImpl >> service2 [
"test2"
^ #service2
]
97 changes: 30 additions & 67 deletions src/Molecule-Tests/MolComponentFactoryTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ Class {

{ #category : #running }
MolComponentFactoryTest >> cleanGeneratedClassesAndTraits [
<script: 'self new cleanGeneratedClassesAndTraits'>

| edited |

edited := false.

self class environment at: self generatedComponentClassSymbolName ifPresent: [ :c | c removeFromSystem. edited := true].
Expand All @@ -32,13 +31,12 @@ MolComponentFactoryTest >> cleanGeneratedClassesAndTraits [
{ #category : #running }
MolComponentFactoryTest >> cleanGeneratedMethods [
"Restore methods added by tests"
<script: 'self new cleanGeneratedMethods'>

MolCompleteSubComponentOverloadImpl class removeSelector: #usedComponentServices.
MolCompleteSubComponentOverloadImpl class removeSelector: #providedComponentServices
]

{ #category : #utils }
{ #category : #utilities }
MolComponentFactoryTest >> createInstanceMethod: aSelector in: aClassOrTrait protocol: aProtocolString withCode: aSourceCodeString [
"Create an instance method in a Class or Trait with source code implementation"
| sourceCode |
Expand Down Expand Up @@ -118,11 +116,25 @@ MolComponentFactoryTest >> generationTag [
^'Molecule-Tests-Resources - Generated'
]

{ #category : #utilities }
MolComponentFactoryTest >> resetSourceCode [
<script:'self new resetSourceCode'>

MolComponentFactory default deactivateDynamicContractUpdate: false.

self cleanGeneratedClassesAndTraits.
self restoreRemovedThings.
self cleanGeneratedMethods.

MolComponentFactory default activateDynamicContractUpdate: false.

"Issue #230: Define the component manually after source code modification without dynamic update"
MolCompleteComponentOverloadImpl defineComponent.
]

{ #category : #running }
MolComponentFactoryTest >> restoreRemovedThings [
"Restore things removed in tests"
<script: 'self new restoreRemovedThings'>

"Simulate an overridden contract by the user VV"

self createInstanceMethod: 'usedComponentServices' in: (MolCompleteComponentOverloadImpl class) protocol: 'accessing - services' withCode: '"Warning: dont edit this method, it is generated in MolComponentFactoryTest>>restoreRemovedThings"
Expand Down Expand Up @@ -171,72 +183,23 @@ MolComponentFactoryTest >> restoreRemovedThings [
{ #category : #running }
MolComponentFactoryTest >> setUp [

super setUp.

self timeLimit: 30 seconds.
MolComponentManager cleanUp.

MolComponentFactory default deactivateDynamicContractUpdate: false.
self cleanGeneratedClassesAndTraits.
self restoreRemovedThings.
self cleanGeneratedMethods.
MolComponentFactory default activateDynamicContractUpdate: false.

]

{ #category : #running }
MolComponentFactoryTest >> setUpComponentAndType [
<script: 'self new setUpComponentAndType'>
| edited |
edited := false.

"Prepare or reset required test classes"
self class environment at: self generatedComponentTypeSymbolName ifAbsent: [
MolComponentFactory createComponentType: self generatedComponentTypeSymbolName in: self generationTag.
edited := true.
].

self class environment at: self generatedComponentServicesSymbolName ifAbsent: [
MolComponentFactory createComponentServices: self generatedComponentServicesSymbolName in: self generationTag.
edited := true.
].

self class environment at: self generatedComponentParametersSymbolName ifAbsent: [
MolComponentFactory createComponentParameters: self generatedComponentParametersSymbolName in: self generationTag.
edited := true.
].

self class environment at: self generatedComponentEventsSymbolName ifAbsent: [
MolComponentFactory createComponentEvents: self generatedComponentEventsSymbolName in: self generationTag.
edited := true.
].

self class environment at: self generatedComponentClassSymbolName ifAbsent: [
MolComponentFactory createComponentForType: MolCompleteComponent named: self generatedComponentClassSymbolName in: self generationTag.
edited := true.
].

self class environment at: self generatedComponentClass2SymbolName ifAbsent: [
MolComponentFactory createComponentForType: MolCompleteComponent named: self generatedComponentClass2SymbolName in: self generationTag.
edited := true.
].

(MolCompleteComponent usedComponentServices includes: MolUsedServices) ifFalse:[
MolComponentFactory addUsedServices: MolUsedServices in: MolCompleteComponent.
edited := true.
].
self resetSourceCode

edited ifTrue:[(Delay forMilliseconds: 100) wait].
]

{ #category : #running }
MolComponentFactoryTest >> tearDown [

MolComponentFactory default deactivateDynamicContractUpdate: false.
self cleanGeneratedClassesAndTraits.
self restoreRemovedThings.
self cleanGeneratedMethods.
MolComponentFactory default activateDynamicContractUpdate: false.
self resetSourceCode.

MolComponentManager cleanUp.

super tearDown.
]

{ #category : #tests }
Expand Down Expand Up @@ -1450,9 +1413,6 @@ MolComponentFactoryTest >> testSubOverrideOfContractAddingProvidedServices [

| usedServices |

self flag:'Pharo doesnt support this use cases (see #210)'.
true ifTrue:[ ^ self ].

"initial state"
usedServices := MolCompleteSubComponentOverloadImpl providedComponentServices.
self assert: usedServices size equals: 2.
Expand Down Expand Up @@ -1485,11 +1445,11 @@ MolComponentFactoryTest >> testSubOverrideOfContractAddingProvidedServices [

"Clean generated method"
MolCompleteSubComponentOverloadImpl class removeSelector: #providedComponentServices.
"test initial state again"

self flag:'Need to rewrite dynamic contract system to wait all system modifications before define components'.
100 milliSeconds wait.
"Waiting for system modifications notifications for defining components (as IDE usage)"
0.5 seconds wait.

"test initial state again"
usedServices := MolCompleteSubComponentOverloadImpl providedComponentServices.
self assert: usedServices size equals: 2.
self deny: (usedServices includes: MolUsedServices3).
Expand Down Expand Up @@ -1538,6 +1498,9 @@ MolComponentFactoryTest >> testSubOverrideOfContractAddingUsedServices [
"Clean generated method"
MolCompleteSubComponentOverloadImpl class removeSelector: #usedComponentServices.

"Waiting for system modifications notifications for defining components (as IDE usage)"
0.5 seconds wait.

"initial state"
usedServices := MolCompleteSubComponentOverloadImpl usedComponentServices.
self assert: usedServices size equals: 2.
Expand Down
82 changes: 52 additions & 30 deletions src/Molecule/MolComponentFactory.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -623,36 +623,38 @@ MolComponentFactory >> dirtyComponents [
]

{ #category : #'private - code generation' }
MolComponentFactory >> generateComponentAccessorsFor: aSymbol withList: aCollection in: aComponent suffix: suffix [
| selector sourceCode sourceMethod method |

aCollection copy do: [ :e | | trait |

"e can be another thing that a Trait, need to check nature of e before generate"
( e notNil and:[ e isTrait and:[( e isComponentServices or:[ e isComponentParameters or:[ e isComponentEvents ]])]]) ifTrue:[

trait := e.

selector := ('get' , trait printString , suffix) asSymbol.
sourceCode := self getSourceCodeFor: aSymbol trait: trait selector: selector.
(aComponent allSelectors includes: selector) ifFalse: [
aComponent compile: sourceCode contents classified: self class protocolForComponentAccess
] ifTrue: [
"if the method exist inspect this source code for search any difference between the existing required services and the requested required services"
"the selector must not be a parent"
(aComponent selectors includes: selector) ifTrue: [
method := aComponent >> selector.
sourceMethod := method sourceCode.
sourceMethod ifNotNil: [
sourceMethod ~= sourceCode contents ifTrue: [
"rewrite the method"
aComponent compile: sourceCode contents classified: self class protocolForComponentAccess
].
].
].
].
].
]
MolComponentFactory >> generateComponentAccessorsFor: aSymbol traits: aTraits in: aComponent suffix: suffix [
| selector sourceCode protocol |

(aTraits notNil and: [
aTraits isTrait and: [
aTraits isComponentServices or: [
aTraits isComponentParameters or: [ aTraits isComponentEvents ] ] ] ])
ifFalse: [ ^ self ].

selector := ('get' , aTraits printString , suffix) asSymbol.
protocol := self class protocolForComponentAccess.
sourceCode := self
getSourceCodeFor: aSymbol
trait: aTraits
selector: selector.

self
generateMethod: sourceCode
selector: selector
protocol: protocol
inComponent: aComponent
]

{ #category : #'private - code generation' }
MolComponentFactory >> generateComponentAccessorsFor: aSymbol withList: aListOfTraits in: aComponent suffix: suffix [

aListOfTraits copy do: [ :traits |
self
generateComponentAccessorsFor: aSymbol
traits: traits
in: aComponent
suffix: suffix ]
]

{ #category : #'code generation' }
Expand All @@ -674,6 +676,26 @@ MolComponentFactory >> generateConsumedEventsComponentAccessorsFor: aComponentCl
suffix: 'Subscriber'
]

{ #category : #'private - code generation' }
MolComponentFactory >> generateMethod: aSourceCode selector: aSelector protocol: aProtocol inComponent: aComponent [

| method sourceMethod methodProtocol |
(aComponent allSelectors includes: aSelector)
ifFalse: [
aComponent compile: aSourceCode contents classified: aProtocol ]
ifTrue: [
(aComponent selectors includes: aSelector) ifFalse: [ ^ self ].
"if the method exist inspect this source code for search any difference between the existing required services and the requested required services""the selector must not be a parent"
method := aComponent >> aSelector.
methodProtocol := method protocol ifNil: [ nil ] ifNotNil: [ :p |
"Pharo 11 reflective API support: protocol is directly a ByteString" p class = Protocol ifTrue:[ p name ] ifFalse:[ p ] ].
sourceMethod := method sourceCode.
sourceMethod ifNotNil: [ "if the source code of the method is different than the existing one, recreate it. Same thing for the procotol."
(sourceMethod ~= aSourceCode contents or: [
methodProtocol ~= aProtocol ]) ifTrue: [ "rewrite the method"
aComponent compile: aSourceCode contents classified: aProtocol ] ] ]
]

{ #category : #'code generation' }
MolComponentFactory >> generateProducedEventsComponentAccessorsFor: aComponentClass [

Expand Down
Loading