Talk from IWST 2025: An Analysis of Inline Method Refactoring
PDF: https://archive.esug.org/ESUG2025/iwst-day1/iwst-106-sare-inline-method-refactoring.pdf
3. Goals
‣ Enable users to de
fi
ne their own refactorings
‣ Redesign existing refactorings into modular de
fi
nitions
3
4. Inline method example
4
breakingChangePreconditions
^ { (RBCondition withBlock: [
self
fi
ndReceiverNode.
true ]) }
breakingChangePreconditions
^ { (RBCondition withBlock: [
| receiverNodes |
receiverNodes := statementNodes collect: [ :each | each receiver ].
receiverNodes asSet size = 1 ifFalse: [
self refactoringError: 'All statements must have the same receiver' ].
(receiverNodes
fi
rst isLiteralNode or: [ receiverNodes
fi
rst isVariable ]) ifFalse: [
self refactoringWarning: 'The receiver is an expression. Proceed with caution' ].
true ]) }
5. Contributions
‣ Analysis of the existing Inline Method refactoring monolithic implementation.
‣ Reuse and extension of the Inline Method refactoring modular logic to de
fi
ne
domain-speci
fi
c refactoring:
‣ Inline Method with Pragma refactoring for Slang (virtual machine generator).
5
6. Legacy implementation
Pros and cons of legacy implementation
‣ Pros:
‣ Mostly correct implementation
‣ Correct precondition logic
‣ Cons:
‣ Mixed calculations, precondition
checking and transformation setup
logic
‣ Mixed transformation logic and user
interaction
‣ Monolithic implementation
6
7. Analysis
Canonicalization
‣ Transforming the inline method’s source code into a state that is inlinable.
‣ Adding a return if it is not already explicitly de
fi
ned,
‣ Transforming guard clauses into if/else blocks (for example, ifTrue:ifFalse: in
the case of Pharo),
‣ Transform ifTrue: and ifFalse: into ifTrue:ifFalse:,
‣ Removing non-local returns.
7
12. Current flow
‣ Inline Method refactoring:
1. Check preconditions
2. Canonize the inline method,
3. Handle cascades and returns (+ more canonization),
4. Replace argument variables with values,
5. Substitute the message send with the inline method,
6. Remove dead code: empty and immediate blocks.
12
Preprocessing
Preconditions
Transformations
13. Can we make this composite?
‣ Inline Method refactoring:
1. Canonize the inline method,
2. Check preconditions
3. Handle cascades and returns
4. Rename con
fl
icting temporaries
5. Replace argument variables with values,
6. Substitute the message send with the inline method,
7. Remove dead code, empty and immediate blocks.
13
Preprocessing
Preconditions
Transformations
Specialization
14. Can we make this composite?
‣ Inline Method refactoring:
1. Canonize the method to be inlined,
2. Check preconditions
3. Rename con
fl
icting temporaries
4. Replace argument variables with values,
5. Substitute the message send with the inline method,
6. Remove dead code, empty and immediate blocks.
14
Preprocessing
Preconditions
Transformations
Transformation - Preprocessing
Transforming
Cleanup
15. Can we make this composite?
‣ Inline Method refactoring:
1. Canonize the method to be inlined (from transformation),
2. Check preconditions,
1. Inlining overridden methods,
2. Inlining bigger methods that will add statements before the target
message.
3. Inlining methods that send overridden super messages
3. Inline method transformation.
15
Preprocessing
Preconditions
Transformations
18. What do we do with method with Pragma
18
ExampleClass >> m
<var: ‘a’ declareC: ‘int’>
| a |
a := 1 + 3.
^ a * self calculation
ExampleClass >> m
| a |
a := self exampleMethod.
^ a * self calculation
ExampleClass >> exampleMethod
<var: ‘c’ declareC: ‘int’>
| c |
c := 1 + 3.
^ c
19. Inline with pragma composite
‣ Inline Method with pragma refactoring:
1. Canonize the method to be inlined,
2. Check preconditions,
3. Handle pragmas,
4. Inline method transformation.
19
Preprocessing
Preconditions
Transformations
20. Conclusion
• Challenges when implementing the Inline Method in Pharo
• Leverage Decorator and Specialization to simplify Inline Method
• Inline Method with Pragma domain speci
fi
c refactoring
20