如何自动删除java代码中的方法

发布于 2024-12-11 08:07:22 字数 113 浏览 1 评论 0原文

我需要删除大型 java 项目中的一些方法,我想知道是否有工具可以帮助我做到这一点。我基本上会指定一个签名和一个源文件夹,其中所有匹配的方法都将被删除。

如果不存在这样的东西,那么我会写一个脚本。

I need to remove some methods in a large java project and I was wondering if there are tools that would help me do so. I would basically specify a signature and a source folder in which all the matching method would be removed.

It no such thing exists then I will write a script.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一人独醉 2024-12-18 08:07:22

今天,有几种方法可以实现这一目标。例如,您可以告诉 Eclipse 编译器为您提供 AST(请参阅 我的博客为例)。您可以导航 AST 以查找方法并删除节点以更改源。

这使得保持代码有效变得容易。使用 Eclipse 代码格式化程序,您可以随后清理格式。

MoDisCo 这样的项目更进一步,分析整个项目并为您提供搜索整个项目的方法。我刚刚发现 MoDisCo 的文档对于初学者来说并不是很有帮助。

Today, there are a couple of way to achieve this. For example, you can tell the Eclipse compiler to give you the AST (see my blog for an example). You can navigate the AST to find methods and remove nodes to change the source.

This makes it easy to keep the code valid. Using the Eclipse code formatter, you can clean up the formatting afterwards.

Projects like MoDisCo go one step further by analyzing a whole project and giving you ways to search the whole thing. I just found that the documentation for MoDisCo is not very helpful when you're a beginner.

宛菡 2024-12-18 08:07:22

如果您使用 eclipse 或其他功能强大的 IDE,您可能已经内置了对此的支持。
请参阅我无法使用 Eclipse 重构删除方法?寻找实现您想要的目标的方法。

If you use eclipse or other powerful IDE you may have built in support for doing this.
See I can't delete a method using eclipse refactoring? for a way to achieve what you want.

可爱咩 2024-12-18 08:07:22

您正在谈论“源转换”,Google 发现了 BeautyJ for Java 的存在:

http://beautyj。 berlios.de/

“BeautyJ 可以将 Java 源代码与 XML 相互转换。BeautyJ 引入了 XJava 格式,该格式将类或接口及其成员与关联的源代码和 Javadoc 注释一起存储在单个 XML 文件中。 BeautyJ开张了通过其 Sourclet API 或通过将 Java 源代码转换为 XML 并允许任何外部转换(例如通过应用 XSLT)来自动构建 Java 源代码的各种可能性。”

不知道您的情况是否如此很简单,不过,脚本比费力学习如何使用这样的程序要好。尽管出于其他目的将其放入您的工具链中也可能是值得的。

You're talking about a "source transformation", and Google turns up the existence of BeautyJ for Java:

http://beautyj.berlios.de/

"BeautyJ can convert Java source code to XML and back. BeautyJ introduces the XJava format which stores classes or interfaces and their members together with associated source code and Javadoc comments in a single XML file. BeautyJ opens up a wide range of possibilities for automatic structuring of Java source code either by its Sourclet API or by converting Java source code to XML and allowing any external transformations (for example by applying XSLT)."

No clue whether your case is so simple that a script would be better than going through the trouble of learning how to use such a program, though. Although it may be worthwhile to get it in your toolchain for other purposes as well.

君勿笑 2024-12-18 08:07:22

我们的 DMS 软件重组工具包及其 Java 前端 可用于此目的。

DMS 解析语言(使用其前端,在本例中为 Java),构建 AST 和符号表,并提供基于自定义分析操作 AST 的工具。在这种情况下,OP想要提供一个方法签名(大概有一个应该解释它的上下文,否则签名中使用的类型可能无法定义),在符号表中查找该签名,找到声明点( (在符号表中)作为 AST 节点,然后应用重写规则,用空声明替换该声明。

他可能希望对找到的方法进行分析,以确定该方法是否被使用。我们在符号表中也有这些信息。

Our DMS Software Reengineering Toolkit with its Java Front End could be used for this.

DMS parses languages (using its front ends, in this case Java), builds ASTs and symbol tables, and provide facilities to manipulate the ASTs based on custom analysis. In this case OP wants to provide a method signature (presumably with a context in which it should be interpreted because otherwise the types used in the signature might not be defined), look that signature up in the symbol table, find the point of declaration (this is in the symbol table) as a AST node, and then apply a rewriting rule that replaces the declaration with an empty declaration.

An analysis he may wish to perform on the found method is whether is it used or not. We have that information in the symbol table, too.

一梦浮鱼 2024-12-18 08:07:22

您可以使用 Java 中的某些东西来批量修改您的 Java 项目。诀窍是使用自定义注释处理器。使用注释处理器,您几乎可以修改所有内容。

例如,此库(用于 ecilipse 和 IDEA) 将一些 String 字段成员修改为它的 /**多行*/ 文档。

研究该库也使我能够修改方法体。

今天,我想删除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

示例用法,从 androidx/appcompat 中删除 NightMode:

  @StripMethods(key="Night")
  public class AppCompatActivity
  ...
  @StripMethods(key="Night")
  public abstract class AppCompatDelegate
  ...
  @StripMethods(key="Night")
  class AppCompatDelegateImpl 
  ...

You can use something in Java to batch-modify your Java project. The trick is to use a custom annotation processor. With annotation processor you can modify almost everything.

For an example, this library ( for ecilipse and IDEA ) modifies some String field members to it's /**multiline*/ docs.

Studying the library gives me the power to modify the method body as well.

Today, I want to strip out some unwanted methods in the android support library( used as editable local module ). I can manually remove them, but it would be hard to keep udpate after that.

So, instead of using script or mere-hand to modify the code directly, I decide to write another annotation processor which allow you to remove some class members.

For IDEA, the concept-proving code is very simple:

// 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; 
    }
}

the result error caused by the member removal:

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

Still a long way to go. I will publish the code when it's finished.


Done. see https://github.com/KnIfER/Metaline

Exmaple usage, removing NightMode from androidx/appcompat:

  @StripMethods(key="Night")
  public class AppCompatActivity
  ...
  @StripMethods(key="Night")
  public abstract class AppCompatDelegate
  ...
  @StripMethods(key="Night")
  class AppCompatDelegateImpl 
  ...
万人眼中万个我 2024-12-18 08:07:22

我寻找快速解决方案,但没有找到任何解决方案,我使用不同的工具来实现:

  1. grep 查找包含我想要的主要方法的所有文件
    删除
  2. 这些文件中的查找/替换,使这些方法成为私有
  3. Eclipse 清理,只需一条规则:删除未使用的
    私有方法

它完成了这项工作,但删除了其他未使用的私有方法,带来了轻微的副作用。在该项目的上下文中这并不是什么大问题,因为几乎所有文件之前都是通过保存操作删除未使用的私有方法来保存的。

感谢大家的意见,以后可能会用到。

I looked for quick solutions and did not find any, I used different tools to get there:

  1. grep to find all the files containing the main methods I wanted
    to remove
  2. find/replace in these files to make those methods private
  3. Eclipse clean-up with just one rule: remove unused
    private methods

It did the job with the minor side effect of removing other unused private methods. It is not a big deal in the context of that project since pretty much all the files were previously saved with a save action removing unused private methods.

Thanks all for the input, it may be applicable later on.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文