Delphi: как автоматически удалять неиспользуемые переменные (подсказка «переменная x объявлена, но никогда не используется») - PullRequest
5 голосов
/ 10 февраля 2009

Существует ли какой-либо инструмент (желательно бесплатный), который может анализировать синтаксис Pascal / Delphi и автоматически удалять неиспользуемые переменные?

В моем случае я работаю с очень большой базой кода Delphi, и компилятор намекает на отчет о более чем тысяче случаев "Переменная 'x' объявлена, но никогда не используется".

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

Я искал в Интернете, но не нашел ... Кто-нибудь здесь знает о таком инструменте?

Спасибо ...

Марк Брэрфорд

Ответы [ 4 ]

4 голосов
/ 10 февраля 2009

Я понимаю вашу точку зрения и полностью согласен, что такой инструмент будет полезен при работе с устаревшим кодом. К сожалению, я не знаю ни одного существующего инструмента (я должен добавить бесплатный инструмент здесь, инструменты статического анализа, конечно, должны быть в состоянии сделать это легко, но я не знаю ни одного бесплатного инструмента статического анализа кода), который способен сделать это .

Но я думаю, вы могли бы легко написать такой инструмент за несколько минут. Небольшой графический интерфейс с памяткой и кнопкой должно быть достаточно. Затем просто скопируйте подсказки компилятора в заметку и нажмите кнопку. Затем инструмент анализирует каждую строку. Он может легко проверить, содержит ли строка искомую подсказку, и каждая такая строка имеет одинаковую структуру, поэтому анализ должен быть относительно простым. Затем он может извлечь имя файла и номер строки, открыть файл и удалить объявление переменной. Это может быть немного сложно в случае нескольких объявлений переменных в одной строке, но я думаю, что это выполнимо.

Я не знаю, слишком ли много для вас усилий по сравнению с задачей удаления всех объявлений переменных самостоятельно. Но я бы хотел увидеть такой инструмент, поэтому не стесняйтесь писать его:)

Надеюсь, это помогло хоть немного.

Хорошо, я действительно не вижу здесь никаких проблем. Для синтаксического анализа:

function ParseHint (const HintText : String; out HintInfo : THintInfo) : Boolean;
var
  I, J     : Integer;
  HintName : String;
begin
  Result := False;
  for I := 1 to Length (HintText) do
  begin
    if (HintText [I] = '(') then
    begin
      J := I + 1;
      while (HintText [J] <> ')') do Inc (J);
      HintInfo.LineNumber := StrToInt (MidStr (HintText, I+1, J-(I+1)));
      HintInfo.SourceFile := MidStr (HintText, 12, I-12);
      HintName := MidStr (HintText, J+3, 5);
      if (HintName <> 'H2164') then Exit (False);
    end;
    if (HintText [I] = '''') then
    begin
      J := I + 1;
      while (HintText [J] <> '''') do Inc (J);
      HintInfo.VarName := MidStr (HintText, I+1, J-(I+1));
      Exit (True);
    end;
  end;
end;

Что ж, чтение исходного файла должно быть легким, поэтому единственная оставшаяся часть - это удаление переменной из строки объявления. Мы можем просто найти вхождения HintInfo.VarName в строке и проверить, являются ли символы до и после вхождения не буквами, а только «,» или «:». Если это так, мы можем просто удалить его. Это охватывает все эти случаи:

var UnusedVar : Integer;
var
  UnusedVar,
  AnotherVar : Integer;
var
  UnusedVar, AnotherVar : Integer;

Скажите, если я ошибаюсь или если я забыл какие-либо случаи, но я думаю, что это сработает, и я решу проблему удаления неиспользуемых переменных из исходных файлов delphi, используя подсказки, сгенерированные компилятором.

2 голосов
/ 11 февраля 2009

Решение простое, но требует таких часов, чтобы убедиться, что вы не ошиблись. Прежде всего, вы можете использовать Alt-F8 для пошагового просмотра каждого отчета один за другим (и Alt-F7 для перехода назад). Это делает их поиск очень легким. Курсор ставится на линии для вас. Затем просто дважды нажмите клавишу «/», чтобы закомментировать. Не удаляйте это, прокомментируйте это. Таким образом, если вы допустили ошибку, вы не потеряли никакой информации. Наличие переменной и ее тип данных все еще записывается. Вы можете привести это в порядок позже.

Одна оговорка ко всему этому: условная компиляция может сделать некоторые переменные неиспользованными при построении различными способами. Если это произойдет, просто раскомментируйте переменную еще раз и поместите условие вокруг объявления.

2 голосов
/ 10 февраля 2009

Вы уверены, что переменные не должны использоваться? Я знаю, что компилятор выясняет, что они сейчас не используются, но верно ли это, возможно, многие из них следует использовать, но разработчик использовал x2 вместо x1, например, копирование и вставка?

Хотя вы можете захотеть удалить все эти переменные без контроля, я бы не стал так торопиться, они могут быть признаками ошибок в вашем коде, которые вы хотели бы исправить.

Пример:

procedure PlotPixelAtCenter(rect: Rectangle)
var
    x, y: Integer;
begin
    x := (rect.Left + rect.Right) div 2;
    x := (rect.Top + rect.Bottom) div 2; // <-- bug here, should be y :=
    PlotPixel(x, y);
end;

В этом примере вы получите ошибку о неиспользованной переменной, но это скрытая ошибка. Конечно, в этом примере ошибку легко найти, так как построение графика, вероятно, будет отключено, но другие подобные ошибки, возможно, будет сложнее обнаружить.

2 голосов
/ 10 февраля 2009

Если такого инструмента нет и у вас есть терпение, я создаю инструмент анализа и исправления Delphi. И удаление неиспользованных символов в списке. Это проект с низким уровнем добычи, поэтому я не могу дать оценку, когда он будет готов.

Просто чтобы объяснить, почему это не тривиальная задача:

  1. читать источник
  2. создать модель, которая содержит достаточно информации для каждого использования символа.
  3. отметить все неиспользуемые символы.
  4. переписать источник без лишних символов.

Задачи 1 и 2 сложные (к счастью для меня они уже выполнены). Язык Delphi довольно сложный. И вам нужны все языковые элементы, чтобы иметь возможность воссоздать источник.

Задача 3 проста. Просто отметьте все символы, которые не используются. Но остерегайтесь символов в разделе интерфейса устройства. Возможно, они не используются, но понадобятся позже (или другим проектом).

Задача 4 зависит.

Aproach A использует промежуточный формат (например, список строк), затем вы можете использовать модель, чтобы найти объявление каждого неиспользуемого символа (снизу вверх, в противном случае вы можете изменить номера строк). Вы удаляете все, что не нужно. И не забудьте удалить ключевое слово var, если оно является последним в списке!

Aproach B полностью переписывает исходный файл. В этом случае вы должны сохранить все комментарии, что не очень интересно делать (но моей модели это тоже нужно). Вы просто удаляете неиспользуемые символы из модели и переписываете ее. Всегда создавайте резервную копию, поскольку это может привести к катастрофе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...