Включить заголовочный файл в абстрактное синтаксическое дерево CDT - PullRequest
0 голосов
/ 29 мая 2018

Проблема: я хочу сгенерировать прототип функции, если он не существует, в файле C я сделал это, но в случае, если прототип уже существует в заголовочном файле, он этого не чувствует, кстати, я использовал CDTIIndex

//C Code
#include "test.h" //where it have bar prototype
void bar(void)
{
    //function body
}


//Obtaining the AST [JAVA CDT CHECKER]
ITranslationUnit tu = (ITranslationUnit) CDTUITools.getEditorInputCElement(editor.getEditorInput());
String cFilePath = tu.getResource().getFullPath().toString();
ICProject[] allProjects = CoreModel.getDefault().getCModel().getCProjects();
IIndex **index** = CCorePlugin.getIndexManager().getIndex(allProjects);
IASTTranslationUnit ast = null;
try {
    index.acquireReadLock(); // we need a read-lock on the index
    ast = tu.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
} finally {
    index.releaseReadLock();
    ast = null; // don't use the ast after releasing the read-lock
}


//In the AST visitor class
/**
 * extract prototype and store them into 'prototypes' hash set and then rewrite the AST.
 */
@Override
protected int visit(IASTSimpleDeclaration simpleDeclaration) {
    IASTDeclarator[] declarators = simpleDeclaration.getDeclarators();  
    boolean isProtoFuncDeclaration = false;
    for (IASTDeclarator declarator: declarators) {
        if( declarator instanceof IASTFunctionDeclarator)
        {
            isProtoFuncDeclaration = true;
        }
    }   
    if(isProtoFuncDeclaration)
    {
        prototypes.add(simpleDeclaration);
    }
    return super.visit(simpleDeclaration);
}

Вывод нового кода C

#include "test.h" //where it have bar prototype
void bar(void) <=== I shouldn't be inserted as it is already in the header

void bar(void)
{
    //function body
}

1 Ответ

0 голосов
/ 30 мая 2018

Я бы предложил следующее:

  • Пройдите AST, чтобы найти IASTFunctionDefinition, для которого вы, возможно, захотите добавить прототип.
  • Используйте getDeclarator().getName(), чтобы получитьимя функции,
  • Используйте IASTName.resolveBinding(), чтобы получить привязку функции.
  • Используйте IIndex.findDeclarations(IBinding), чтобы найти все объявления и определения функции.
  • Из полученного IIndexName[], отфильтруйте само определение (отметьте IName.isDefinition()).
  • Далее отфильтруйте список по объявлениям, которые появляются во включенных заголовочных файлах (поскольку findDeclarations() будет возвращать объявления во всем проекте).Вы можете сделать это, вызвав IASTTranslationUnit.getIndexFileSet() в своем AST и проверив IIndexFileSet.contains(name.getFile()) для каждого IIndexName.
  • Если после этой фильтрации список пуст, вы знаете, что вам нужно добавить прототип.
...