diff --git a/src/Famix-MetamodelBuilder-Core/FmxMBClass.class.st b/src/Famix-MetamodelBuilder-Core/FmxMBClass.class.st index 8b629cff..ef13293f 100644 --- a/src/Famix-MetamodelBuilder-Core/FmxMBClass.class.st +++ b/src/Famix-MetamodelBuilder-Core/FmxMBClass.class.st @@ -3,7 +3,8 @@ Class { #superclass : #FmxMBBehavior, #instVars : [ 'classGeneralization', - 'isAbstractClass' + 'isAbstractClass', + 'propertiesForEqualityCheck' ], #category : #'Famix-MetamodelBuilder-Core-Implementation' } @@ -80,7 +81,70 @@ FmxMBClass >> generate [ self generatePrecedenceInTraitComposition: aClass. self generateNavigationGroupsFor: aClass. - self generateAddToCollectionFor: aClass + self generateAddToCollectionFor: aClass. + + self generateEqualsMethodFor: aClass. + self generateHashMethodFor: aClass. +] + +{ #category : #'generating-methods' } +FmxMBClass >> generateEqualsMethodFor: aClass [ + + propertiesForEqualityCheck ifNotNil: [ + | variableName | + variableName := 'a' , aClass name. + self builder environment + compile: (String streamContents: [ :stream | + stream << '= '. + stream << variableName. + stream << ' + + + ^ '. + stream + << variableName; + << ' '; + << propertiesForEqualityCheck first; + << ' = self '; + << propertiesForEqualityCheck first. + propertiesForEqualityCheck size > 1 ifTrue: [ + 2 to: propertiesForEqualityCheck size do: [ :idx | + stream << ' and: [ '. + stream + << variableName; + << ' '; + << (propertiesForEqualityCheck at: idx); + << ' = self '; + << (propertiesForEqualityCheck at: idx) ]. + 2 to: propertiesForEqualityCheck size do: [ :idx | + stream << '] ' ] ] ]) + in: aClass instanceSide + classified: #comparing ] +] + +{ #category : #'generating-methods' } +FmxMBClass >> generateHashMethodFor: aClass [ + + propertiesForEqualityCheck ifNotNil: [ + self builder environment + compile: (String streamContents: [ :stream | + stream << 'hash'. + stream << ' + + + ^ '. + stream + << 'self '; + << propertiesForEqualityCheck first; + << ' hash '. + propertiesForEqualityCheck size > 1 ifTrue: [ + 2 to: propertiesForEqualityCheck size do: [ :idx | + stream + << 'bitXor: self '; + << (propertiesForEqualityCheck at: idx); + << ' hash ' ] ] ]) + in: aClass instanceSide + classified: #comparing ] ] { #category : #generating } @@ -183,3 +247,9 @@ FmxMBClass >> traitsFromRelations [ ^ (self relations collect: [ :each | each side trait ] thenSelect: #isNotNil) asSet ] + +{ #category : #generalization } +FmxMBClass >> withEqualityCheckOn: aCollectionOfPropertySymbol [ + + propertiesForEqualityCheck := aCollectionOfPropertySymbol +] diff --git a/src/Famix-Test4-Entities/FamixTest4Book.class.st b/src/Famix-Test4-Entities/FamixTest4Book.class.st index 056b5e3c..08e29686 100644 --- a/src/Famix-Test4-Entities/FamixTest4Book.class.st +++ b/src/Famix-Test4-Entities/FamixTest4Book.class.st @@ -8,12 +8,19 @@ | `person` | `FamixTest4Book` | `books` | `FamixTest4Person` | | +## Properties +====================== + +| Name | Type | Default value | Comment | +|---| +| `id` | `Number` | nil | | " Class { #name : #FamixTest4Book, #superclass : #FamixTest4Entity, #instVars : [ + '#id => FMProperty', '#person => FMOne type: #FamixTest4Person opposite: #books' ], #category : #'Famix-Test4-Entities-Entities' @@ -28,6 +35,34 @@ FamixTest4Book class >> annotation [ ^ self ] +{ #category : #comparing } +FamixTest4Book >> = aFamixTest4Book [ + + + ^ aFamixTest4Book id = self id +] + +{ #category : #comparing } +FamixTest4Book >> hash [ + + + ^ self id hash +] + +{ #category : #accessing } +FamixTest4Book >> id [ + + + + ^ id +] + +{ #category : #accessing } +FamixTest4Book >> id: anObject [ + + id := anObject +] + { #category : #accessing } FamixTest4Book >> person [ "Relation named: #person type: #FamixTest4Person opposite: #books" diff --git a/src/Famix-Test4-Entities/FamixTest4Person.class.st b/src/Famix-Test4-Entities/FamixTest4Person.class.st index 8c838d3b..d212e06e 100644 --- a/src/Famix-Test4-Entities/FamixTest4Person.class.st +++ b/src/Famix-Test4-Entities/FamixTest4Person.class.st @@ -8,12 +8,23 @@ | `books` | `FamixTest4Person` | `person` | `FamixTest4Book` | | +## Properties +====================== + +| Name | Type | Default value | Comment | +|---| +| `age` | `Number` | nil | | +| `firstName` | `String` | nil | | +| `lastName` | `String` | nil | | " Class { #name : #FamixTest4Person, #superclass : #FamixTest4Entity, #instVars : [ + '#firstName => FMProperty', + '#lastName => FMProperty', + '#age => FMProperty', '#books => FMMany type: #FamixTest4Book opposite: #person' ], #category : #'Famix-Test4-Entities-Entities' @@ -36,12 +47,33 @@ FamixTest4Person class >> isAbstract [ ^ self == FamixTest4Person ] +{ #category : #comparing } +FamixTest4Person >> = aFamixTest4Person [ + + + ^ aFamixTest4Person firstName = self firstName and: [ aFamixTest4Person lastName = self lastName and: [ aFamixTest4Person age = self age] ] +] + { #category : #adding } FamixTest4Person >> addBook: anObject [ ^ self books add: anObject ] +{ #category : #accessing } +FamixTest4Person >> age [ + + + + ^ age +] + +{ #category : #accessing } +FamixTest4Person >> age: anObject [ + + age := anObject +] + { #category : #accessing } FamixTest4Person >> books [ "Relation named: #books type: #FamixTest4Book opposite: #person" @@ -64,3 +96,38 @@ FamixTest4Person >> booksGroup [ ^ MooseSpecializedGroup withAll: self books asSet ] + +{ #category : #accessing } +FamixTest4Person >> firstName [ + + + + ^ firstName +] + +{ #category : #accessing } +FamixTest4Person >> firstName: anObject [ + + firstName := anObject +] + +{ #category : #comparing } +FamixTest4Person >> hash [ + + + ^ self firstName hash bitXor: self lastName hash bitXor: self age hash +] + +{ #category : #accessing } +FamixTest4Person >> lastName [ + + + + ^ lastName +] + +{ #category : #accessing } +FamixTest4Person >> lastName: anObject [ + + lastName := anObject +] diff --git a/src/Famix-Test4-Entities/FamixTest4School.class.st b/src/Famix-Test4-Entities/FamixTest4School.class.st index 78201eb2..a2bd008f 100644 --- a/src/Famix-Test4-Entities/FamixTest4School.class.st +++ b/src/Famix-Test4-Entities/FamixTest4School.class.st @@ -18,9 +18,9 @@ Class { #superclass : #FamixTest4Entity, #instVars : [ '#principal => FMOne type: #FamixTest4Principal opposite: #school', - '#rooms => FMMany type: #FamixTest4Room opposite: #school', '#students => FMMany type: #FamixTest4Student opposite: #school', - '#teachers => FMMany type: #FamixTest4Teacher opposite: #school' + '#teachers => FMMany type: #FamixTest4Teacher opposite: #school', + '#rooms => FMMany type: #FamixTest4Room opposite: #school' ], #category : #'Famix-Test4-Entities-Entities' } diff --git a/src/Famix-Test4-Entities/FamixTest4TEntityCreator.trait.st b/src/Famix-Test4-Entities/FamixTest4TEntityCreator.trait.st index 48ebb316..a1250005 100644 --- a/src/Famix-Test4-Entities/FamixTest4TEntityCreator.trait.st +++ b/src/Famix-Test4-Entities/FamixTest4TEntityCreator.trait.st @@ -6,7 +6,7 @@ It provides an API for creating entities and adding them to the model. " Trait { #name : #FamixTest4TEntityCreator, - #category : #'Famix-Test4-Entities-Traits' + #category : #'Famix-Test4-Entities-Model' } { #category : #meta } diff --git a/src/Famix-Test4-Tests/FamixTest4Test.class.st b/src/Famix-Test4-Tests/FamixTest4Test.class.st index 40a1f62a..e7f44246 100644 --- a/src/Famix-Test4-Tests/FamixTest4Test.class.st +++ b/src/Famix-Test4-Tests/FamixTest4Test.class.st @@ -33,9 +33,13 @@ FamixTest4Test >> setUp [ student1 := FamixTest4Student new. student1 := FamixTest4Student new. student2 := FamixTest4Student new. + student2 firstName: 'firstname'. + student2 lastName: 'lastName'. student3 := FamixTest4Student new. teacher1 := FamixTest4Teacher new. + teacher1 firstName: 'John'. teacher2 := FamixTest4Teacher new. + teacher2 firstName: 'Bob'. book1 := FamixTest4Book new. book2 := FamixTest4Book new. @@ -58,6 +62,18 @@ FamixTest4Test >> testAbstractClasses [ self assert: FamixTest4Person isAbstract ] +{ #category : #tests } +FamixTest4Test >> testEqualityStudent [ + + | sameStudent | + "A copy of student2 to test same" + sameStudent := FamixTest4Student new. + sameStudent firstName: 'firstname'. + sameStudent lastName: 'lastName'. + + self assert: student2 equals: sameStudent +] + { #category : #tests } FamixTest4Test >> testRelations [ self assert: (principal books includes: book2). diff --git a/src/Famix-TestGenerators/FamixTest4Generator.class.st b/src/Famix-TestGenerators/FamixTest4Generator.class.st index 1e310751..b0cc9647 100644 --- a/src/Famix-TestGenerators/FamixTest4Generator.class.st +++ b/src/Famix-TestGenerators/FamixTest4Generator.class.st @@ -69,9 +69,18 @@ FamixTest4Generator >> defineHierarchy [ { #category : #definition } FamixTest4Generator >> defineProperties [ + super defineProperties. - (builder ensureClassNamed: #Entity) property: #name type: #String + (builder ensureClassNamed: #Entity) property: #name type: #String. + + person property: #firstName type: #String. + person property: #lastName type: #String. + person property: #age type: #Number. + person withEqualityCheckOn: { #firstName. #lastName. #age }. + + book property: #id type: #Number. + book withEqualityCheckOn: { #id } ] { #category : #definition }