2017-08-25 6 views
1

Considérons l'exemple complet suivant d'une classe de style Builder.IntelliJ Structural Search ne remplace pas tous les appels de méthode dans une interface en chaîne/fluide

package com.derp; 

class MyBuilder { 

    public MyBuilder set(String key, Object val) { 
     return this; 
    } 

    public MyBuilder setFoo(Object val) { 
     return this; 
    } 

    public MyBuilder setBar(Object val) { 
     return this; 
    } 

    public MyBuilder setBaz(Object val) { 
     return this; 
    } 
} 

public class Main { 

    public static void main(String[] args) { 
     // ** Example 1 
     MyBuilder a = new MyBuilder(); 
     a.set("foo", 1); 
     a.set("bar", 2); 
     a.set("baz", 3); 

     // ** Example 2 
     MyBuilder b = new MyBuilder() 
       .set("foo", 1) 
       .set("bar", 2) 
       .set("baz", 3); 
    } 
} 

Utilisation de la recherche structurelle de IntelliJ Je voudrais factoriser invocations de méthode de la forme set("foo", value)-setFoo(value) partout où elle est invoquée sur une certaine classe/interface, pour tous les littéraux de chaîne (pas seulement « foo »).

Cela ne fonctionne que très légèrement avec une chaîne d'appels de méthode (AKA, une interface "fluide"), dans laquelle la méthode set() en question renvoie this.

Dans la principale méthode ci-dessus, ce que j'ai étiquetée comme Exemple 1 obtient correctement remaniée avec, mais Exemple 2 se termine comme ça, ce qui est utile:

MyBuilder b = new MyBuilder() 
    .set("foo", 1) 
    .set("bar", 2).setBaz(3); 

J'ai besoin set("foo", 1) et set("bar", 2) à mettre à jour ici aussi.


peut gérer IntelliJ ce cas d'utilisation?

Ci-dessous se trouvent les détails des options que j'ai passées dans Structural Search and Replace. J'ai essayé de peaufiner les options autour de "nombre d'occurrences" mais malheureusement je n'ai pas trouvé d'option qui fonctionne. Voici les détails du modèle.

modèle de recherche: $Builder$.set($Key$, $Val$)

modèle de remplacement: $Builder$.set$Name$($Val$)

Variables:

$Builder$ Type d'expression (regexp): com\.derp\.MyBuilder

$Key$ Type d'expression (regexp): java\.lang\.String

$Name$ texte Script: Key.getText().replace("\"", "").capitalize()

+0

S'il vous plaît suivez ce numéro https://youtrack.jetbrains.com/issue/IDEA-178110 – Andrey

Répondre

0

Ceci est une limitation de recherche structurelle & Remplacer, et il est impossible à l'heure actuelle. Ce que vous pouvez faire est d'appeler Remplacer plusieurs fois. Chaque fois qu'une instance de la chaîne sera trouvée. Vous devrez continuer à le faire jusqu'à ce qu'il n'y ait plus d'instances.

Ou légèrement plus pratique, vous pouvez créer une inspection de recherche structurelle à partir de vos modèles. Cela trouvera toutes les instances. Mais vous devrez invoquer le correctif rapide sur chaque instance de la chaîne séparément ou cela ne fonctionnera pas.

Vous souhaiterez peut-être soumettre un bug report à ce problème.

+0

Merci pour la réponse rapide.Avez-vous des pointeurs ou de la documentation sur la façon dont je pourrais exécuter une recherche structurelle de manière «sans tête», c'est-à-dire une version scriptable à partir d'une ligne de commande? Il n'est pas possible pour moi de l'exécuter manuellement 100 fois avec l'interface graphique jusqu'à ce qu'elle cesse de changer. Depuis, j'ai improvisé un outil pour aider mon refactor basé sur une représentation AST différente, mais ce ne sera certainement pas la dernière fois que je dois faire de grands refacteurs. À l'avenir, je considérerais le clonage de la source IntelliJ et je corrigerais mon IDE pour ce genre de choses, donc tout document que vous avez serait le bienvenu :) – wsanville