#roslyn-code-analysis
#roslyn-code-analysis
Вопрос:
я пишу DiagnosticAnalyzer
и регистрирую SyntaxNode
действие SyntaxKind.Attribute
. Атрибут называет какой-либо другой файл в проекте.
Например, анализируемый код может включать
[RelatedFile("otherFileName.foo")]
interface Whatever {...}
В моем обратном вызове анализа я хочу иметь доступ к содержимому связанного файла с точки зрения анализируемого проекта. Итак, мне нужно:
- Извлеките имя файла из
SyntaxNode
. Я могу это сделать. - Получить объект, описывающий документ, содержащий анализируемый код. Я не знаю, как это сделать.
- Получить объект, описывающий проект, содержащий анализируемый код. Я не знаю, как это сделать.
- Узнайте, содержит ли проект документ с указанным именем. Я могу это сделать.
- Откройте и проанализируйте или обновите содержимое этого файла. Я думаю, что смогу это сделать.
Я застрял на шагах (2) и (3). (Да, возможно, мне не обязательно выполнять шаг 2, но я все равно хотел бы знать, как.)
Из SyntaxNodeAnalysisContext
параметра я могу получить Workspace
объект, а из него Solution
объект, а из него коллекцию Project
объектов. Но я не вижу способа связать конкретное SyntaxNode
обратно с Project
или Document
, из которого оно пришло.
Любые идеи о том, как это сделать, будут оценены.
Ответ №1:
Я его нашел:
Workspace workspace = ...;
SyntaxNode node = ...;
Document document = workspace.Solution.GetDocument(node.SyntaxTree);
Project project = document.Project;
Я не знаю, почему я не видел этого раньше.
Редактировать: теперь я знаю, почему я не видел его раньше. Получение Workspace
доступа к требует использования непубличного свойства AnalyzerOptions
.
Вы можете получить Workspace
от SyntaxNodeAnalysisContext
через…
SyntaxNodeAnalysisContext context = ...;
AnalyzerOptions options = context.Options;
Workspace workspace = (Workspace)
(options.GetType().GetRuntimeProperty("Workspace").GetValue(options));
Это не красиво, но это работает. Хотелось бы, чтобы был лучший способ.
Комментарии:
1. Джим, не мог бы ты объяснить, как ты получаешь рабочую область из syntaxnodeanalysisiscontext ?
2. Спасибо, Джим. Я не знаю, лучший ли это способ, но вы также можете получить рабочее пространство, как описано Джошем Варти . Если вы не находитесь в VSPackage, вы можете вызвать GetService с помощью ServiceProvider . GlobalProvider в Microsoft.VisualStudio. Оболочка. Для этого могут потребоваться ссылки, которые вы строго не должны использовать при анализе кода. В исправлении кода (но не в анализе кода) вы можете импортировать рабочую область как компонент MEF.