Подтвердить что ты не робот

Любой инструмент рефакторинга C/С++, основанный на libclang? (даже самый простой "пример игрушки" )

Как я уже указывал - здесь - кажется, clang libclang должен быть отличным для реализации сложной задачи, которая представляет собой анализ и модификацию кода C/С++ (просмотрите видео презентацию и слайды).

Знаете ли вы о любом инструменте рефакторинга C/С++ на основе libclang?

"Любой" включает в себя даже простой проект альфа-состояния с поддержкой одного метода рефакторизации. Он может быть без поддержки препроцессора. В качестве примера функционально о котором я говорю: изменение имен методов, независимо от того, поддерживает ли он несколько файлов или только один файл за раз. Возможно, вам интересно, какая цель состоит в том, чтобы просить даже небольшие рабочие примеры. Моя мысль заключается в том, что создание списка примеров кода и небольших инструментов, которые находятся в одном месте, предоставит лучший ресурс, чтобы узнать, как реализовать рефакторизацию с помощью libclang. Я считаю, что из простых проектов могут развиваться более крупные проекты - в правильной форме с открытым исходным кодом:).

4b9b3361

Ответ 1

Clang содержит библиотеку под названием "CIndex", которая, я полагаю, была разработана для выполнения кода в среде IDE. Он также может использоваться для синтаксического анализа С++ и перехода по AST, но не имеет никакого способа рефакторинга. См. Статью Эли Бендерски здесь.

Я недавно запустил такой проект: cmonster. Это API на основе Python для синтаксического анализа С++ (с использованием libclang), анализа AST, с интерфейсом для "переписывания" (т.е. Вставки/удаления/изменения диапазонов источников). Нет никакого хорошего способа (пока) для того, чтобы делать такие вещи, как изменение имен функций и преобразование их в исходные модификации, но это было бы не так сложно сделать.

Я еще не создал выпуск с этой функциональностью (хотя это и в github repo), так как я жду, когда будет выпущен llvm/clang 3.0.

Кроме того, я должен указать несколько вещей:

  • Код очень груб, назвав его альфа, возможно, будет щедрым.
  • Я ни в коем случае не специалист по этому вопросу (в отличие, скажем, доктор Ира Бакстер).

Отрегулируйте ожидания соответствующим образом.

Обновление: выпущен cmonster 0.2, который включает описанные функции. Проверьте на Github.

Ответ 2

Google работает над библиотекой инструментов для Clang. Начиная с версии 3.2. Он включает библиотеку ASTMatchers, поэтому вы можете просто создать запрос и не должны проходить AST.

Существует отличная видео-беседа по этому вопросу, которая просматривает простой пример переименования. (Это от того же парня, что и Обсуждение MapReduce, опубликованного выше, но новее и более простую практическую реализацию, а не внутренний дизайн и масштаб предприятия материал Google продолжается).

Источник для этого примера, который переименовывает метод, доступен в ветке . Это может быть где-то в багажнике, но я не могу его найти. Также переименовать функцию getDeclAs в getNodesAs, как и в другой, явно не рекомендуется.). Существует более расширенный пример, который удаляет дублированные вызовы c_str (который находится в туловище и кто-то выше).

Вот документация для LibASTMatchers и LibTooling.

EDIT: Некоторые лучшие документы для ASTMatcher. Здесь и здесь.

EDIT: Google теперь работает над тем, что называется Clangd, целью которого является какой-то сервер Clang для рефакторинга.

Ответ 3

Google создал инструмент рефакторинга, основанный на Clang, для своей базы кода на С++ и планирует его опубликовать. Я не знаю текущее состояние проекта, но вы можете увидеть эту демонстрацию, представленную на собрании разработчиков LLVM 2011: https://www.youtube.com/watch?v=mVbDzTM21BQ.

Кроме того, встроенные функции автозавершения и рефакторинга XCode (4+) основаны на libclang.

Ответ 4

Это может быть немного "мета", но есть пример, написанный в clang как инструмент для запуска на clang (хотя, там больше, чем просто это.

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 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

Ответ 5

Не с открытым исходным кодом, но был использован для выполнения очень не игрушечного массивного автоматизированного рефакторинга программ на С++: наш DMS Software Reengineering Toolkit. DMS - это "библиотека" (мы называем ее "инструментарием" ) объектов, которые могут составлять для достижения anlaysis и/или автоматического перевода.

Относительно С++, DMS обеспечивает в этот момент времени:

  • Полный анализатор С++ 11, создающий AST и способный точно восстанавливать исходный код включая комментарии, с полным препроцессором
  • Полный синтаксический анализатор С++ с разрешением имени и типа для С++ (ANSI, GNU, MS Visual С++)
  • Анализ потока управления для С++
  • Преобразования источника в источник
  • Частично завершен механизм "переименования" (см. ниже).

Из опыта я могу сказать, что С++ - сука языка для преобразования.

Мы продолжаем работать над этим и завершаем надежный инструмент переименования. Даже это сложно; ключевой проблемой является проблема с именем-затенением. У вас есть локальная переменная X и ссылка на Y внутри этой области; вы пытаетесь переименовать Y в X и обнаружите, что локальная переменная "захватывает" доступ. Удивительно, сколько пространств имен и типов захвата вам нужно беспокоиться на С++. И это необходимо как основа для многих других рефакторингов.

EDIT Feb 2014: полный анализатор С++ 14, анализ потока управления, анализ локальных данных

Ответ 6

https://github.com/lukhnos/refactorial основан на clang и претензиях

Предоставленные преобразования

Аксессуар: синтезировать геттеры и сеттеры для назначенного элемента Переменные

MethodMove: переместить встроенные элементы функций элемента в реализацию файл

ExtractParameter: продвигайте переменную функции к параметру Функция

TypeRename: переименовать типы, включая типы тегов (enum, struct, union, класс), классы шаблонов, Objective-C типы (класс и протокол), typedefs и даже типы bulit-in (например, unsigned to uint32_t)

RecordFieldRename: переименовать записи (struct, union), включая С++ переменные-члены

ФункцияRename: переименовать функции, включая функции членов С++

Работает через спецификации в файле конфигурации YAML. Я еще не пробовал (пока).

Ответ 7

Другая возможность - создать свой собственный плагин для GCC или разработать расширение GCC MELT для выполнения вашей задачи. Но расширение GCC (или Clang) требует понимания внутренних представлений этих компиляторов (Gimple и Tree для GCC), и для этого требуется некоторая работа. MELT - это высокоуровневый доменный язык для расширения GCC.