Eclipse CDT ASTRewrite无法正常工作

时间:2016-02-11 09:23:30

标签: java eclipse eclipse-cdt

我想在C源代码中添加一些代码,所以我尝试使用ASTRewrite 我的Github项目:cdt-rewrite
我的代码:

enter image description here

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.DefaultLogService;
import org.eclipse.cdt.core.parser.FileContent;
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.ltk.core.refactoring.Change;


public class Main {

    public static void main(String[] args) throws Exception {
        IASTTranslationUnit u = getTranslationUnit(new File("D:/test.c"));
        System.out.println(u.getRawSignature());

        ASTRewrite rw = ASTRewrite.create(u);
        u.accept(new ASTVisitor(true) {

            @Override
            public int visit(IASTStatement stm) {

                if (stm instanceof IASTIfStatement){
                    rw.insertBefore(stm.getParent(), stm, 
                            rw.createLiteralNode("callTo(1,2,3);"), null);
                }

                return PROCESS_CONTINUE;
            }

        });

        Change c = rw.rewriteAST();
        c.perform(new NullProgressMonitor());
        //String changedSource = someHowGetCode(c);
    }

    static IASTTranslationUnit getTranslationUnit(File source) throws Exception{
        FileContent reader = FileContent.create(
                source.getAbsolutePath(), 
                getContentFile(source).toCharArray());

        return GCCLanguage.getDefault().getASTTranslationUnit(
                reader, 
                new ScannerInfo(), 
                IncludeFileContentProvider.getSavedFilesProvider(), 
                null, 
                ILanguage.OPTION_IS_SOURCE_UNIT, 
                new DefaultLogService());
    }

    static String getContentFile(File file) throws IOException {
        StringBuilder content = new StringBuilder();
        String line;

        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(new FileInputStream(file)))) {
            while ((line = br.readLine()) != null)
                content.append(line).append('\n');
        }

        return content.toString();
    }
}

但是当我运行此代码时,会发生异常:

int test(int x){
    if (x < 0)
        return 0;
    int i, s = 0;
    for (i = 1; i < x; i++)
        s = s + i;
    return s;
}

Exception in thread "main" java.lang.NullPointerException
    at org.eclipse.cdt.internal.formatter.ChangeFormatter.formatChangedCode(ChangeFormatter.java:92)
    at org.eclipse.cdt.internal.core.dom.rewrite.changegenerator.ChangeGenerator.generateChange(ChangeGenerator.java:117)
    at org.eclipse.cdt.internal.core.dom.rewrite.changegenerator.ChangeGenerator.generateChange(ChangeGenerator.java:104)
    at org.eclipse.cdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.rewriteAST(ASTRewriteAnalyzer.java:26)
    at org.eclipse.cdt.core.dom.rewrite.ASTRewrite.rewriteAST(ASTRewrite.java:212)
    at Main.main(Main.java:44)

有谁知道如何解决这个例外?
谢谢你

1 个答案:

答案 0 :(得分:1)

AFAIK此代码依赖于在OSGi中运行,但您似乎已经创建了一个main的Java项目。您需要一个带有MANIFEST.MF的插件项目,该项目引用了您的需求。

如果要控制程序的入口点,可以创建Eclipse Application。如果你想让这个重写代码成为Eclipse / CDT的一部分,那么你可能会想到与菜单/工具栏/组合键相关联的不同入口点,例如Eclipse Command