Как расширения разметки WPF вызывают ошибки компиляции? - PullRequest
4 голосов
/ 09 ноября 2009

Некоторые расширения разметки вызывают ошибки компиляции. Например, StaticExtension (x: Static) вызывает ошибку компиляции, если указанный класс не найден. Кто-нибудь знает механизм для этого? Он встроен в компилятор XAML или такая функциональность недоступна для пользовательских расширений разметки?

РЕДАКТИРОВАТЬ: mfeingold ниже предположил, что мне нужно посмотреть в интерфейс IVsErrorList, но я не могу сразу увидеть, как это могло бы помочь кому-то добавить расширение разметки, которое генерирует ошибку во время компиляции. Есть примеры?

Ответы [ 2 ]

6 голосов
/ 09 ноября 2009

Расширение процесса компиляции BAML для регистрации дополнительных ошибок

Я столкнулся с такой же проблемой в прошлом году. Я писал свое собственное расширение, для которого я хотел ошибки во время компиляции в определенных сценариях, и обнаружил, что просто генерировать исключение из ProvideValue не работает, потому что ProvideValue не вызывается, пока XAML фактически не загружен и дерево объектов создан.

Я провел несколько экспериментов и обнаружил, что сообщение об ошибке компилятора для x:Static является побочным продуктом оптимизации, выполняемой компилятором BAML. Формат BAML фактически имеет концепцию определенного члена определенного типа, поэтому, когда XAML содержит x:Static, компилятор фактически заменяет его специальной записью, которая напрямую ссылается на член, а не содержит имя типа и метода. Это достигается путем явного распознавания класса StaticExtension. TypeExtension имеет аналогичную оптимизацию.

Я искал хуки, которые позволили бы мне вызывать собственный код во время компиляции BAML, но я не нашел ни одного. Компиляция BAML - это в основном прямая транслитерация в двоичный формат, соответствующий XAML, с несколькими конкретными оптимизациями, но в основном игнорирующим то, что он видит.

Я закончил тем, что добавил дополнительный шаг в процесс сборки, моделируя мой код из Microsoft.WinFX.targets и других встроенных целевых файлов. Этот шаг сканирует XAML для моего расширения разметки, проверяет параметры и генерирует ошибку компиляции, если они не верны. Это делается полностью независимо от перевода на BAML. Когда все было сказано и сделано, потребовалась дополнительная работа в течение пары дней, но я многому научился.

Предостережение о создании собственного файла .targets

Если вы думаете о добавлении собственного файла .targets, вы должны знать, что, если вы не включите цель в раздел реестра SafeImports локального компьютера, Visual Studio и Expression Blend будут жаловаться на любой проект, в который входит ваш. файл целей. Этот ключ требует доступа администратора на компьютере для обновления. Это может или не может быть проблемой в зависимости от вашего сценария развертывания. (Например, установка MSI на компьютере могла бы исправить это, или вы могли бы вручную установить ключ, если у вас есть только несколько машин для разработки). В моем случае это не имело значения, так как мне уже был нужен специальный файл .targets для некоторых других вещей, которые я делал в этом проекте.

Ошибка регистрации из задачи сборки

Вам не нужен IVsErrorList для добавления ошибок в Visual Studio во время сборки (и если бы вы это сделали, вы бы не поддерживали сборки командной строки, Expression Blend и другие инструменты).

Все, что вам нужно сделать, это вызвать Log.LogErrror Log.LogWarning изнутри вашей задачи сборки, например:

public class CheckForErrorsInMyMarkupExtension : Task
{
  ... parameters here ...

  public override Execute()
  {
    ... code to load XAML and scan it for markup extension errors ...
    ... when you discover an error ...
      Log.LogError("I saw an error");
  }
}
0 голосов
/ 09 ноября 2009

Существует несколько API интеграции VisualStudio, которые позволяют создавать собственные диагностические сообщения из расширения MEF (только VS2010), пакета VSIntegration или надстройки.

проверить интерфейс IVsErrorList , а также OutputTaskItemString метод интерфейса IVsOutputWindowPane. Последнее - то, что я использовал в моем редакторе django.

Вызовы этих методов, конечно, запекаются в компиляторе XAML - как они могут не быть, они основаны на результатах синтаксического анализа XAML

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...