【问题标题】:Modify Abstract syntax tree eclipse cdt C code修改抽象语法树eclipse cdt C代码
【发布时间】:2017-11-06 01:38:26
【问题描述】:

我有这样的c代码

static S16 test_1603b( const S16 *,  const S16 * );

我想把这段代码编辑成这样的样子

static S16 test_1603b( const S16 *varName,  const S16 *varName );

所以我做了什么我在eclipse之外使用了Eclipse CDT插件,并且我已经成功提取了抽象语法树(AST)并访问了所有方法参数声明,但是我找不到任何方法来再次重写AST新修改,My Code sn-p:

公共类 RuleChk 扩展 AbstractRule {

public RuleChk(IASTTranslationUnit ast) {
    super("RuleChk", false, ast);
    shouldVisitDeclarations = true;
    shouldVisitParameterDeclarations = true;
}

@Override
public int visit(IASTParameterDeclaration parameterDeclaration) {
    if (!parameterDeclaration.getRawSignature().startsWith("void")) {
        if (parameterDeclaration.getDeclarator().getName().getRawSignature().equals("")) {

            IASTDeclarator oldDec = parameterDeclaration.getDeclarator();

            //Create New Declarator Node
            INodeFactory factory = ast.getASTNodeFactory();
            IASTName name = factory.newName("varName".toCharArray());             
            IASTDeclarator declarator = factory.newDeclarator(name);
            declarator.setParent(oldDec.getParent());
            declarator.setInitializer(oldDec.getInitializer());
            declarator.setName(name);
            declarator.setNestedDeclarator(oldDec.getNestedDeclarator());
            declarator.setPropertyInParent(oldDec.getPropertyInParent());

            //get the rewriter
            final TextEditGroup editGroup = new TextEditGroup("FakeGroup");
            ASTRewrite rewriter = ASTRewrite.create(ast);
            rewriter.replace(declarator,oldDec,editGroup);
            rewriter.rewriteAST();
        }
    }
    return super.visit(parameterDeclaration);
  }
}

调试后我发现org.eclipse.cdt.internal.formatter.ChangeFormatter#formatChangedCode,当它尝试获取时

ICProject project = tu.getCProject();

它抛出一个空指针异常,因为 TransionUnit (tu) 从整个应用程序开始就为空,

任何想法极客!

【问题讨论】:

  • 你从哪里得到IASTTranslationUnit?通常您通过ITranslationUnit.getAST() 获得它,这意味着拥有ITranslationUnit...
  • IASTTranslationUnit translationUnit = GCCLanguage.getDefault().getASTTranslationUnit(fileContent, info, emptyIncludes, null, opts, log); 我在 Eclipse 之外作为独立项目运行 cdt 解析器,我正在使用 intellij,我尝试了这段代码 IPath ipath= new Path(path); IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(ipath); ITranslationUnit tu= (ITranslationUnit) CoreModel.getDefault().create(file); 但也失败了,因为 ResourcesPlugin.getWorkspace() 总是抛出异常说工作区已关闭:@HighCommander4

标签: java eclipse-cdt abstract-syntax-tree


【解决方案1】:

很多 CDT 基础架构,包括 ASTRewrite,并非设计为在 Eclipse 项目/工作区之外运行。

在这种情况下你通常需要做的是:

  • 创建一个 Eclipse 工作区。如果您不需要 Eclipse 工作区,您可以创建一个临时工作区并在完成后将其删除。

  • 在您的工作区中创建一个 CDT C 项目。

  • 确保您要处理的代码是项目的一部分。如果文件包含在项目的目录树中,那么这会自动发生。否则,您可以在项目中设置“链接文件夹”以引用项目目录树之外的位置。

  • 根据您的重构需求,您可能需要在项目上运行 CDT 的索引器。

  • 获取代表您要处理的文件的ITranslationUnit(类似于您在评论中写的内容)。

  • ITranslationUnit 获取IASTTranslationUnit

前四个步骤可以手动完成,也可以使用 Eclipse API 自动完成。

【讨论】:

  • 很好的解释,但是你能指导我如何通过代码完成前两步吗?,因为 ResourcePlugin 总是为空?
  • 我已经设法通过创建一个eclipse c项目并在其中添加文件来完成上述操作,但不幸的是上面的代码没有重写AST,有什么遗漏??????
  • IASTDeclarator oldDec = parameterDeclaration.getDeclarator(); //Create New Declarator Node INodeFactory factory = ast.getASTNodeFactory(); IASTName name = factory.newName("varName".toCharArray()); name.setBinding(oldDec.getName().getBinding()); name.setParent(oldDec.getName().getParent()); name.setPropertyInParent(oldDec.getPropertyInParent()); ASTRewrite rewriter = ASTRewrite.create(ast); rewriter.replace(name,oldDec.getName(),null); rewriter.rewriteAST();
  • @MostafaHassan 根据一小段代码很难判断缺少什么。我建议在CDT mailing list 上发布一个完整的示例,人们应该能够在那里提供帮助。
  • @MostafaHassan:顺便说一句。我没有忘记您的另一个问题(如何从代码创建工作区和项目),但我需要自己研究它,还没有时间。
猜你喜欢
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 2012-01-15
  • 2014-02-04
相关资源
最近更新 更多