2016-06-15 8 views
0

Я пытаюсь сопоставить такие вызовы методов некоторого свободного API. Может быть произвольное количество вызовов метода (минимум 2 вызова, но не верхний предел). Все выражение должно быть сопоставлено. На самом деле, цель состоит в том, чтобы найти вызовы с цепными вызовами в беглой api, которые пропускают doIt(), так как в этом случае свободный API ничего не делает.Согласование вызовов цепных методов со структурным поиском

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

Я пытался что-то вроде

FooClass.$a$($b$) 

и использовать различные "встречаемости отсчеты" как 0,∞ для $a$ и 0,1 для $b$, но это по-прежнему соответствует только FooClass.some("fluent")

ответ

1

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

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

Нажмите Изменить переменные:

  1. набором Expression type из Instance к FooClass
  2. множества Text/Regexp от MethodCall до doit и активировать Invert condition
+0

методы API не возвращать экземпляры 'FooClass', но мне кажется, что все еще можно использовать тип выражения сопоставления нескольких классов' (FooClass | BarClass) ', как я опубликует в ответ – user140547

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. Matching статический метод FooClass.bar(). Нет перевернутый doIt условие не требуется

    FooClass.$MethodCall$($Parameter$);

  2. Соответствующие промежуточные классы FooClass, BarClass. Нет перевернутый doIt условие не требуется

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

    Выражение типа экземпляра является (FooClass|BarClass)

  3. Соответствующие классы Bar2Class, FinalClass. Различие заключается в том, что можно сделать допустимое выражение, добавив doIt() к выражению. Вероятно, это работает только тогда, когда есть только один последний звонок.

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

    Выражение тип экземпляра является (Bar2Class|FinalClass) Здесь с использованием инвертированного ограничения на вызов метода doIt

    Шаблон замены $Instance$.$MethodCall$($Parameter$).doIt();

Эти структурные схемы поиска может затем также могут использоваться в качестве инспекций в 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 

 Смежные вопросы

  • Нет связанных вопросов^_^