Поделиться через


Работа с семантикой

Деревья синтаксиса представляют лексическую и синтаксическую структуру исходного кода. Хотя одной этой информации достаточно для описания всех объявлений и логики в источнике, ее недостаточно для определения того, на что указывает ссылка. Имя может представлять:

  • тип;
  • поле;
  • метод;
  • локальную переменную.

Хотя каждый из этих элементов имеет уникальные отличия, чтобы определить, на какой из них ссылается идентификатор, часто требуется хорошо разбираться в правилах языка.

В исходном коде представлены программные элементы, а программы также могут ссылаться на ранее скомпилированные библиотеки, упакованные в файлы сборки. Хотя исходный код, а, следовательно, и синтаксические узлы и деревья синтаксиса для сборок недоступны, программы по-прежнему могут ссылаться на элементы внутри них.

Для этих задач требуется семантическая модель.

Дополняя синтаксическую модель исходного кода, семантическая модель инкапсулирует правила языка, позволяя вам легко соотнести идентификаторы с программным элементом, на который указывает ссылка.

табличных переменных

Компиляция является представлением всего, что необходимо для компиляции программы C# или Visual Basic, куда входят все ссылки на сборки, параметры компилятора и исходные файлы.

Так как эти сведения находятся в одном месте, элементы, содержащиеся в исходном коде, можно описать более подробно. Компиляция представляет каждый объявленный тип, член или переменную в виде символа. Компиляция содержит различные методы, помогающие найти и соотнести символы, которые были объявлены в исходном коде или импортированы в виде метаданных из сборки.

Аналогично деревьям синтаксиса компиляции являются неизменяемыми. После создания компиляция не может быть изменена ни вами, ни другим человеком, совместно с которым вы ее используете. Однако вы можете создать компиляцию из существующей компиляции, указав при этом некоторое изменение. Например, можно создать компиляцию, которая во всем аналогична существующей компиляции, за исключением того, что она может включать дополнительный исходный файл или ссылку на сборку.

Символы

Символ представляет отдельный элемент, объявленный исходным кодом или импортированный из сборки в виде метаданных. Символом представлены все пространства имен, типы, методы, свойства, поля, события, параметры или локальные переменные.

Различные методы и свойства в типе Compilation помогают вам искать символы. Например, можно найти символ для объявленного типа по его общему имени метаданных. Можно также получить доступ к целой таблице символов в виде дерева, корнем которого является глобальное пространство имен.

Символы также содержат дополнительную информацию, которую компилятор определяет из источника или метаданных, например другие символы, на которые указывает ссылка. Каждый тип символа представлен отдельным интерфейсом, производным от ISymbol, а также имеет собственные методы и свойства, описывающие собранные компилятором сведения. Многие из этих свойств напрямую ссылаются на другие символы. Например, свойство IMethodSymbol.ReturnType сообщает вам фактический символ типа, который возвращает метод.

Символы представляют общее представление пространств имен, типов и членов между исходным кодом и метаданными. Например, метод, который был объявлен в исходном коде, и метод, который был импортирован из метаданных, оба представлены IMethodSymbol с одинаковыми свойствами.

По своей сути символы похожи на систему типов среды CLR, представленную API System.Reflection, однако их возможности шире, так как они моделируют не только типы. Пространства имен, локальные переменные и метки — все это символы. Кроме того, символы являются представлением концепций языка, а не концепций среды CLR. Есть много похожего, но имеется и большое количество значимых различий. Например, метод итератора в C# или Visual Basic является отдельным символом. Однако когда метод итератора преобразуется в метаданные среды CLR, он превращается в тип и несколько методов.

Семантическая модель

Семантическая модель представляет всю семантическую информацию для одного исходного файла. Ее можно использовать для обнаружения:

  • символов, на которые указывает ссылка в определенном месте в исходном коде;
  • результирующего типа выражения;
  • всех данных диагностики, относящихся к ошибкам и предупреждениям;
  • перемещений переменных в регионы исходного кода и из них;
  • ответов на более отвлеченные вопросы.