Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subclass replacement operator #75

Merged
merged 24 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from 7 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
13 changes: 8 additions & 5 deletions src/MuTalk-Model/MTBlockBasedMutantOperator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,27 @@ MTBlockBasedMutantOperator class >> isOriginalOperator [
^ false
]

{ #category : 'testing' }
{ #category : 'private' }
MTBlockBasedMutantOperator >> isAPosibleMutatedNode: aRBMethodNode [

| nodeThatMatches |
nodeThatMatches := aRBMethodNode allChildren detect: self newExpression ifNone: [nil].
^ nodeThatMatches notNil and: [
nodeThatMatches := aRBMethodNode allChildren
detect: self newExpression
ifNone: [ nil ].

^ nodeThatMatches notNil and: [
self is: nodeThatMatches equalTo: aRBMethodNode ]
]

{ #category : 'testing' }
{ #category : 'private' }
MTBlockBasedMutantOperator >> isAPosibleNodeToMutate: aRBMethodNode [

| nodeThatMatches |
nodeThatMatches := aRBMethodNode allChildren
detect: self expressionToReplace
ifNone: [ nil ].

^ nodeThatMatches notNil and: [
^ nodeThatMatches notNil and: [
self is: aRBMethodNode equalTo: nodeThatMatches ]
]

Expand Down
2 changes: 1 addition & 1 deletion src/MuTalk-Model/MTMessageSendToYourselfOperator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Class {
{ #category : 'printing' }
MTMessageSendToYourselfOperator >> description [

^ 'Chnage a message send with #yourself'
^ 'Change a message send with #yourself'
]

{ #category : 'applying' }
Expand Down
39 changes: 25 additions & 14 deletions src/MuTalk-Model/MTMutantOperator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,14 @@ MTMutantOperator >> modifiedSourceFor: aCompiledMethod with: aParseTree number:
]

{ #category : 'private' }
MTMutantOperator >> mutationFor: aCompiledMethod with: aParseTree number: aNumberOfSelector [
MTMutantOperator >> mutationFor: aCompiledMethod with: aParseTree number: aNumberOfSelector storeIn: aCollection [

^ MTMethodMutation
for: aCompiledMethod
using: self
nodeNumber: aNumberOfSelector
ofClass: aCompiledMethod methodClass
aCollection add: (MTMethodMutation
for: aCompiledMethod
using: self
nodeNumber: aNumberOfSelector
ofClass: aCompiledMethod methodClass).
^ aCollection
]

{ #category : 'mutant generation' }
Expand All @@ -162,16 +163,26 @@ MTMutantOperator >> mutationsFor: aCompiledMethod [
]

{ #category : 'mutant generation' }
MTMutantOperator >> mutationsFor: aCompiledMethod with: aParseTree [
MTMutantOperator >> mutationsFor: aCompiledMethod with: aParseTree [

| numberOfMutations |
numberOfMutations := ((aCompiledMethod hasPragmaNamed: #ignoreForMutations) or: [ aCompiledMethod hasPragmaNamed: #ignoreForCoverage ])
ifTrue: [ ^ Array new ]
ifFalse: [ self timesToApplyIn: aCompiledMethod with: aParseTree ].
numberOfMutations := ((aCompiledMethod hasPragmaNamed:
#ignoreForMutations) or: [
aCompiledMethod hasPragmaNamed:
#ignoreForCoverage ])
ifTrue: [ ^ Array new ]
ifFalse: [
self
timesToApplyIn: aCompiledMethod
with: aParseTree ].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh we are going to simplify this in our next pair programming session! ;)

^ (1 to: numberOfMutations)
collect: [:aNumberOfSelector | self
mutationFor: aCompiledMethod
with: aParseTree
number: aNumberOfSelector]
inject: OrderedCollection new
into: [ :collection :aNumberOfSelector |
self
mutationFor: aCompiledMethod
with: aParseTree
number: aNumberOfSelector
storeIn: collection ]
]

{ #category : 'applying' }
Expand Down
41 changes: 41 additions & 0 deletions src/MuTalk-Model/MTParametricMethodMutation.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Class {
#name : 'MTParametricMethodMutation',
#superclass : 'MTMethodMutation',
#instVars : [
'newExpression'
],
#category : 'MuTalk-Model',
#package : 'MuTalk-Model'
}

{ #category : 'instance creation' }
MTParametricMethodMutation class >> for: aMethod using: anOperatorApplied nodeNumber: aNodeNumber ofClass: aClass replacingWith: anObject [

^ self new
initializeFor: aMethod
using: anOperatorApplied
nodeNumber: aNodeNumber
ofClass: aClass
replacingWith: anObject;
yourself
]

{ #category : 'initialization' }
MTParametricMethodMutation >> initializeFor: aMethod using: anOperatorApplied nodeNumber: aNodeNumber ofClass: aClass replacingWith: anObject [

super
initializeFor: aMethod
using: anOperatorApplied
nodeNumber: aNodeNumber
ofClass: aClass.
newExpression := anObject
]

{ #category : 'accessing' }
MTParametricMethodMutation >> modifiedSource [

^ operator
modifiedSourceFor: originalMethod
number: nodeNumber
newExpression: newExpression
]
93 changes: 93 additions & 0 deletions src/MuTalk-Model/MTSubclassReplacementOperator.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
Class {
#name : 'MTSubclassReplacementOperator',
#superclass : 'MTBlockBasedMutantOperator',
#instVars : [
'classesToReplace'
],
#category : 'MuTalk-Model-Operators',
#package : 'MuTalk-Model',
#tag : 'Operators'
}

{ #category : 'printing' }
MTSubclassReplacementOperator >> description [

^ 'Replace a class reference by a reference to one of its subclasses'
]

{ #category : 'applying' }
MTSubclassReplacementOperator >> expressionToReplace [

^ [ :aNode |
aNode isVariable and: [
(self class environment includesKey: aNode name) and: [
| referencedClass shouldReplace |
referencedClass := self class environment at: aNode name.
shouldReplace := referencedClass isClass and: [
referencedClass subclasses notEmpty ].
shouldReplace ifTrue: [ classesToReplace add: referencedClass ].
shouldReplace ] ] ]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want that we discuss how to fix this. I know you just followed how others were done, but I don't like blocks used like this!

]

{ #category : 'initialization' }
MTSubclassReplacementOperator >> initialize [

super initialize.
classesToReplace := OrderedCollection new
]

{ #category : 'private' }
MTSubclassReplacementOperator >> modifiedSourceFor: aCompiledMethod number: aNumber newExpression: anExpression [

^ self
modifiedSourceFor: aCompiledMethod
with: aCompiledMethod parseTree
number: aNumber
newExpression: anExpression
]

{ #category : 'private' }
MTSubclassReplacementOperator >> modifiedSourceFor: aCompiledMethod with: aParseTree number: aNumber newExpression: anExpression [

| parser allNodes |
parser := aParseTree copy.
allNodes := parser allChildren select: self expressionToReplace.
allNodes size >= aNumber ifTrue: [
| oldNode newNode |
oldNode := allNodes at: aNumber.
newNode := anExpression value: oldNode.
oldNode replaceWith: newNode ].
^ parser formattedCode
]

{ #category : 'private' }
MTSubclassReplacementOperator >> mutationFor: aCompiledMethod with: aParseTree number: aNumberOfSelector storeIn: aCollection [

| classToReplace |
classToReplace := classesToReplace at: aNumberOfSelector.
aCollection addAll:
((1 to: classToReplace subclasses size) collect: [ :index |
| newExpression |
newExpression := self
newExpressionForClass: aNumberOfSelector
andSubclass: index.
MTParametricMethodMutation
for: aCompiledMethod
using: self
nodeNumber: aNumberOfSelector
ofClass: aCompiledMethod methodClass
replacingWith: newExpression ]).
^ aCollection
]

{ #category : 'applying' }
MTSubclassReplacementOperator >> newExpressionForClass: classIndex andSubclass: subclassIndex [

^ [ :anOldNode |
| nodeCopy |
nodeCopy := anOldNode copy.
nodeCopy name:
((classesToReplace at: classIndex) subclasses at: subclassIndex)
name.
nodeCopy ]
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Class {
#name : 'MTAuxiliarClassForSubclassReplacementOperator',
#superclass : 'Object',
#category : 'MuTalk-TestResources',
#package : 'MuTalk-TestResources'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Class {
#name : 'MTAuxiliarClassForSubclassReplacementWithManySubclasses',
#superclass : 'Object',
#category : 'MuTalk-TestResources',
#package : 'MuTalk-TestResources'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Class {
#name : 'MTAuxiliarSubclass1ForSubclassReplacementWithManySubclasses',
#superclass : 'MTAuxiliarClassForSubclassReplacementWithManySubclasses',
#category : 'MuTalk-TestResources',
#package : 'MuTalk-TestResources'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Class {
#name : 'MTAuxiliarSubclass2ForSubclassReplacementWithManySubclasses',
#superclass : 'MTAuxiliarClassForSubclassReplacementWithManySubclasses',
#category : 'MuTalk-TestResources',
#package : 'MuTalk-TestResources'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Class {
#name : 'MTAuxiliarSubclass3ForSubclassReplacementWithManySubclasses',
#superclass : 'MTAuxiliarClassForSubclassReplacementWithManySubclasses',
#category : 'MuTalk-TestResources',
#package : 'MuTalk-TestResources'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Class {
#name : 'MTAuxiliarSubclassForSubclassReplacementOperator',
#superclass : 'MTAuxiliarClassForSubclassReplacementOperator',
#category : 'MuTalk-TestResources',
#package : 'MuTalk-TestResources'
}
Loading
Loading