Complex Structural Search and Replace

Answered

Good morning,

I am in the process of migrating some code from using an instance method to using a static helper method within our test suites.  The instance method is the terminal method at the end of a potentially long chain of fluent methods.  I've been using the following template and it's been working pretty well where $statements$ is set to 1/unlimited and with the expression type regex:

Search template:

$type$ $ret$ = $statements$.get();

Replace template:


$type$ $ret$ = Helper.get($statements$);

But the static helper method declares a different set of checked exceptions than the instance method did and I'm struggling to figure out how I can use SSR to also correct all of the affected test methods so that they also declare the same checked exceptions to permit the exceptions to bubble out of the tests.  The test methods follow a variation on the following theme:

@Test
public void testSomething() throws InterruptedException, ExecutionException, FooException {
    DoStuff();
    String result = Helper.getClient().fluent1(x, y).fluent2(z).fluent3(new Foo()).get();
    assertThat(expected, result);
}

Is there a good way using SSR to identify a method based on a specific method call within that method and then be able to affect the signature while leaving all of the contents intact?

I've tried the following template, with $method$ set to 1/unlimited and as the target, $exceptions$ set to 1/unlimited, $statements1$ and $statements2$ set to 0/unlimited and $statements$ set to 1/unlimited with the type expression regex again, but it finds barely any of the methods in question.

search template:

class $class$ {
    @Test
    public void $method$() throws $exceptions$ {
        $statements1$;
        $type$ $ret$ = Helper.get($statements$);
        $statements2$;
    }
}

I'm kind of on the verge of just trudging through this manually but there are over a thousand of these test methods across a number of projects and that would be very tedious.  Not to mention I'd really like to learn if/how SSR can be utilized to solve problems like this.

0
3 comments
Official comment

Could be just a mistake in your post here, but your search template searches for `Helper.get()` while the example method uses `Helper.getClient()'. Other than that I don't see anything obviously wrong with your query. You could try searching without the surrounding class and $method$ set to 1/1 and see if that makes difference: 

@Test
public void $method$() throws $exceptions$ {
    $statements1$;
    $type$ $ret$ = Helper.get($statements$);
    $statements2$;
}
Avatar
Permanently deleted user

Sorry, yeah, that's a mistake in the post.  I was using the wrapping class declaration because without it no methods would be found at all.

@Test
public void $Method$() throws $Exceptions$ {
$statements1$;
$Type$ $Ret$ = PromiseFactory.await($args$);
$statements2$;
}

$Method$ - 1/1

$Exceptions$ - 1/unlimited

$statements1$ - 0/unlimited

$Type$ = 1/1

$Ret$ = 1/1

$args$ = 1/unlimited

$statements$ = 0/unlimited

 

So to ask this a bit more generically, is there a recommended type of pattern in SSR for identifying methods that happen to at some point call a static method?  I don't want to keep hacking at this particular pattern if there is a better way to do it in general.

0

The pattern you have constructed is the recommended way to do this. And from the information you have provided I don't see why it doesn't work for you. Could you perhaps create some self contained/compiling example code or small project? That has an example of the method you are trying to find but for which the query does't work? Also which version of IntelliJ IDEA do you use?

0

Please sign in to leave a comment.