作为用户,我希望在当前界面以最快速的速度,最简单的方式完成对活动编辑页的操作,我选择使用视图标签和按钮,操作流程:
一。点击视图按钮,输入插入的函数名;
使用eclipse创建新的Plug-in Project,选择创建Plug-in with a view模板,eclipse自动生成视图和按钮的框架程序,下面要做的就是扩展对应按钮的action。
二。程序获取当前活动编辑器输入数据源对象
我们继承eclipse的传统“不使用,不创建”,在action中添加获取数据流的代码,CDT同样提供了JDT的Plugin单件模式,两个Plugin类均可使用,但是为了保持统一,我们使用CUIPlugin,这个类包含了当前eclipse界面上大多数控件的对象,例如:view、editor和Property Page等等。通过这个类获取到当前活动编辑器正在编辑的文件对象,通过这个对象,可以获取到当前文件的文件名和路径,同时也可以用来搜索对应头文件的文件名和路径。
IEditorInput input = CUIPlugin.getActivePage().getActiveEditor().getEditorInput(); if (input instanceof IFileEditorInput) { file = ((FileEditorInput)input).getFile(); }
三。生成对应文件的TranslationUnit对象。
TranslationUnit对象包含了该.c文件的语言特性,我们需要它来生成抽象语法树(AST),当然这必须要你当前的语言支持抽象语法树的生成,很幸运,C语言是支持的,抽象语法树的生成提高了我们对函数的搜索。
ITranslationUnit tu = CoreModelUtil.findTranslationUnit(file);
四。搜索函数插入位置。
我们搜索当前文件的最后一个函数的位置,在其后插入函数的定义,当然在这之前必须获取Document对象。
for ( IASTDeclaration child : ast.getDeclarations()) { if (child instanceof IASTFunctionDefinition) { FileLocation = ((IASTFunctionDefinition)child).getFileLocation(); System.out.println(((IASTFunctionDefinition)child).getDeclarator().getName()); System.out.println(FileLocation.getEndingLineNumber()); System.out.println(FileLocation.getNodeLength()); } }
五。插入函数定义。
插入文本时一定要注意replace的第二个参数一定要写0,表示插入完整的文本,不然文本可能不会被完整插入。这种插入方式是非保存形式的。
IEditorPart editorPart = CUIPlugin.getActivePage().getActiveEditor(); if (editorPart instanceof ITextEditor) { document = ((ITextEditor)editorPart).getDocumentProvider().getDocument(input); HeadProvider = new FileDocumentProvider(); try { HeadProvider.connect(HeadInput); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } headDocument = HeadProvider.getDocument(HeadInput); }
到这里c文件中的函数定义插入已经完成,原想函数声明的插入应该类似,谁知道实际操作时还颇为费了一番周则。
1。要想通过路径直接获取头文件TranslationUnit对象,必须将工程下面包含该头文件的第一个文件夹修改为Source Folder,否则CDT不会搜索该路径。通过一下方式获取Source Folder的ICElement对象,实际这是一个SourceRoot类,我们只需要在该类下加上相对路径,即可获取头文件的TranslationUnit对象。
ITranslationUnit tu = CoreModelUtil.findTranslationUnit(file); ICProject ICproject = tu.getCProject();
2。由于头文件没有活动编辑器,所以修改了document对象后,一定要保存,否则修改无法生效。
try { HeadProvider.saveDocument(null, HeadInput, headDocument, true); } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); }
3。搜索头文件函数声明时应使用TranslationUnit中的getDeclarations方法获取所有的声明,以此搜索最后的声明位置。
for ( IASTDeclaration child : HeadASTUnit.getDeclarations()) { System.out.println("Declaration: "+child.getRawSignature()); if (child instanceof IASTSimpleDeclaration) { IASTDeclarator[] declarator = ((IASTSimpleDeclaration)child).getDeclarators(); if (declarator.length < 1) { continue; } IASTDeclarator simpleDec = declarator[0]; if (simpleDec instanceof IASTFunctionDeclarator) { IASTFunctionDeclarator funcDec = (IASTFunctionDeclarator)simpleDec; HeadFileLocation = funcDec.getFileLocation(); System.out.println(funcDec.getName()); System.out.println("Head:" + HeadFileLocation.getNodeOffset()); } } }
值得注意的是,CDT6.0在搜索.c文件时会自动将包含的头文件链接进来一起搜索,太智能了,无形中增加了代码的搜索量,应该有方法可以关闭这个功能的,但是一时间没有找到。以上就是完整的CDT下自动插入文件定义和声明的程序了。预知后事如何,请听下回分解。