-
-
Notifications
You must be signed in to change notification settings - Fork 434
Fix #19936: Forbid removing temporary variables with usages unless shadowed #19937
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
base: Pharo15
Are you sure you want to change the base?
Changes from 8 commits
a12fd64
4fa377d
c04ab52
d58ccd5
7e49f8a
ad964b2
82b9ac0
2171aac
15d2571
730eafb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,25 +50,56 @@ RBRemoveTemporaryVariableTransformation class >> variable: aString inMethod: aSe | |
| yourself | ||
| ] | ||
|
|
||
| { #category : 'preconditions' } | ||
| { #category : #preconditions } | ||
| RBRemoveTemporaryVariableTransformation >> applicabilityPreconditions [ | ||
|
|
||
| ^ { | ||
| self classExist. | ||
| (ReDefinesSelectorsCondition new definesSelectors: (Array with: selector) in: self definingClass). | ||
| (RBCondition | ||
| withBlock: [ | ||
| self definingMethod allTemporaryVariables includes: variableName ] | ||
| errorString: 'Method named ' , selector | ||
| , ' does not define a temporary variable named ' , variableName). | ||
| (RBCondition | ||
| withBlock: [ | ||
| (self definingMethod allArgumentVariables includes: | ||
| variableName) not ] | ||
| errorString: 'Variable named ' , variableName | ||
| , ' cannot be removed because it is an argument in this method') } | ||
| ^ { | ||
| self classExist. | ||
| (ReDefinesSelectorsCondition new definesSelectors: { selector } in: self definingClass). | ||
| (RBCondition | ||
| withBlock: [ | ||
| self definingMethod allTemporaryVariables includes: variableName ] | ||
| errorString: 'Method named ' , selector | ||
| , ' does not define a temporary variable named ' , variableName). | ||
| (RBCondition | ||
| withBlock: [ | ||
| (self definingMethod allArgumentVariables includes: variableName) not ] | ||
| errorString: 'Variable named ' , variableName | ||
| , ' cannot be removed because it is an argument in this method'). | ||
| (RBCondition | ||
| withBlock: [ | ||
| self hasUsagesInScope not or: [ | ||
| self definingClass definesInstanceVariable: variableName ] ] | ||
| errorString: 'Variable named ' , variableName | ||
| , ' cannot be removed because it is used in the method') } | ||
| ] | ||
|
|
||
| { #category : #'private - accessing' } | ||
| RBRemoveTemporaryVariableTransformation >> definingSequenceNode [ | ||
|
|
||
| ^ (self definingMethod allChildren select: [ :each | each isSequence ]) | ||
| detect: [ :each | each exactNodeDefines: variableName ] | ||
| ifNone: [ nil ] | ||
| ] | ||
|
|
||
| { #category : #'private - testing' } | ||
| RBRemoveTemporaryVariableTransformation >> hasUsagesInScope [ | ||
|
PrasannaBhavan2005 marked this conversation as resolved.
Outdated
|
||
|
|
||
| | definingSeq | | ||
| definingSeq := self definingSequenceNode. | ||
| definingSeq ifNil: [ ^ false ]. | ||
|
|
||
| ^ definingSeq statements anySatisfy: [ :stmt | | ||
| stmt allChildren anySatisfy: [ :node | | ||
| node isVariable and: [ | ||
| node name = variableName and: [ | ||
| | innerSeq | | ||
| innerSeq := node parent. | ||
| [ innerSeq isNotNil and: [ innerSeq isSequence not ] ] | ||
| whileTrue: [ innerSeq := innerSeq parent ]. | ||
| innerSeq == definingSeq or: [ | ||
| innerSeq isNil or: [ (innerSeq exactNodeDefines: variableName) not ] ] ] ] ] ] | ||
| ] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be possible to write some tests for this new code as well? In the future we might want to move this code to RB metamodel, so having tests is really useful in that case.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add these test cases:
|
||
| { #category : 'scripting api - conditions' } | ||
| RBRemoveTemporaryVariableTransformation >> checkPreconditions [ | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer for this to be standalone precondition, but it's good like this as well, it's important we are fixing these.
I'm now thinking that this delegation to instnace variable is behavior-preserving precondition, but this is a tricky scenario where applicability preconditions will fail (variable has usages) and then behavior can still be fixed. I think we didn't have this scenario so far. So nothing to fix now, rather I have to re-think some scenarios and how to support this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the review @balsa-sarenac!
I've applied your suggestion for
ReDefinesSelectorsCondition, happy to hear that the precondition logic helps address the issue, let me know if any further changes needed