Balša Šarenac, Stéphane Ducasse, Guillermo Polito and Gordana Rakić
An Analysis of Inline Method
Refactoring
1
Evref
fervE
Introduction
‣ Refactoring
‣ Composition
‣ Inline Method
‣ Source method
‣ Inline method
2
Goals
‣ Enable users to de
fi
ne their own refactorings
‣ Redesign existing refactorings into modular de
fi
nitions
3
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 ]) }
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
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
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
Analysis
Canonicalization
8
Before canonization After canonization
ifNotEmpty:
Analysis
Cascades
• Right now handled using ifs
• Only supports inlining the last message from the cascade
• Makes the code very hard to change
9
New architecture
‣ Prepare for execution
‣ Precondition checking
‣ Transformation
10
11
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
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
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
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
16
Comparison to Extract Method?
17
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
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
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

An Analysis of Inline Method Refactoring

  • 1.
    Balša Šarenac, StéphaneDucasse, Guillermo Polito and Gordana Rakić An Analysis of Inline Method Refactoring 1 Evref fervE
  • 2.
    Introduction ‣ Refactoring ‣ Composition ‣Inline Method ‣ Source method ‣ Inline method 2
  • 3.
    Goals ‣ Enable usersto 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 ofthe 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 andcons 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 theinline 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
  • 8.
  • 9.
    Analysis Cascades • Right nowhandled using ifs • Only supports inlining the last message from the cascade • Makes the code very hard to change 9
  • 10.
    New architecture ‣ Preparefor execution ‣ Precondition checking ‣ Transformation 10
  • 11.
  • 12.
    Current flow ‣ InlineMethod 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 makethis 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 makethis 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 makethis 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
  • 16.
  • 17.
  • 18.
    What do wedo 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 pragmacomposite ‣ 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 whenimplementing the Inline Method in Pharo • Leverage Decorator and Specialization to simplify Inline Method • Inline Method with Pragma domain speci fi c refactoring 20