Skip to content

Commit

Permalink
add support for Closure
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiovandewaeter committed Jul 10, 2024
1 parent 6fe4373 commit e3f6906
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ FamixValueOfType >> referenceCount [

^ attributeInObjects size + elementInCollections size
+ keyInDictionaries size + valueInDictionaries size
+ variableInClosures size
]

{ #category : #'*Famix-Value-Entities-Extensions' }
Expand Down
6 changes: 6 additions & 0 deletions src/Famix-Value-Entities/FamixValueOfClosureVariable.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,9 @@ FamixValueOfClosureVariable >> value: anObject [
<generated>
value := anObject
]

{ #category : #generate }
FamixValueOfClosureVariable >> varName [

^ name
]
6 changes: 6 additions & 0 deletions src/Famix-Value-Exporter/FamixStMethod.extension.st
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
Extension { #name : #FamixStMethod }

{ #category : #'*Famix-Value-Exporter' }
FamixStMethod >> isSetterLax [

^ self isSetter
]

{ #category : #'*Famix-Value-Exporter' }
FamixStMethod >> varName [

Expand Down
33 changes: 16 additions & 17 deletions src/Famix-Value-Exporter/FamixValue2PharoVisitor.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ FamixValue2PharoVisitor >> ensureVisited: value [
ifPresent: [ :name | RBVariableNode named: name ]
ifAbsent: [
| name node |
name := self varNameFor: value.
value isOfPrimitiveType ifFalse: [
self varNameDict at: value put: (name := self varNameFor: value) ].
self varNameDict at: value put: name ].
node := value accept: self.
value isReferencedInLoop
ifTrue: [
Expand Down Expand Up @@ -70,20 +71,17 @@ FamixValue2PharoVisitor >> visitClassReference: aFamixValueOfClassReference [
{ #category : #visiting }
FamixValue2PharoVisitor >> visitClosure: object [

| objectNode attributeNodes |
object value detect: [ :a | a attribute isNil ].
objectNode := RBMessageNode
receiver: (RBVariableNode named: object type name)
selector: #new.
attributeNodes := (object value
collect: [ :attribute |
self visitObjectAttribute: attribute ]
as: OrderedCollection) reject: #isNil.
attributeNodes ifEmpty: [ ^ objectNode ].
attributeNodes first receiver: objectNode.
attributeNodes add:
(RBMessageNode receiver: RBVariableNode new selector: #yourself).
^ RBCascadeNode messages: attributeNodes
object variables do: [ :var |
| visitedVar |
visitedVar := self ensureVisited: var value.
statementBlock addNodeFirst: (RBAssignmentNode
variable: (RBVariableNode named: var name)
value: visitedVar) ].
^ [ RBParser parseExpression: object sourceCode ]
on: SyntaxErrorNotification
do: [ :error | "TODO: fix reflective opperation on block when metalink is installed"
Transcript crShow: error description.
error pass ]
]

{ #category : #visiting }
Expand All @@ -95,8 +93,9 @@ FamixValue2PharoVisitor >> visitCollection: collection [
| newNode |
newNode := self ensureVisited: element value.
(element value isReferencedInLoop and: [
newNode isVariable not ])
ifTrue: [ newNode addParenthesisToVariable]
newNode isVariable not and: [
newNode value isLiteralNode not ] ])
ifTrue: [ newNode addParenthesisToVariable ]
ifFalse: [ newNode ] ]).
^ collection type name = 'Array'
ifTrue: [ collectionNode ]
Expand Down
39 changes: 34 additions & 5 deletions src/Famix-Value-Importer/FamixValuePharoJacksonImporter.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ Class {
'typeKey',
'idKey',
'refKey',
'specialTypes'
'specialTypes',
'closureSources'
],
#category : #'Famix-Value-Importer'
}
Expand Down Expand Up @@ -87,16 +88,31 @@ FamixValuePharoJacksonImporter >> importClassReference: rawValue of: type [
{ #category : #importing }
FamixValuePharoJacksonImporter >> importClosure: value of: type [

self flag: #TODO. "handle FullBlockClosure, add FamixValueOfClosure entity with `variables` relation to FamixValueOfType"
^ self model newOfPrimitiveType
value: nil;
type: type
| closure compiledBlock source |
compiledBlock := value at: 'compiledBlock'.
source := compiledBlock
at: '@ref'
ifPresent: [ :id | closureSources at: id ]
ifAbsent: [
closureSources
at: (self getObjectIdentity: compiledBlock)
put: (compiledBlock at: 'source') ].
closure := self model newOfClosure
type: type;
sourceCode: source.
value at: 'vars' ifPresent: [ :vars |
vars associationsDo: [ :assoc |
closure addVariable: (self model newOfClosureVariable
name: assoc key;
value: (self importValue: assoc value)) ] ].
^ closure
]

{ #category : #importing }
FamixValuePharoJacksonImporter >> importCollection: rawValue of: type [

| collection |
type name = 'Array2D' ifTrue: [ self halt ].
collection := self model newOfCollection type: type.
objectDict at: (self getObjectIdentity: rawValue) put: collection.
(rawValue at: '@') do: [ :rawElement |
Expand Down Expand Up @@ -141,6 +157,14 @@ FamixValuePharoJacksonImporter >> importValue: rawValue [
^ rawValue asPharoJacksonValueOn: self
]

{ #category : #initialization }
FamixValuePharoJacksonImporter >> initialize [

super initialize.

closureSources := Dictionary new
]

{ #category : #importing }
FamixValuePharoJacksonImporter >> newReader [

Expand Down Expand Up @@ -184,6 +208,11 @@ FamixValuePharoJacksonImporter >> specialTypes [
specialTypes
at: 'Set'
put: [ :value :type | self importCollection: value of: type ].
specialTypes
at: 'ConstantBlockClosure'
put: [ :value :type | self importClosure: value of: type ]. specialTypes
at: 'CleanBlockClosure'
put: [ :value :type | self importClosure: value of: type ].
specialTypes
at: 'FullBlockClosure'
put: [ :value :type | self importClosure: value of: type ].
Expand Down

0 comments on commit e3f6906

Please sign in to comment.