Skip to content

Commit

Permalink
Separate attributes set with setters and constructors
Browse files Browse the repository at this point in the history
+ Robust parameter-attribute mapper
  • Loading branch information
Gabriel-Darbord committed Jun 5, 2024
1 parent dd3b1ab commit 79608c1
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 29 deletions.
21 changes: 8 additions & 13 deletions src/Famix-Value-Exporter/FASTJavaVariableExpression.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,17 @@ FASTJavaVariableExpression >> accessedAttributesOf: aFamixJavaClass [
self javaAssignmentExpressionOwner ifNotNil: [ :assign |
| attributeName |
attributeName := assign variable accessedAttributeName.
^ (aFamixJavaClass attributes
^ { (aFamixJavaClass attributes
detect: [ :attribute | attribute name = attributeName ]
ifNone: [
aFamixJavaClass inheritedAttributes detect: [ :attribute |
attribute name = attributeName ] ]) asArray ].
attribute name = attributeName ] ]) } ].
argumentOwner ifNotNil: [ :invoc | "if used as argument, reiterate the search on the corresponding parameter of the invoked method"
| method |
^ (((method := invoc famixInvocation anyCandidate) parameters
ifNotEmpty: [ method ]
ifEmpty: [ "TODO: investigate why we need to do this"
| methods |
(methods := method invokingMethods) size = 1 ifFalse: [
self error: 'Only one method expected' ].
methods anyOne ]) parameters at:
(invoc arguments indexOf: self)) allAccessedAttributesOf:
aFamixJavaClass ].
self error: 'TODO: what else can be using the parameter?'.
^ nil
^ (method := invoc famixInvocation anyCandidate) isStub
ifTrue: [ "ignore stubs" { } ]
ifFalse: [
(method parameters at: (invoc arguments indexOf: self))
allAccessedAttributesOf: aFamixJavaClass ] ].
self error: 'TODO: what else can be using the parameter?'
]
4 changes: 2 additions & 2 deletions src/Famix-Value-Exporter/FamixTMethod.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ FamixTMethod >> mapConstructorParametersToAttributes [
access accessedAttributesOf: parentType ])
ifNotEmpty: [ :attributes |
attributes size = 1
ifTrue: [ attributes at: 1 ]
ifTrue: [ attributes anyOne ]
ifFalse: [ self error: 'Expected only one attribute.' ] ]
ifEmpty: [ nil ] ]
ifEmpty: [ "parameter is not mapped to an attribute" nil ] ]
]
39 changes: 31 additions & 8 deletions src/Famix-Value-Exporter/FamixValue2FASTJavaVisitor.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ Class {
'markedForReflection',
'constructorCache',
'staticAttributesCache',
'objectExportStrategy'
'objectExportStrategy',
'setterCache'
],
#category : #'Famix-Value-Exporter'
}
Expand All @@ -29,21 +30,21 @@ FamixValue2FASTJavaVisitor >> addAttributesFrom: object asArgumentsTo: newExpres
ifAbsentPut: [ constructor mapConstructorParametersToAttributes ])
withIndexDo: [ :paramAttribute :index |
newExpression addArgument: (paramAttribute
ifNil: [
ifNil: [ "constructor parameter is not mapped to an attribute"
(constructor parameters at: index) declaredType
asFASTJavaDefaultValueOn: self model ]
ifNotNil: [
object value
detect: [ :objAttribute |
objAttribute attribute == paramAttribute ]
ifOne: [ :objAttribute |
detect: [ :objAttribute | "find the matching value attribute"
objAttribute attribute == paramAttribute ]
ifFound: [ :objAttribute |
self makeVariableExpression: objAttribute value ]
ifNone: [ "the object does not have the attribute set"
paramAttribute declaredType asFASTJavaDefaultValueOn:
self model ] ]) ]
]

{ #category : #initialization }
{ #category : #accessing }
FamixValue2FASTJavaVisitor >> builder [

^ builder ifNil: [ builder := FASTJavaBuilder new model: self model ]
Expand All @@ -64,7 +65,28 @@ FamixValue2FASTJavaVisitor >> constructObject: object [
addAttributesFrom: object
asArgumentsTo: varDecl declarators first expression
usingConstructor: constructor ] ]
ifTrue: [ "use reflection" self halt ]
ifTrue: [ "use reflection" self shouldBeImplemented ]
]

{ #category : #accessing }
FamixValue2FASTJavaVisitor >> filterAttributesToSet: attributes for: object [
"No need to set attributes that are set in the constructor."

^ (setterCache at: object type ifAbsentPut: [
| famixAttributes |
famixAttributes := attributes collect: [ :attribute |
attribute attribute ].
constructorCache
at: object type
ifPresent: [ :constructor |
constructorCache
at: constructor
ifPresent: [ :constructorAttributes |
famixAttributes difference: constructorAttributes ]
ifAbsent: [ famixAttributes ] ]
ifAbsent: [ famixAttributes ] ]) ifNotEmpty: [ :famixAttributes |
attributes select: [ :attribute |
famixAttributes includes: attribute attribute ] ]
]

{ #category : #private }
Expand Down Expand Up @@ -114,6 +136,7 @@ FamixValue2FASTJavaVisitor >> findStaticAttributeMatching: object [
FamixValue2FASTJavaVisitor >> initialize [

constructorCache := IdentityDictionary new.
setterCache := IdentityDictionary new.
staticAttributesCache := IdentityDictionary new
]

Expand Down Expand Up @@ -284,7 +307,7 @@ FamixValue2FASTJavaVisitor >> makeVarDeclStatement: value [
yourself
]

{ #category : #visiting }
{ #category : #ast }
FamixValue2FASTJavaVisitor >> makeVarDeclStatement: object usingStaticAttribute: attribute [
"Declare a variable for object, initialized with the value of the given static attribute.
For example: MyClass myClass = MyClass.MY_STATIC_ATTRIBUTE;"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ FamixValueHelperObjectExportStrategy >> buildMethodFor: object withParametersFor
on: visitor.
"make the method body: instantiate object, set attributes and return it"
visitor constructObject: object.
self makeSetterInvocationsFor: attributes on: visitor.
self
makeSetterInvocationsFor:
(visitor filterAttributesToSet: attributes for: object)
on: visitor.
visitor statementBlock addStatement:
(model newReturnStatement expression:
(model newVariableExpression name: (visitor varNameFor: object))).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ Class {
{ #category : #exporting }
FamixValueInlineObjectExportStrategy >> export: object on: visitor [

self flag: #TODO. "redo object visit, we need to have attributes ready when calling the constructor.
We need to know if an attribute has been set using the constructor or if it will be set using a setter!"
visitor constructObject: object.
object relevantAttributes do: [ :attribute |
visitor visitObjectAttribute: attribute ]
(visitor filterAttributesToSet: object relevantAttributes for: object)
do: [ :attribute | visitor visitObjectAttribute: attribute ]
]
2 changes: 1 addition & 1 deletion src/Famix-Value-Importer/FamixEntityFinder.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ FamixEntityFinder >> findMethodWithSignature: signature in: class [
| candidates |
class methods
detect: [ :method | method signature = signature ]
ifOne: [ :method | ^ method ].
ifFound: [ :method | ^ method ].
"signature might not exactly match due to representation format"
candidates := self
findMethodsWithName:
Expand Down

0 comments on commit 79608c1

Please sign in to comment.