Я создаю набор диагностических кодов с использованием Roslyn (в VS2015 Preview). В идеале, я бы хотел, чтобы любые ошибки, которые они производят, действовали как постоянные ошибки, так же, как если бы я нарушал нормальное языковое правило.
Есть множество вариантов, но мне трудно заставить любой из них работать последовательно. Мне удалось реализовать элементарное синтаксическое действие node, т.е. Зарегистрированное в
context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression);
в методе Initialize
моего диагностического класса. И вот, когда я открываю файл, который нарушает эту диагностику (при запуске проекта VSIX), VS2015 показывает ошибку:
- Красная кривая под правом битом кода
- Красный блок в поле
- Ошибка в списке ошибок
Однако при закрытии файла ошибка исчезает.
Я попытался использовать context.RegisterCompilationEndAction
, но это имеет две проблемы:
- Кажется, огонь непоследовательно. Обычно, когда я открываю решение, оно срабатывает, но не всегда. Он не срабатывает при чистом/восстановлении, что кажется странным.
-
Хотя диагностика, созданная непосредственно в методе метода анализа, для реализации диагностики я использую посетителя, например, это может быть неуместным:
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); } } }
Я знаю, что диагностика создается - точка останова в строке
ReportDiagnostic
попадает несколько раз, но я не вижу ничего в списке ошибок. (В то время как аналогичный вызовReportDiagnostic
в начале метода или один для дерева синтаксиса с указанием пути к файлу отображается.)
Что я здесь делаю неправильно? Первый подход (синтаксис node action) был бы идеальным, если это осуществимо - он дает мне именно тот контекст, в котором я нуждаюсь. Есть ли какой-либо параметр в свойствах проекта, который мне нужно сделать, чтобы компилятор использовал это для компиляции "полного проекта", а также просто интерактивную обработку "в среде IDE"? Возможно, это всего лишь часть интеграции Roslyn, которая еще не закончена?
(Я мог бы включить полный код для класса, если бы это было полезно - в этом случае я подозреваю, что это будет больше шума, чем сигнал.)