Open rajkuma1 opened 13 years ago
There is another way to invoke refactorings (it might be the same category as one of those listed above): you can right-click on the structured view (Package Explorer or Outline View).
Let's classify the Package Explorer and Outline View (and possibly other views) as graphical structured view of source code. It would be interesting to see how developers prefer to invoke the refactorings:
@vazexqi: You can invoke the refactoring menu from the graphical structured views by using ALT+SHIFT+T
keyboard shortcut.
Here' my investigation notes for the evening:
There are 2 refactoring suggestions present when you invoke CTRL+1
quick assist shortcut.
They are from this file: CorrectionMessages.properties
RenameRefactoringProposal_name=Rename in workspace LinkedNamesAssistProposal_description=Rename in file
org.eclipse.jdt.internal.ui.text.correction.CorrectionMessages has a truck load of strings for being referenced for correction suggestions. org.eclipse.jdt.internal.ui.text.correction.proposals.RenameRefactoringProposal contains Mohsen's changes to say that the refactoring was invoked through quick assist. org.eclipse.jface.text.contentassist.ICompletionProposal seems to be the common base class for all the context sensitive proposals. There are other interfaces that exist for backward compatibility. org.eclipse.jface.text.contentassist.ICompletionListener are interfaces for listening to the content assist events. org.eclipse.jface.text.contentassist.ContentAssistant registers listeners for capturing events about invoking content assistant code.
org.eclipse.jdt.ui.text.java.IQuickFixProcessor org.eclipse.jdt.internal.ui.text.correction.QuickFixProcessor is the concrete class for checking the problems. org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor gets the correction proposals for all the QuickFixProcessor instances in the system.
Consider a file in a JAVA project called C.java
with the following contents.
public class D {
}
Now, you can invoke the quick fix from insider the editor to rename the compilation unit to D.java
.
When you do this, the file gets renamed and the compilation issue gets resolved. However, eclipse doesn't seem to record this change. Also, the RenameCompilationUnit
refactoring processor does not get invoked. It looks like quick fixes don't reuse refactoring classes and compute the changes themselves.
When I invoke the completion popup via CTRL + 1
and pick an action to perform, line 933 gets executed.
This holds good for my previous comment.
Now, let's say that you type sysout inside a method and hit CTRL + 1
, you'll see the following:
When in this state, the user can do one of the 2 actions:
Hits the ESC
key and quits the suggestions.
In this case, the org.eclipse.jface.text.contentassist.CompletionProposalPopup.verifyKey(VerifyEvent)
would execute to line
switch (key) { case 0x1B: // Esc e.doit = false; hide(); break; }
No further action is taken.
Hits the ENTER
key.
In this case, the verifyKey
method would execute this part of the switch:
case '\n': // Ctrl-Enter on w2k case '\r': // Enter e.doit= false; insertSelectedProposalWithMask(e.stateMask); break;
insertSelectedProposalWithMask
is executed.
In this method, the ICompletionProposal
that was selected by the user is fetched and the change is performed.
There is a subtle difference between the correction performed when invoked via CTRL + 1
and CTRL + SPACE
.
Inside the method org.eclipse.jface.text.contentassist.CompletionProposalPopup.insertProposal(ICompletionProposal, char, int, int)
, the instance of the proposal called is different.
In the case of CTRL + 1
invocation, the proposal is an instance of org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeCorrectionProposal
. So, line 933
is executed.
Now, consider this scenario of invoking CTRL + SPACE
to kick off the template proposal.
In this case, the flow is the same, except that an instance of org.eclipse.jface.text.contentassist.ICompletionProposalExtension2
is executed in line 927
.
Another way to look at this is org.eclipse.jface.text.contentassist.ContentAssistant.isAutoInserting()
is true when invoked through CTRL + SPACE
.
I see two possibilities here:
CompletionProposalPopup
class.org.eclipse.jface.text.contentassist.ContentAssistant
and see if we can add ourselves as a listener. Refer org.eclipse.jface.text.contentassist.ContentAssistant.addContentAssistListener(IContentAssistListener, int)
.Why was the issue closed? Was it incorporated into a different issue? Or did we choose to use a different approach? Or is this issue no longer important?
Anyway, my question about the previous comment is: is there a way that we can hook into the invocation mechanism without touching the jface code? JFace is quite low-level and is depended on by many other plug-ins so it is very risky to modify.
I didn't close this issue. I don't know how that happened.
Notes for the evening: When eclipse first starts up, org.eclipse.jdt.ui.actions.RefactorActionGroup.RefactorActionGroup(IWorkbenchSite, ISelectionProvider) is created. From then on, it's cached. It is here that the refactoring actions are created.
One of the implementations, org.eclipse.jdt.ui.actions.RenameAction has been touched by @vazexqi and @reprogrammer to know if the invocation was through quickAssist.
/org.eclipse.jdt.ui holds references to the menu items that are present on the right click action.
RenameInformationPopup_EnterNewName=Enter new name, press {0} to refactor
Here's the stack trace when the initialization of the org.eclipse.jdt.ui.actions.RefactorActionGroup
takes place:
Thread [main] (Suspended (breakpoint at line 66 in RenameAction))
RenameAction.<init>(IWorkbenchSite) line: 66
RefactorActionGroup.<init>(IWorkbenchSite, ISelectionProvider) line: 371
RefactorActionGroup.<init>(IViewPart) line: 205
JavaNavigatorRefactorActionProvider.init(ICommonActionExtensionSite) line: 60
NavigatorActionService$6.run() line: 373
SafeRunner.run(ISafeRunnable) line: 42
NavigatorActionService.initialize(String, String, CommonActionProvider) line: 369
NavigatorActionService.access$2(NavigatorActionService, String, String, CommonActionProvider) line: 366
NavigatorActionService$5.run() line: 351
SafeRunner.run(ISafeRunnable) line: 42
NavigatorActionService.getActionProviderInstance(CommonActionProviderDescriptor) line: 347
NavigatorActionService$3.run() line: 257
SafeRunner.run(ISafeRunnable) line: 42
NavigatorActionService.fillActionBars(IActionBars) line: 253
CommonNavigatorManager.selectionChanged(SelectionChangedEvent) line: 222
Viewer$2.run() line: 162
SafeRunner.run(ISafeRunnable) line: 42
JFaceUtil$1.run(ISafeRunnable) line: 49
SafeRunnable.run(ISafeRunnable) line: 175
CommonViewer(Viewer).fireSelectionChanged(SelectionChangedEvent) line: 160
CommonViewer(StructuredViewer).updateSelection(ISelection) line: 2162
CommonViewer(StructuredViewer).handleSelect(SelectionEvent) line: 1190
CommonViewer.handleSelect(SelectionEvent) line: 478
StructuredViewer$4.widgetSelected(SelectionEvent) line: 1220
OpenStrategy.fireSelectionEvent(SelectionEvent) line: 228
OpenStrategy.access$4(OpenStrategy, SelectionEvent) line: 222
OpenStrategy$1.handleEvent(Event) line: 389
EventTable.sendEvent(Event) line: 84
Tree(Widget).sendEvent(Event) line: 1258
Display.runDeferredEvents() line: 3540
Display.readAndDispatch() line: 3161
Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 2640
Workbench.runUI() line: 2604
Workbench.access$4(Workbench) line: 2438
Workbench$7.run() line: 671
Realm.runWithDefault(Realm, Runnable) line: 332
Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 664
PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149
IDEApplication.start(IApplicationContext) line: 115
EclipseAppHandle.run(Object) line: 196
EclipseAppLauncher.runApplication(Object) line: 110
EclipseAppLauncher.start(Object) line: 79
EclipseStarter.run(Object) line: 369
EclipseStarter.run(String[], Runnable) line: 179
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 597
Main.invokeFramework(String[], URL[]) line: 619
Main.basicRun(String[]) line: 574
Main.run(String[]) line: 1407
Main.main(String[]) line: 1383
@vazexqi guess I found why the issue closes. When you hit the Comment & Close
button on chrome on ubuntu, the issue is closed. The earlier behavior was, the issue wouldn't be closed :)
When eclipse first starts up, org.eclipse.jdt.ui.actions.RefactorActionGroup.RefactorActionGroup(IWorkbenchSite, ISelectionProvider)
is created. From then on, it's cached. It is here that the refactoring actions are created.
One of the implementations, org.eclipse.jdt.ui.actions.RenameAction
has been touched by @vazexqi and @reprogrammer to know if the invocation was through quickAssist.
When refactoring menu is invoked through SHIFT + CTRL + T
, org.eclipse.jdt.ui.actions.RefactorActionGroup.fillQuickMenu(IMenuManager)
gets invoked. This is due to the call from org.eclipse.ui.actions.QuickMenuCreator.createMenu()
When I right click on the project to see the menu options, this is what happens: org.eclipse.jdt.internal.ui.navigator.JavaNavigatorRefactorActionProvider.fillContextMenu(IMenuManager)
gets invoked.
@reprogrammer and I found out that the drag-and-drop mechanism for Move Refactoring is called through this the ReorgMoveStarter class.
This information might be useful to get started on capturing the drag-and-drop invocation mechanism.
The refactoring logs of CodingSpectator should include the method the refactoring was invoked. There are 8 ways that I know of to invoke a refactoring:
Refactor
Some quick fixes will implicitly invoke refactorings. Here's the only example that we know so far (are there more?):
If C1 was not declared in package a, then there wil be a quick-fix annotation on the editor. Click on it and it will suggest two things: move the package or delete the package declaration. If you select move package, it will implicitly invoke the move refactoring (this is captured in the refactoring logs).
Currently, CodingSpectator distinguishes invocations of refactorings through quick assist from others. It might be useful to distinguish other methods of invoking refactorings as well.