ErrorProne.NET - Implementarea Extract Method

In ultimul articol ne-am uitat la situatiile in care ErrorProne.NET anunta procesarea incorecta a preconditiilor din iterator block si metode asynchronous. Analiza in sine nu este foarte dificila sau de mare interes dar repararea acestei implementari este interesanta.

Sep 5, 2016 1670
In ultimul articol ne-am uitat la situatiile in care ErrorProne.NET anunta procesarea incorecta a preconditiilor din iterator block si metode asynchronous. Analiza in sine nu este foarte dificila sau de mare interes dar repararea acestei implementari este interesanta.

Analyzer-ul defineste faptul ca metoda asynchronous contine o verificare de “argument” invalid si ofera o metoda prin care se poate rezolva aceasta situatie:

ErrorProne.NET. Part 4_1.jpg

Fiecare fixer trebuie sa stie ce mai exact repara. Pentru a face asta, trebuie sa luati informatia din clasa CodeFixProvider si sa treceti peste atributul FixableDiagnosticIds:

ErrorProne.NET. Part 4_2.jpg

Acum trebuie sa implementam metoda RegisterCodeFixesAsync pentru a inregistra actiunea necesara pentru reparare.

Aceasta metoda ia CodeFixContext ca parametru. Putem face acest lucru intr-un mod mai general:

ErrorProne.NET. Part 4_3.jpg

GetFirstNodeWithDiagnostic este metoda de extensie care poate fi folosita din nou:

ErrorProne.NET. Part 4_4.jpg

Apoi trebuie sa ne uitam la o situatie speciala a Extract Method pattern: luati o source method (FooAsync) si separati-o in doua – lasati precondition check in prima parte si transferati restul de cod fara preconditii in cea noua.

Mai detaliat solutia ar trebui sa arate asa:

1. Gasiti block-ul cu preconditiile in source method
2. Selectati metoda:

  • Clonati source method lasand doar semnatura sursei (noua metoda trebuie sa aiba aceeasi value type si acelasi set de parametri)
  • Transformati metoda intr-una inchisa
  • Stergeti preconditiile din noua metoda
  • Schimbati source method
  • Stergeti context keyword async din method declaration (metoda ofera in continuare Task sau Task<T> dar compiler-ul nu o va include in final automatic state).
3. Lasati check pe preconditiile in corpul metodei
4. Delegati catre metoda creata la punctul 2: return DoMethodAsync(args).

ErrorProne.NET. Part 4_5.jpg

In acest fragment sunt folosite cateva extension methods precum ParameterList.AsArguments() pentru a obtine argumente pentru method parameter list sau WithoutModifiers pentru a sterge modifiers din metoda. Sunt simple si pot fi gasite in cod la github dar nu sunt foarte mari si nu ar trebui sa afecteze intelegerea procesului din acest fragment. De asemenea nu mentionez codul sursa al PreconditionBlock class, care nu este complicat sau important.

Acum trebuie sa inregistram actiunea in context:

ErrorProne.NET. Part 4_6.jpg

Ultima etapa este simpla dar cruciala pentru a face update-ul atomic. Spre exemplu, urmatorul cod nu va functiona:

ErrorProne.NET. Part 4_7.jpg

In acest caz source method va fi inlocuit de cel actualizat dar metoda selectata nu va fi “pasted”. Asta deoarece InsertNoesAfter nu poate sa gaseasca o metoda actualizata in trunchiul actualizat.

Concluzie

Relativa usurime cu care se implementeaza method selection este legata de faptul ca avem o operatie simpla. Datorita caracterului imuabil al caracteristicilor Roslyn, orice metoda WithXXX cloneaza source tree node, care este un punct important de plecare pentru implementarea acestui tip de refactoring. Mai mult, in acest caz nu trebuie sa analizam ce variabile sunt localizate si daca trebuie transferate in noua metoda. Stim ca trebuie sa stergem preconditiile in noua metoda si sa le lasam in cea veche.

Acest tip de implementare nu ne protejeaza de provocari daca DoMethodName este deja prezenta in clasa dar eliminarea acestor provocari nu este dificila.

Sergey Teplyakov
Expert in .Net, С++ and Application Architecture

Daca iti place acest articol, distribuie-l si prietenilor tai!




Mai ai intrebari?
Contacteaza-ne.
Thank you.
Your request has been received.