-
-
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 all 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 |
|---|---|---|
|
|
@@ -53,20 +53,25 @@ RBRemoveTemporaryVariableTransformation class >> variable: aString inMethod: aSe | |
| { #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 argumentNames includes: variableName) not ] | ||
|
PrasannaBhavan2005 marked this conversation as resolved.
|
||
| 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') } | ||
|
Comment on lines
+69
to
+74
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. I'd prefer for this to be standalone precondition, but it's good like this as well, it's important we are fixing these.
Author
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. thanks for the review @balsa-sarenac! I've applied your suggestion for |
||
| ] | ||
|
|
||
| { #category : 'scripting api - conditions' } | ||
|
|
@@ -83,6 +88,28 @@ RBRemoveTemporaryVariableTransformation >> classExist [ | |
| errorString: 'No such class or trait named ' , className asString | ||
| ] | ||
|
|
||
| { #category : 'private - accessing' } | ||
| RBRemoveTemporaryVariableTransformation >> definingSequenceNode [ | ||
|
|
||
| ^ (self definingMethod allChildren select: [ :each | each isSequence ]) | ||
| detect: [ :each | each exactNodeDefines: variableName ] | ||
| ifNone: [ nil ] | ||
| ] | ||
|
|
||
| { #category : 'private-testing' } | ||
| RBRemoveTemporaryVariableTransformation >> hasUsagesInScope [ | ||
|
|
||
| | definingSequence | | ||
| definingSequence := self definingSequenceNode. | ||
| definingSequence ifNil: [ ^ false ]. | ||
|
|
||
| ^ definingSequence statements anySatisfy: [ :statement | | ||
| statement withAllChildren anySatisfy: [ :node | | ||
| node isVariable | ||
| and: [ node name = variableName | ||
| and: [ (node whichUpNodeDefines: variableName) == definingSequence ] ] ] ] | ||
| ] | ||
|
|
||
| { #category : 'executing' } | ||
| RBRemoveTemporaryVariableTransformation >> privateTransform [ | ||
|
|
||
|
|
||
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.
nit: we usually prefer to test one thing in a test, so this would've been two tests
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.
So should I split testDefiningSequenceNodeAndHasUsagesInScope into two separate tests (testDefiningSequenceNode and testHasUsagesInScope) to keep each test focused on a single responsibility.?
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.
it's nitpick, you don't have to, we can merge like this. I'm just mentioning it to get familiar with team preferences and to potentially have it in mind for future changes
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.
Understood, thanks for the feedback! I'll keep that in mind for future contributions. Looking forward to make more and more contris, thanks!