2013-09-23 13 views
7

Ho un certo numero di eventi in una nuova base di codice dove ci sono una sequenza di chiamate di metodo come,analizzatori codice statico, rilevano modelli di codice

object o = something.foo(); 
bar(o); 
something.foobar(); 

in righe consecutive. Mi piacerebbe trovare/contare il numero totale di una tale sequenza nel mio codice in cui il nome dell'oggetto "qualcosa" potrebbe essere diverso, ma voglio essere trattato allo stesso modo.

Voglio estrarli come metodo e vedere tutte le posizioni in cui è necessario refactoring. Come faccio a fare qualcosa del genere?

+0

Non sono a conoscenza di alcuno strumento che possa eseguire questa operazione. Puoi scrivere (o estendere il plugin findbug esistente) per fare questo controllo: http://findbugs.sourceforge.net/ – Jayan

+0

Perché non cercare semplicemente il modello con un'espressione regolare nel tuo IDE? Dovresti darti il ​​conto e le posizioni ... – assylias

+0

@assylias Regexes potrebbe funzionare, ma penso che potrebbe essere davvero difficile. Inoltre potresti dover fare i conti con tutti i dettagli della sintassi, dove potrebbe esserci un cast da qualche parte o qualsiasi altra cosa. – SpaceTrucker

risposta

1

Si potrebbe utilizzare una regex - per esempio in Netbeans, questa espressione regolare:

(?s)object o = (.*?)\.foo\(\);\s+bar\(o\);\s+(\1)\.foobar\(\); 

trova tutte le linee piace:

object o = xyz.foo(); 
bar(o); 
xyz.foobar(); 

dove xyz può essere qualsiasi cosa, purché sia ​​lo stesso sul prima e ultima riga.

+0

Forse dovresti considerare linee vuote e righe di commento nella tua espressione regolare. – SpaceTrucker

+0

Le righe vuote di @ SpaceTrucker sono già state ignorate con tale regex. I commenti potrebbero infatti essere aggiunti se necessario. – assylias

+0

Per fare lo spazio bianco, è necessario inserire una serie di regex goo aggiuntive ovunque; allo stesso modo per i commenti. Questo diventa piuttosto peloso per motivi più complessi. E se ci sono espressioni di argomenti arbitrari all'interno delle parentesi dell'argomento del metodo (presumo che il caso di Op non sia esattamente quello che ha mostrato) l'espressione regolare ti farà fallire completamente perché non può ignorare in modo affidabile tali espressioni. –

2

Intellij IDEA (inclusa la versione gratuita della comunità) esegue la duplicazione del codice di identificazione &.

Se ritagliarsi uno di tale evento in un metodo che utilizza la sua funzione di refactoring, passa attraverso la base di codice e si chiede se si desidera sostituirlo in altri luoghi, anche.

1

Se il codice è Java 1.6 o inferiore, è possibile utilizzare Eclipse MoDisco per generare un'istanza EMF model dei progetti Java. Quindi puoi implementare uno Model Query per cercare il modello che descrivi. Anche se il modello MoDisco Java è basato su Java 1.5, è possibile utilizzarlo anche per 1.6, poiché non sono state introdotte modifiche alla sintassi in 1.6.

2

Esistono strumenti in grado di eseguire questa operazione e si chiamano program transformation tools.

Se si desidera veramente riconoscerli come linea consecutiva, con il nostro motore di trasformazione del programma DMS Software Reengineering Toolkit, utilizzando il suo RSL (Rule Specification Language). RSL consente di scrivere i modelli in termini di sintassi del linguaggio di un linguaggio la cui grammatica è già noto al DMS:

domain Java~v7; 

pattern odd_pattern(IDENTIFIER: o, 
        qualifier: something, 
        IDENTIFIER: foo 
        IDENTIFIER: bar, 
        IDENTIFIER: foobar, 
        more: stmt_sequence): stmt_sequence 
= " Object \o = \something.\foo; 
    \bar(\o); 
    \something.\foobar(); 
    \more"; 

Questo definisce un modello in termini di sintassi superficie della notazione designato ("dominio Java ~ v7"). Ogni modello ha un nome ("odd_pattern") in modo da poter distinguere tra molti modelli. Un modello ha una serie di sottotrammi specificati della categoria di sintassi forzata (clean grammar), denominati come < (non) terminale: nome>. Questo modello ha diversi identificatori distinti, nomi di modelli o, foo, bar, foobar. Immaginavo che volevi dire che qualcosa era una sorta di percorso di qualificazione, ma forse intendevi anche che fosse solo un identificatore.

I contenuti del modello sono definiti tra virgolette meta " per distinguere il testo RSL lingua pattern dalla lingua di destinazione (Java) il testo modello. All'interno delle citazioni meta, \ baz significa che il modello baz variabile della categoria sintassi N dove baz è stato definito come N:.. baz nella lista di parametri modello la variabile modello stesso che si verificano in più posti richiede sostituzioni identici

Dato questo modello, è possibile chiedere DMS dove è corrisponde a un (Java) AST.Corrispondendo a un AST, a tutti i problemi di spazio bianco, commenti, stringhe/identificatori/numeri/ecc. Non normalizzati. sono eliminati Contando semplicemente le corrispondenze, ottieni la metrica desiderata originale di OP. [Abbiamo in gran parte completato un'estensione ai pattern RSL in cui gli elementi sono collegati da flussi di dati anziché dalla sintassi del codice].

Presumibilmente vuole trasformare queste istanze in qualche altro codice, che egli può fare scrivendo, in RSL,

rule rewrite_odd_pattern(parms): stmt_sequence 
     odd_pattern(parms) -> replacement_pattern(parms); 

citare qualche altro "replacement_pattern" scritto in modo simile.

Se l'OP ha solo un numero modesto di tali pattern, è probabilmente meglio usare l'espressione regolare o semplicemente lo slugging piuttosto che ottenere DMS (o un altro strumento di trasformazione del programma) e configurarlo. Se lo fa molto, o sono disseminati su pile di codice molto grandi, gli schemi sono complessi, o ha molti tipi di cose simili da fare, il compromesso potrebbe rovesciarsi dall'altra parte.