匹配链式方法调用与结构搜索

时间:2016-06-15 13:35:24

标签: intellij-idea fluent structural-search

我尝试匹配一些流畅的API的这种方法调用。可以有任意数量的方法调用(至少2次调用,但没有上限)。整个表达应该匹配。实际上,目标是在流畅的api中找到链式方法调用,省略doIt(),因为在这种情况下,流畅的API什么都不做。

FooClass.some("fluent")
        .api()
        .bar(()->"somelambda")
        .doIt();

我试过像

这样的东西
FooClass.$a$($b$) 

并使用不同的"出现次数"例如0,∞的{​​{1}}和$a$的{​​{1}},但这仍然只匹配0,1

2 个答案:

答案 0 :(得分:1)

假设所有流畅的api方法都返回FooClass的实例,则以下内容应该有效。 从现有模板方法调用开始,添加分号以搜索语句:

$Instance$.$MethodCall$($Parameter$);

单击编辑变量:

  1. Instance Expression type设置为FooClass
  2. MethodCall Text/Regexp设置为doit并启用Invert condition

答案 1 :(得分:1)

基于Bas Leijdekkers答案的解决方案,如果有人遇到类似的问题。

为示例使用这些类定义:

static class FooClass{

    static BarClass bar(){
       return new BarClass();
    }
}

static class BarClass{

     Bar2Class bar2(){
        return new Bar2Class();
    }

    BarClass self(){return this;}
}

static class Bar2Class{

    FinalClass bar3(){
        return new FinalClass();
    }
    Bar2Class self(){return this;}
}

static class FinalClass{
    void doIt(){
        System.out.println("bar2");
    }
    FinalClass doSomethingElse(){
        return this;
    }
}

我最终得到了两三个表达式:

  1. 匹配静态方法FooClass.bar()。不需要反转doIt条件

    FooClass.$MethodCall$($Parameter$);

  2. 匹配中间类FooClass,BarClass。不需要反转doIt条件

    $Instance$.$MethodCall$($Parameter$);

    实例的表达式类型为(FooClass|BarClass)

  3. 匹配课程Bar2ClassFinalClass。不同之处在于,可以通过向表达式添加doIt()来生成有效的表达式。这可能仅在最后一次通话时才有效。

    $Instance$.$MethodCall$($Parameter$);

    实例的表达式类型为(Bar2Class|FinalClass)  这里使用方法调用doIt

    上的反向约束

    替换模板是 $Instance$.$MethodCall$($Parameter$).doIt();

  4. 这些结构搜索模式也可以用作IntelliJ中的检查。

    测试用例:

        FooClass.bar().bar2();
    
        FooClass.bar();
    
        FooClass.bar().self().self().bar2();
    
        FooClass.bar().bar2().bar3(); // do it can be added
    
        FooClass.bar().bar2();
    
        FooClass.bar().self().bar2();
    
        FooClass.bar().bar2().bar3().doSomethingElse(); // do it can be added
    
    
        FooClass.bar().bar2().self().bar3().doSomethingElse(); // do it can be added
    
        FooClass.bar().bar2().bar3().doSomethingElse().doIt(); // all but this are invalid and found by the inspections