-
-
Notifications
You must be signed in to change notification settings - Fork 420
[Refactoring] Driver improvement for temp to instance variable #18821
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
Changes from 5 commits
7f93db9
497bf9a
3fa60b3
5396e18
901503a
7e2d58c
be757cd
c5fd2f3
3c78684
f2c41d1
553b828
e341041
2a425d4
1b216c9
6875cf6
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 |
|---|---|---|
|
|
@@ -114,17 +114,9 @@ RBTemporaryToInstanceVariableRefactoring >> applicabilityPreconditions [ | |
| RBTemporaryToInstanceVariableRefactoring >> breakingChangePreconditions [ | ||
|
|
||
| ^ { | ||
| (RBCondition withBlock: [ | ||
| (class allSubclasses anySatisfy: [ :cls | cls definesInstanceVariable: temporaryVariableName asString ]) ifTrue: [ | ||
| self refactoringWarning: | ||
| ('One or more subclasses of <1p> already defines an<n>instance variable with the same name. Proceed anyway?' | ||
| expandMacrosWith: class name) ]. | ||
| true ]). | ||
| (RBCondition checkNotMultipleTemporaryDefinitionsOf: temporaryVariableName in: class). | ||
| (ReVariablesNotReadBeforeWrittenCondition new | ||
| subtree: parseTree; | ||
| variables: temporaryVariableName; | ||
| checkForTemporaryVariables: true) } | ||
| self preconditionNoSubclassDefinesVar. | ||
| self preconditionNoMultipleTempOccurences. | ||
| self preconditionNoReadBeforeWritten } | ||
| ] | ||
|
|
||
| { #category : 'initialization' } | ||
|
|
@@ -143,6 +135,31 @@ RBTemporaryToInstanceVariableRefactoring >> isTemporaryVariableNameValid [ | |
| self refactoringError: temporaryVariableName , ' is a block parameter' ] | ||
| ] | ||
|
|
||
| { #category : 'preconditions' } | ||
| RBTemporaryToInstanceVariableRefactoring >> preconditionNoMultipleTempOccurences [ | ||
|
|
||
| ^ ReMultipleMethodsDontReferToTempVarsCondition name: temporaryVariableName class: class selector: selector | ||
| ] | ||
|
|
||
| { #category : 'preconditions' } | ||
| RBTemporaryToInstanceVariableRefactoring >> preconditionNoReadBeforeWritten [ | ||
|
|
||
| ^ ReVariablesNotReadBeforeWrittenCondition new | ||
| subtree: parseTree; | ||
| variables: temporaryVariableName; | ||
| checkForTemporaryVariables: true | ||
| ] | ||
|
|
||
| { #category : 'preconditions' } | ||
| RBTemporaryToInstanceVariableRefactoring >> preconditionNoSubclassDefinesVar [ | ||
|
|
||
| ^ RBCondition | ||
| withBlock: [ (class allSubclasses anySatisfy: [ :cls | cls definesInstanceVariable: temporaryVariableName asString ]) 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. In a second PR we should remove this pop up!
Contributor
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.
Yes, I suggested Alexis to leave it like this for the moment. |
||
| errorString: | ||
| ('One or more subclasses of <1p> already defines an<n>instance variable with the same name. Proceed anyway?' | ||
| expandMacrosWith: class name) | ||
| ] | ||
|
|
||
| { #category : 'preconditions' } | ||
| RBTemporaryToInstanceVariableRefactoring >> preconditions [ | ||
|
|
||
|
|
@@ -159,10 +176,6 @@ RBTemporaryToInstanceVariableRefactoring >> prepareForExecution [ | |
| RBTemporaryToInstanceVariableRefactoring >> privateTransform [ | ||
|
|
||
| self removeTemporaryOfClass: class. | ||
| class allSubclasses do: [ :cls | | ||
| (cls definesInstanceVariable: temporaryVariableName) | ||
| ifTrue: [ cls removeInstanceVariable: temporaryVariableName ] | ||
| ifFalse: [ self removeTemporaryOfClass: cls ] ]. | ||
| class addInstanceVariable: temporaryVariableName | ||
| ] | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| Class { | ||
| #name : 'ReMultipleMethodsDontReferToTempVarsCondition', | ||
| #superclass : 'ReVariableNameCondition', | ||
| #instVars : [ | ||
| 'class', | ||
| 'selector' | ||
| ], | ||
| #category : 'Refactoring-Core-Conditions', | ||
| #package : 'Refactoring-Core', | ||
| #tag : 'Conditions' | ||
| } | ||
|
|
||
| { #category : 'instance creation' } | ||
| ReMultipleMethodsDontReferToTempVarsCondition class >> name: aString class: aClass selector: aSelector [ | ||
|
|
||
| ^ (self name: aString) | ||
| class: aClass; | ||
| selector: aSelector yourself | ||
| ] | ||
|
|
||
| { #category : 'checking' } | ||
| ReMultipleMethodsDontReferToTempVarsCondition >> check [ | ||
|
|
||
| ^ self violators isEmpty | ||
| ] | ||
|
|
||
| { #category : 'setter' } | ||
| ReMultipleMethodsDontReferToTempVarsCondition >> class: aRBClass [ | ||
|
|
||
| class := aRBClass. | ||
|
|
||
| ] | ||
|
|
||
| { #category : 'utilities' } | ||
| ReMultipleMethodsDontReferToTempVarsCondition >> multipleMethodsDefiningTemporary: aString in: aClass ignore: aBlock [ | ||
|
|
||
| | searcher methods method | | ||
| searcher := OCParseTreeSearcher new. | ||
| methods := Set new. | ||
| method := nil. | ||
|
|
||
| searcher matches: aString do: [ :aNode :answer | methods add: method ]. | ||
| aClass withAllSubclasses do: [ :cls | | ||
| cls selectors do: [ :each | | ||
| (aBlock value: cls value: each) ifFalse: [ | ||
| | parseTree | | ||
| method := cls methodFor: each. | ||
| parseTree := cls parseTreeForSelector: each. | ||
| parseTree ifNotNil: [ searcher executeTree: parseTree ] ] ] ]. | ||
| ^ methods | ||
| ] | ||
|
|
||
| { #category : 'accessing' } | ||
| ReMultipleMethodsDontReferToTempVarsCondition >> selector: aSelector [ | ||
|
|
||
| selector := aSelector | ||
| ] | ||
|
|
||
| { #category : 'displaying' } | ||
| ReMultipleMethodsDontReferToTempVarsCondition >> violationMessageOn: aStream [ | ||
|
|
||
| self violators ifEmpty: [ ^ self ]. | ||
| ^ aStream | ||
| nextPutAll: 'More than one method defines temporary variable '; | ||
| nextPutAll: name; | ||
| nextPutAll: ': '; | ||
| nextPutAll: (self violators collect: [ :m | m selector ]) asArray asString | ||
| ] | ||
|
|
||
| { #category : 'checking' } | ||
| ReMultipleMethodsDontReferToTempVarsCondition >> violators [ | ||
|
|
||
| | methods | | ||
| methods := self multipleMethodsDefiningTemporary: name in: class ignore: [ :cls :selectors | false ]. | ||
| ^ methods reject: [ :m | m selector = selector ] | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| Class { | ||
| #name : 'ReClassToConvertTemporaryToInstanceVariable', | ||
| #superclass : 'Object', | ||
| #instVars : [ | ||
| 'instVar' | ||
| ], | ||
| #category : 'Refactoring-DataForTesting-ForConvertingVariables', | ||
| #package : 'Refactoring-DataForTesting', | ||
| #tag : 'ForConvertingVariables' | ||
| } | ||
|
|
||
| { #category : 'action' } | ||
| ReClassToConvertTemporaryToInstanceVariable >> doAction1 [ | ||
|
|
||
| | temp | | ||
| temp := 35. | ||
|
|
||
| ^ temp | ||
| ] | ||
|
|
||
| { #category : 'action' } | ||
| ReClassToConvertTemporaryToInstanceVariable >> doAction2 [ | ||
|
|
||
| | instVar | | ||
| instVar := 3. | ||
| ^ instVar | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| Class { | ||
| #name : 'ReConvertTemporaryToInstanceVariableDriverTest', | ||
| #superclass : 'ReDriverTest', | ||
| #instVars : [ | ||
| 'testingEnvironment' | ||
| ], | ||
| #category : 'Refactoring-UI-Tests-Driver', | ||
| #package : 'Refactoring-UI-Tests', | ||
| #tag : 'Driver' | ||
| } | ||
|
|
||
| { #category : 'getter' } | ||
| ReConvertTemporaryToInstanceVariableDriverTest >> classToConvertTemporaryToInstanceVariable [ | ||
|
|
||
| ^ ReClassToConvertTemporaryToInstanceVariable | ||
| ] | ||
|
|
||
| { #category : 'running' } | ||
| ReConvertTemporaryToInstanceVariableDriverTest >> setUp [ | ||
|
|
||
| super setUp. | ||
| testingEnvironment := RBClassEnvironment classes: self classToConvertTemporaryToInstanceVariable withAllSubclasses | ||
| ] | ||
|
|
||
| { #category : 'tests' } | ||
| ReConvertTemporaryToInstanceVariableDriverTest >> testConvertTempFailure [ | ||
|
|
||
| | driver | | ||
| driver := ReConvertTemporaryToInstanceVariableDriver new. | ||
| self setUpDriver: driver. | ||
| driver class: self classToConvertTemporaryToInstanceVariable selector: #doAction2 variable: 'instVar'. | ||
|
|
||
| driver runRefactoring. | ||
|
|
||
| self assert: driver refactoring changes changes size equals: 0 | ||
| ] | ||
|
|
||
| { #category : 'tests' } | ||
| ReConvertTemporaryToInstanceVariableDriverTest >> testConvertTempSuccessfully [ | ||
|
|
||
| | driver | | ||
| driver := ReConvertTemporaryToInstanceVariableDriver new. | ||
| self setUpDriver: driver. | ||
| driver class: self classToConvertTemporaryToInstanceVariable selector: #doAction1 variable: 'temp'. | ||
|
|
||
| driver runRefactoring. | ||
|
|
||
| self assert: driver refactoring changes changes size equals: 2. | ||
|
|
||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| Class { | ||
| #name : 'ReBrowseMethodsChoice', | ||
| #superclass : 'ReMethodChoice', | ||
| #category : 'Refactoring-UI-Choices', | ||
| #package : 'Refactoring-UI', | ||
| #tag : 'Choices' | ||
| } | ||
|
|
||
| { #category : 'accessing' } | ||
| ReBrowseMethodsChoice >> action [ | ||
|
|
||
| driver browseMethods | ||
| ] | ||
|
|
||
| { #category : 'accessing' } | ||
| ReBrowseMethodsChoice >> description [ | ||
|
|
||
| ^ 'Browse the methods' | ||
|
Contributor
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. This description is almost the same as |
||
| ] | ||
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.
This is certainly a mistake; could you please revert it?
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.
Yes, this is happening when doing a merge from Iceberg :(