任何基于libclang的C / C ++重构工具? (甚至最简单的“玩具示例”)
正如我已经指出的 – 在这里 – 似乎clang的libclang应该是伟大的执行艰巨的任务是C / C + +代码分析和修改( 检查video演示和幻灯片 )。
你知道任何基于libclang的C / C ++重构工具吗?
“任何”包括简单的阿尔法状态项目,支持一种重构技术。 它可以没有预处理器的支持。 作为我正在谈论的function的一个例子:更改方法名称,一次是支持多个文件还是只支持一个文件。 您可能想知道什么是要求甚至是小的工作示例的目标我的想法是, 在一个地方创build一个代码示例和小工具的列表将提供更好的资源来学习如何使用libclang实现重构 。 我相信,从简单的项目可能会扩大更大的项目 – 以适当的开源方式:)。
Clang包含一个名为“CIndex”的库,我相信这是为在IDE中完成代码完成而开发的。 它也可以用于parsingC ++和走AST,但没有什么重构的方式。 见Eli Bendersky 在这里的文章。
我最近开始了这样一个项目: cmonster 。 这是一个基于Python的API,用于parsingC ++(使用libclang),分析AST,具有“重写”(即插入/删除/修改源范围)的接口。 对于修改函数名称并将其转换为源代码修改,目前还没有很好的方法,但要做到这一点并不难。
我还没有创build这个function的发布(虽然它在github回购),因为我在等待llvm / clang 3.0发布。
另外,我应该指出一些事情:
- 代码非常粗糙,称它为alpha可能是慷慨的。
- 我绝不是这方面的专家(不像那边的Ira Baxter博士)。
适当调整预期。
更新: cmonster 0.2已经发布,其中包括描述的function。 在Github上检查一下。
Google一直在为Clang开发工具库。 自从3.2发布以来 。 它包括一个ASTMatchers库,所以你可以build立一个查询,不必走AST。
这个主题有一个伟大的video谈话 ,通过一个简单的重命名的例子。 (这是来自上面发布的MapReduce会话的同一个人,但更新,更多的是关于一个简单的实际实现,而不是Google正在进行的内部devise和企业级的东西)。
该工具分支中提供了重命名方法的示例源代码。 它可能在树干的某个地方,但我找不到它。 另外重命名getDeclAs函数getNodesAs作为另一个显然是弃用 )。 还有一个更高级的例子,删除重复的c_str调用 (在trunk和上面发布的人)。
这里是LibASTMatchers和LibTooling的文档。
编辑:ASTMatcher一些更好的文档。 在这里和这里 。
编辑: 谷歌现在正在致力于Clangd的一些东西 ,旨在成为某种铿锵的重构服务器。
Google为他们的C ++代码库制作了基于Clang的重构工具,并计划发布它。 我不知道该项目的当前状态,但是您可以在2011年LLVM开发人员会议上看到此演示: https : //www.youtube.com/watch?v = mVbDzTM21BQ 。
此外,XCode的(4+)内置自动完成和重构function基于libclang。
这可能有点“元”,但是有一个例子是用叮当作为一个工具来运行叮当(虽然,除此之外还有更多的东西。
RemoveCStrCalls.cpp
// This file implements a tool that prints replacements that remove redundant // calls of c_str() on strings. // // Usage: // remove-cstr-calls <cmake-output-dir> <file1> <file2> ... // // Where <cmake-output-dir> is a CMake build directory in which a file named // compile_commands.json exists (enable -DCMAKE_EXPORT_COMPILE_COMMANDS in // CMake to get this output). // // <file1> ... specify the paths of files in the CMake source tree. This path // is looked up in the compile command database. If the path of a file is // absolute, it needs to point into CMake's source tree. If the path is // relative, the current working directory needs to be in the CMake source // tree and the file must be in a subdirectory of the current working // directory. "./" prefixes in the relative files will be automatically // removed, but the rest of a relative path must be a suffix of a path in // the compile command line database. // // For example, to use remove-cstr-calls on all files in a subtree of the // source tree, use: // // /path/in/subtree $ find . -name '*.cpp'| // xargs remove-cstr-calls /path/to/source
https://github.com/lukhnos/refactorial是基于叮当声称;
提供的转换
访问器:为指定的成员variables合成getters和setter
MethodMove:将内联成员函数体移动到实现文件
ExtractParameter:将一个函数variables提升为该函数的参数
TypeRename:重命名types,包括标签types(枚举,结构体,联合体,类),模板类,Objective-Ctypes(类和协议),types定义甚至是引入types(例如unsigned为uint32_t)
RecordFieldRename:重命名logging(struct,union)字段,包括C ++成员variables
FunctionRename:重命名函数,包括C ++成员函数
通过YAMLconfiguration文件中的规范工作。 我还没有尝试过(还)。
不是开源的,但已经被用来对C ++程序进行非玩具大规模自动重构 :我们的DMS软件再造工具包 。 DMS是一个“库”(我们称之为“工具包”),可以构成实现分析和/或自动翻译。
与C ++相关,DMS在这个时候提供:
- 完整的C ++ 11parsing器,构buildAST并能够使用完整的预处理器准确地重新生成包括注释的源代码
- 完整的C ++parsing器,具有C ++的名称和typesparsing(ANSI,GNU,MS Visual C ++)
- 控制C ++的stream程分析
- 源到源转换
- 部分完成“重命名”机器(见下面的讨论)
我可以从经验中得出的是,C ++是一种变化的语言。
我们继续努力,并正在完成一个可靠的重命名工具。 即使这很难; 一个关键的问题是名字阴影问题。 你有一个局部variablesX,并在该范围内对Y的引用; 您尝试将Y重命名为X,并发现本地variables“捕获”访问。 在C ++中你必须担心多less命名空间和捕获types是令人惊讶的。 这需要作为许多其他重构的基础。
编辑2014年2月:完整的C ++ 14分析器,控制stream分析,本地数据stream分析
另一种可能性是开发你自己的GCC插件,或者开发一个GCC MELT扩展来完成你的任务。 但是扩展GCC(或者Clang)需要理解这些编译器的内部表示(Gimple&Tree for GCC),这需要一些工作。 MELT是扩展GCC的高级别领域特定语言。
这不是重构,而是完成,但可能是有用的:
- clang完成:使用Clang来完成C,C ++,Objective-C和Objective-C ++