Как автоматически удалить методы в коде Java

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

Такого не бывает, тогда я напишу сценарий.

6 ответов

Решение

Я искал быстрые решения и не нашел, я использовал различные инструменты, чтобы добраться туда:

  1. grep, чтобы найти все файлы, содержащие основные методы, которые я хотел удалить
  2. найти / заменить в этих файлах, чтобы сделать эти методы частными
  3. Очистка Eclipse только с одним правилом: удаляйте неиспользуемые приватные методы

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

Спасибо всем за вклад, это может быть применимо позже.

Если вы используете eclipse или другую мощную IDE, возможно, у вас есть встроенная поддержка для этого. Видите, я не могу удалить метод с использованием рефакторинга Eclipse? за способ достичь того, что вы хотите.

Сегодня есть несколько способов добиться этого. Например, вы можете сказать компилятору Eclipse дать вам AST (см. Мой блог для примера). Вы можете перемещаться по AST, чтобы найти методы и удалить узлы, чтобы изменить источник.

Это позволяет легко сохранять код действительным. Используя средство форматирования кода Eclipse, вы можете впоследствии очистить форматирование.

Такие проекты, как MoDisCo, идут на шаг дальше, анализируя весь проект и давая вам возможность искать его целиком. Я только что обнаружил, что документация для MoDisCo не очень полезна, когда вы новичок.

Для этого можно использовать наш инструментарий реинжиниринга программного обеспечения DMS с интерфейсом Java.

DMS анализирует языки (используя свои внешние интерфейсы, в данном случае Java), создает AST и таблицы символов и предоставляет средства для управления AST на основе пользовательского анализа. В этом случае OP хочет предоставить сигнатуру метода (предположительно с контекстом, в котором его следует интерпретировать, поскольку в противном случае типы, используемые в сигнатуре, могут быть не определены), найдите эту сигнатуру в таблице символов, найдите точку объявления (это находится в таблице символов) как узел AST, а затем применяется правило перезаписи, которое заменяет объявление пустым объявлением.

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

Вы говорите о "преобразовании исходного кода", и Google обнаруживает существование BeautyJ для Java:

http://beautyj.berlios.de/

"BeautyJ может конвертировать исходный код Java в XML и обратно. BeautyJ представляет формат XJava, в котором классы или интерфейсы и их члены хранятся вместе со связанным исходным кодом и комментариями Javadoc в одном файле XML. BeautyJ открывает широкий спектр возможностей для автоматического структурирования. исходного кода Java либо с помощью API Sourclet, либо путем преобразования исходного кода Java в XML и разрешения любых внешних преобразований (например, с помощью XSLT)."

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

Вы можете использовать что-нибудь на Java для пакетной модификации вашего Java-проекта. Хитрость заключается в использовании специального обработчика аннотаций. С помощью процессора аннотаций вы можете изменять практически все.

Например, эта библиотека (для ecilipse и IDEA) изменяет некоторые члены поля String на это /**multiline*/ документы

Изучение библиотеки также дает мне возможность изменять тело метода.

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

Итак, вместо того, чтобы напрямую изменять код с помощью сценария или простой руки, я решил написать другой обработчик аннотаций, который позволит вам удалить некоторые члены класса.

Для IDEA код, подтверждающий концепцию, очень прост:

      // the custom annotation 
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface StripMethods {
    boolean strip() default true;
    String key() default "";
}
      // processing the custom annotation 

@Override
public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
    Set<? extends Element> fields = roundEnv.getElementsAnnotatedWith(StripMethods.class);
    for (Element field : fields) {
        StripMethods annotation = field.getAnnotation(StripMethods.class);
        ElementKind KIND = field.getKind();
        if(KIND == ElementKind.CLASS) {
            // the class declaration
            JCTree.JCClassDecl laDcl = (JCTree.JCClassDecl) elementUtils.getTree(field);
            // the definition tree list
            ArrayList<JCTree> defs = new ArrayList<>(laDcl.defs);
            // remove the second member which in this case is a string field 
            defs.remove(2);
            // finally modify the class definition
            laDcl.defs = List.from(defs);
        }
    }
}
      @StripMethods
public class Test {
    // the first member is the default constructor
    static {
    }
    
    static final int FieldToRemove = 0;
        
    @Test
    public void test() {
        int variableToRemove = FieldToRemove; 
    }
}

ошибка результата, вызванная удалением члена:

      Test.java:10: error: cannot find symbol
        int variableToRemove = FieldToRemove;
                               ^
  symbol:   variable FieldToRemove
  location: class Test

Впереди еще долгий путь. Я опубликую код, когда он будет готов.


Сделанный. см. https://github.com/KnIfER/Metaline

Использование Exmaple, удаление NightMode из androidx / appcompat:

        @StripMethods(key="Night")
  public class AppCompatActivity
  ...
  @StripMethods(key="Night")
  public abstract class AppCompatDelegate
  ...
  @StripMethods(key="Night")
  class AppCompatDelegateImpl 
  ...
Другие вопросы по тегам