2014-12-08 12 views
69

Buduję zestaw diagnostyki kodu za pomocą Roslyn (w VS2015 Preview). Idealnie byłoby, gdyby wszelkie błędy, które generują, działałyby jak trwałe błędy, tak jakbym łamał normalną zasadę języka.W jaki sposób można wykonać działanie węzła składni diagnostycznej kodu dla zamkniętych plików?

Istnieje kilka opcji, ale ciężko jest mi sprawić, aby któryś z nich działał konsekwentnie. Udało mi się wdrożyć działania węzła podstawową składnię, to znaczy jeden zarejestrowany

context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression); 

w metodzie diagnostycznej Initialize mojej klasie. I oto, kiedy otworzy się plik, który narusza ten diagnostyczny (podczas uruchamiania projektu VSIX), VS2015 pokazuje błąd:

  • Red squiggle pod prawym kawałka kodu
  • czerwony blok na marginesie
  • Błąd na liście błędów

Jednak błąd zniknie po zamknięciu pliku.

Próbowałem za pomocą context.RegisterCompilationEndAction jak dobrze, ale to ma dwa problemy:

  • Wydaje niekonsekwentnie ogień. Zwykle po otwarciu rozwiązania odpala, ale nie zawsze. Nie strzela na czystym/przebudowanym, co wydaje się dziwne.
  • Chociaż diagnostyka stworzony bezpośrednio w ogniu metoda analizy, w celu wykonania diagnostyki używam gościa, jak ta - która może być nieudany:

    private static void AnalyzeEndCompilation(CompilationEndAnalysisContext context) 
    { 
        foreach (var tree in context.Compilation.SyntaxTrees) 
        { 
         var visitor = new ReportingVisitor(context.Compilation.GetSemanticModel(tree)); 
         visitor.Visit(tree.GetRoot()); 
         foreach (var diagnostic in visitor.Diagnostics) 
         { 
          context.ReportDiagnostic(diagnostic); 
         } 
        } 
    } 
    

    wiem, że diagnostyka są jest tworzony - punkt przerwania na linii ReportDiagnostic jest uderzany kilka razy - ale nie widzę niczego na liście błędów. (Podczas gdy podobny ReportDiagnostic wezwanie na początku metody, albo jeden na drzewo składni ze ścieżką pliku, robi się widoczne.)

Co robię źle tutaj? Pierwsze podejście (działanie węzła składni) byłoby idealne, gdyby było wykonalne - daje mi dokładnie ten kontekst, którego potrzebuję. Czy istnieje pewne ustawienie we właściwościach projektu, którego potrzebuję, aby kompilator użył go do kompilacji "pełnego projektu", a także po prostu interaktywnego "w obsłudze IDE"? Czy to może tylko odrobina integracji z Roslyn, która nie jest jeszcze ukończona?

(mogę zawierać pełny kod dla klasy czy byłoby użyteczne. - w tym przypadku podejrzewam, że byłoby więcej hałasu niż sygnału chociaż)

+1

Z tego co zrozumiałem na wykładzie 'RegisterCompilationEndAction' jest rzeczywiście tym, czego potrzebujesz, a to, że odpala niekonsekwentnie jest błędem. Wyślę e-mail do głośnika i zapytam. –

Odpowiedz

43

Dla zamkniętych spraw plików, to naszym zamiarem, aby wszystkie diagnostyka zostanie zgłoszona z otwartych lub zamkniętych plików. Dostępna jest opcja użytkownika w podglądzie w menu Narzędzia \ Opcje \ Edytor tekstu \ C# \ Zaawansowane, który można przełączyć, aby uwzględnić diagnostykę w zamkniętych plikach. Mamy nadzieję, że stanie się to domyślne przed wydaniem VS 2015. Należy jednak zauważyć, że opcja ma zastosowanie tylko do analizy w ramach VS. Jeśli analizator zostanie przekazany do kompilatora (przez dodanie analizatora w programie Solution Explorer lub dodanie odwołania do pakietu NuGet do pakietu za pomocą analizatora, w przeciwieństwie do instalowania VSIX w Visual Studio), wówczas kompilator zgłosi wszystkie diagnostykę kiedy użytkownik buduje, niezależnie od tego, czy pliki są otwarte, czy nie.

Dla drugiego numeru z RegisterCompilationEndedAnalyzer, nie jest on prawidłowo wywoływany w programie Visual Studio w podglądzie VS 2015. Dzieje się tak dlatego, że dokonujemy pewnych optymalizacji, aby uniknąć ponownej analizy wszystkiego dla "lokalnych" zmian wewnątrz ciał metod. Z podobnych przyczyn obecnie nie zgłaszamy błędów zgłaszanych w lokalizacjach w obiektach metody. Niedawno zmieniliśmy to tak, że VS rozpocznie ponowną analizę po dłuższym opóźnieniu, więc RegisterCompilationEndedAnalyzer powinno być wywoływane niezawodnie w przyszłych kompilacjach, a my będziemy zgłaszać błędy niezależnie od lokalizacji.

Jednak w twoim przypadku prawidłową rzeczą jest pozostanie przy użyciu narzędzia SyntaxNodeAnalyzer, przełączenie opcji VS w celu włączenia diagnostyki w zamkniętych plikach i dołączenie diagnostyki do opcji kompilacji projektu.

Mam nadzieję, że to pomoże!

+2

Aha - część lokalizacji na pewno wyjaśniłaby dziwności, które widziałem. Moja diagnostyka "tylko sprawdziła, że ​​mogę dostać coś działającego" nie miała lokalizacji, więc te pojawiły się ... a opcja diagnostyki w zamkniętych plikach działała idealnie. Dzięki! Wracając do tego, aby teraz sama diagnostyka zrobiła się dobrze :) –

+0

Czy zauważyłeś notatkę na temat korzystania z dołączonej do projektu diagnostyki, aby wprowadzić ją również do wersji wiersza poleceń? –

+0

Tak. Dopóki jestem na dobrej drodze do zrobienia tego później, mogę na razie zrobić pauzę :) –

Powiązane problemy