phibao37
phibao37

Reputation: 2350

Eclipse CDT ASTRewrite not working

I want to add some code to the C source code, so I try to use ASTRewrite.
My Github project: cdt-rewrite
My code:

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();
    }
}

But when I run this code, an exception is occur:

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)

Does anyone know how to solve this exception?
Thanks you

Upvotes: 1

Views: 461

Answers (1)

Jonah Graham
Jonah Graham

Reputation: 7990

AFAIK This code is dependent on running in OSGi, but you appear to have made a Java project with a main. You need to a plug-in project with a MANIFEST.MF that references what you require.

You can create an Eclipse Application if you want to control the entry point to the program. If you want to graduate this rewriting code to be part of Eclipse/CDT, then different entry points such as an Eclipse Command tied to a menu/toolbar/key combination may be what you want.

Upvotes: 1

Related Questions