Eclipse Extract Method 方法实现 (一)
摘要:
为了我的com.jet.anySqlRun插件的Parse Code部分进行了一点技术准备(参看Eclipse 插件开发
――我的计划 一文)。分析Eclipse Extract Method的实现,为我所用。
在开始之前我假设大家都知道Extract Method是怎么回事,不过真的不明白的话也没有关系。打开《重构》或Google一下就好。不过《重构》可能会更好一些。为什么呢?我个人认为就好在一句话:Extract Method(110)最大的困难就是处理局部变量,而临时变量则是其中一个主要的困难的源头。
The biggest problem with ExtractMethod is dealing with local variables, and temps are one of the main sources
of this issue.
这句话为我指明了分析Extract Method部分的重点。关于Eclipse
JDT这部分的实现也是我最关心的。好了,下面我就把我的分析过程分享给大家。
要分析一个功能当然是从他的操作界面入手了。用户是通过一个什么样的步骤可以完成一个Extract Method的动作呢(也许你已经很熟了,但是我还是要说一下:))?
这个是用户的操作步骤。
下面就说说Eclipse怎样为我们提供这样的服务。
1.
OP
1这是Java Editor提供的。这个不是我们关心的重点。就放他一马吧。
2.
OP2
Invoke Extract Method Function。Eclipse要提供接口来我们才能Invoke 这个Function。Eclipse是如何提供的呢。目前我还不知道是那个插件实现了Extract Method的功能,我就只好去撞大运了。找出源码来,搜索包含“ExtractMethod”字样的文件。搜索结果如下:
运气正的还不坏,发现唯一的plugin.xml。其实我只要搜plugin.xml就可以了,土了一把。
打开一看:
<action
definitionId="org.eclipse.jdt.ui.edit.text.java.extract.method"
label="%Refactoring.extractMethodAction.label"
retarget="true"
menubarPath="org.eclipse.jdt.ui.refactoring.menu/codingGroup"
id="org.eclipse.jdt.ui.actions.ExtractMethod">
</action>
他把ExtractMethod定义成了一个Action,其实不用想也可知道是这样,但是最大的收获在于这个plugin.xml文件是属于org.eclipse.jdt.ui插件。我就大胆的猜测Refactor
是在org.eclipse.ui中实现的,下面只有好好关注这个插件就好了。
现在急解决的问题是Refactor的菜单如何显示。
看到 retarget="true" 可以知道org.eclipse.jdt.ui.actions.ExtractMethod是一个“可重定目标的操作集操作”(Retargetable action set actions)Retargetable action的详细说明可以参考文档。文档中有如下的话:
注意,可重定目标的操作不指定实现类,因为要靠插件中的每个视图或编辑器设置实现每个操作的处理程序。
不会吧,是在编辑器中实现。那我就死了,没法模仿了。
被我言中了。
org.eclipse.jdt.internal.ui.javaeditor. CompilationUnitEditor.java中创建了一个RefactorActionGroup的实例。其后在RefactorActionGroup中把具体的实现类和Action关联起来。有如下代码为证:
fExtractMethodAction= new
ExtractMethodAction(editor);
fExtractMethodAction.setActionDefinitionId(IJavaEditorActionDefinitionIds.EXTRACT_METHOD);
initAction(fExtractMethodAction,
provider, selection);
editor.setAction("ExtractMethod",
fExtractMethodAction); //$NON-NLS-1$
fEditorActions.add(fExtractMethodAction);
这样就为用户提供了一个Invoke “Extract Method”的接口。
另外同过源码可以看出Extract Method这个Function的是有 ExtractMethodAction这个类来实现的。这一点也可以算是一点收获吧。