Любой инструмент рефакторинга C/С++, основанный на libclang? (даже самый простой "пример игрушки" )
Как я уже указывал - здесь - кажется, clang libclang должен быть отличным для реализации сложной задачи, которая представляет собой анализ и модификацию кода C/С++ (просмотрите видео презентацию и слайды).
Знаете ли вы о любом инструменте рефакторинга C/С++ на основе libclang?
"Любой" включает в себя даже простой проект альфа-состояния с поддержкой одного метода рефакторизации. Он может быть без поддержки препроцессора. В качестве примера функционально о котором я говорю: изменение имен методов, независимо от того, поддерживает ли он несколько файлов или только один файл за раз. Возможно, вам интересно, какая цель состоит в том, чтобы просить даже небольшие рабочие примеры. Моя мысль заключается в том, что создание списка примеров кода и небольших инструментов, которые находятся в одном месте, предоставит лучший ресурс, чтобы узнать, как реализовать рефакторизацию с помощью libclang. Я считаю, что из простых проектов могут развиваться более крупные проекты - в правильной форме с открытым исходным кодом:).
Ответы
Ответ 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.
Ответ 8
Это не рефакторинг, а завершение, но может быть полезно: