Плагин Visual Studio для многозамены и отмены замены

Вопрос или проблема

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

Поэтому я ищу

  • плагин для Visual Studio (не Code)
  • который позволит мне выполнять серию поиска и замены
  • и позже сможет отменить замену в обратном порядке
  • проверяет на перекрытия в поисках и предупреждает меня об этом или исправляет порядок
  • в идеале: может генерировать замены на основе правил идентификаторов

Конечно, инструмент должен

  • давать мне возможность игнорировать регистр или нет
  • давать мне возможность учитывать только целые слова или нет

Позвольте привести пример…

Исходный код на C# может выглядеть так:

class SuperSecret
{
    BusinessStuff _b;
    int n;
    static string launchCode = "0000"; // TODO: спросить президента
    
    SuperSecret(BusinessStuff b)
    {
         _b = b;
    }
    
    void NobodyMayKnow()
    {
        for (int i=0; i<100; i++)
        {
            _b.HarmlessStuff();
        }
        _b.LaunchRocket(launchCode[0], launchCode[1], launchCode[2], launchCode[3]);
    }
}

Перед тем, как я помещаю этот код в ИИ, мне нужно заменить секретные части, например, я хочу заменить

  • SuperSecret
  • Stuff
  • launch
  • BusinessStuff
  • Rocket

Теперь я не должен заменять Stuff на что-то другое, пока не заменю BusinessStuff. В противном случае он больше не найдет BusinessStuff, и слово Business может остаться в коде. Поэтому порядок должен быть отсортирован по длине:

  • BusinessStuff (я хочу заменить это на i)
  • SuperSecret (я заменю это на XX02)
  • launch (я заменю это на ll03)
  • Rocket (я заменю это на R004)
  • Stuff (я заменю это на S555)

Теперь инструмент замечает, что i не является безопасной заменой, потому что его нельзя отменить без замены других частей программы. Он предлагает или позволяет мне ввести BS001 вместо этого.

Как только все настроено корректно, я нажимаю кнопку “Сделать это сейчас”.

После замены код выглядит как

class XX02
{
    BS001 _b;
    int n;
    static string ll03Code = "0000"; // TODO: спросить президента
    
    XX02(BS001 b)
    {
         _b = b;
    }
    
    void NobodyMayKnow()
    {
        for (int i=0; i<100; i++)
        {
            _b.HarmlessS555();
        }
        _b.LaunchR004(ll03Code[0], ll03Code[1], ll03Code[2], ll03Code[3]);
    }
}

С помощью ИИ я рефакторю последнюю строку, чтобы передать строку launchCode напрямую, вместо использования отдельных символов

_b.LaunchR004(ll03Code);

Чтобы восстановить мой код, замены теперь отменяются.

  • S555 снова становится Stuff
  • R004 становится Rocket
  • ll03 – это launch
  • XX02 возвращается к SuperSecret
  • BS001 отменяется на BusinessStuff

И это отменение должно быть так же просто, как нажатие кнопки “Отменить это сейчас”.

Я не работаю над ракетами илиMissile, это всего лишь пример, потому что такие вещи очевидно секретные.

Ответ или решение

К сожалению, создание полноценного плагина для Visual Studio, который бы удовлетворял всем приведённым требованиям, выходит за рамки этого ответа, но я постараюсь изложить основные моменты и концепции, которые помогут вам в разработке или выборе подходящего решения.

Задача

Сначала определим основные требования к инструменту:

  1. Многоразовая замена и возврат изменений: Плагин должен позволять производить существенные замены в коде, а затем в любой момент откатывать изменения в обратном порядке.
  2. Управление порядком замены: Плагин должен следить за возможными перекрытиями в заменах и, при необходимости, корректировать их.
  3. Настройки поиска: Инструмент должен позволять учитывать регистр и соответствовать целым словам.
  4. Генерация замен на основе правил идентификаторов: Предложение уникальных замен на основе логики.

Решение

Выбор технологии

Visual Studio поддерживает расширения, использующие .NET Framework или .NET Core. Рекомендуется использовать C# для разработки плагина, поскольку это язык, на котором пишется основной код Visual Studio.

Архитектура плагина

  1. Интерфейс пользователя:

    • Создайте пользовательский интерфейс (UI), позволяющий вводить строки для поиска и замены.
    • Обеспечьте возможность управления параметрами, такими как учёт регистра и соответствие целым словам.
  2. Логика замены:

    • Используйте структуру данных (например, Dictionary<string, string>) для хранения пар "оригинал-замена".
    • Реализуйте алгоритм, который будет проверять длину строк замены и сортировать их перед выполнением замены.
    • Реализуйте механизм для предупреждения о перекрытиях между строками. Например, если "BusinessStuff" сопоставляется с "i", программа должна предложить альтернативу.
  3. Системы Undo/Redo:

    • Реализуйте стек изменений, где каждое изменение будет фиксироваться. Для отката сохраните изначальные значения и обновите код с учётом этих значений.
  4. Функциональность генерации замен:

    • Создайте систему, которая может генерировать замены на основе заранее определённых правил (например, имя класса должно быть с определённым префиксом).

Пример реализации

Вот упрощённый пример, как может выглядеть основной код для осуществления замены. Этот код может служить основой для дальнейшей разработки:

public class ReplacementService
{
    private Dictionary<string, string> replacements = new Dictionary<string, string>();
    private Stack<string> history = new Stack<string>();

    public void AddReplacement(string original, string replacement)
    {
        // Проверка на длинные совпадения
        if(replacements.Keys.Any(key => original.Contains(key)))
        {
            throw new Exception("Replacement conflicts with existing replacements.");
        }

        replacements.Add(original, replacement);
        history.Push(original); // Добавляем в историю
    }

    public void ExecuteReplacements(ref string code)
    {
        foreach (var pair in replacements.OrderByDescending(p => p.Key.Length))
        {
            code = code.Replace(pair.Key, pair.Value);
        }
    }

    public void UndoReplacements(ref string code)
    {
        while (history.Count > 0)
        {
            var original = history.Pop();
            var replacement = replacements[original];
            code = code.Replace(replacement, original);
        }
    }
}

Заключение

Разработка плагина для Visual Studio с заданной функциональностью потребует значительных усилий, но с правильным подходом и пониманием основ можно создать эффективный инструмент для выполнения анонимизации кода. Учитывая вашу специфическую задачу, возможно, стоит рассмотреть использование существующих решений и адаптацию их под свои нужды или, при необходимости, сотрудничество с разработчиками для создания кастомного плагина.

Оцените материал
Добавить комментарий

Капча загружается...