Trabalhar com semântica
As árvores de sintaxe representam a estrutura lexical e sintática do código-fonte. Embora esta informação por si só seja suficiente para descrever todas as declarações e lógica na fonte, não é informação suficiente para identificar o que está a ser referenciado. Um nome pode representar:
- um tipo
- um campo
- um método
- uma variável local
Embora cada um deles seja exclusivamente diferente, determinar a qual deles um identificador realmente se refere muitas vezes requer uma compreensão profunda das regras da linguagem.
Existem elementos de programa representados no código-fonte, e os programas também podem se referir a bibliotecas compiladas anteriormente, empacotadas em arquivos assembly. Embora nenhum código-fonte e, portanto, nenhum nó de sintaxe ou árvores, estejam disponíveis para assemblies, os programas ainda podem se referir a elementos dentro deles.
Para essas tarefas, você precisa do modelo semântico.
Além de um modelo sintático do código-fonte, um modelo semântico encapsula as regras de linguagem, oferecendo uma maneira fácil de combinar corretamente os identificadores com o elemento de programa correto que está sendo referenciado.
Compilação
Uma compilação é uma representação de tudo o que é necessário para compilar um programa C# ou Visual Basic, que inclui todas as referências de assembly, opções de compilador e arquivos de origem.
Como todas essas informações estão em um só lugar, os elementos contidos no código-fonte podem ser descritos com mais detalhes. A compilação representa cada tipo, membro ou variável declarado como um símbolo. A compilação contém uma variedade de métodos que ajudam você a localizar e relacionar os símbolos que foram declarados no código-fonte ou importados como metadados de um assembly.
Semelhante às árvores de sintaxe, as compilações são imutáveis. Depois de criar uma compilação, ela não pode ser alterada por você ou por qualquer outra pessoa com quem você possa compartilhá-la. No entanto, você pode criar uma nova compilação a partir de uma compilação existente, especificando uma alteração à medida que você faz isso. Por exemplo, você pode criar uma compilação que seja igual em todos os sentidos que uma compilação existente, exceto que ela pode incluir um arquivo de origem adicional ou referência de assembly.
Símbolos
Um símbolo representa um elemento distinto declarado pelo código-fonte ou importado de um assembly como metadados. Cada namespace, tipo, método, propriedade, campo, evento, parâmetro ou variável local é representado por um símbolo.
Uma variedade de métodos e propriedades no tipo ajudam a Compilation encontrar símbolos. Por exemplo, você pode encontrar um símbolo para um tipo declarado por seu nome de metadados comum. Você também pode acessar toda a tabela de símbolos como uma árvore de símbolos enraizada pelo namespace global.
Os símbolos também contêm informações adicionais que o compilador determina a partir da fonte ou metadados, como outros símbolos referenciados. Cada tipo de símbolo é representado por uma interface separada derivada de ISymbol, cada um com seus próprios métodos e propriedades detalhando as informações que o compilador reuniu. Muitas dessas propriedades fazem referência direta a outros símbolos. Por exemplo, a IMethodSymbol.ReturnType propriedade informa o símbolo de tipo real que o método retorna.
Os símbolos apresentam uma representação comum de namespaces, tipos e membros, entre o código-fonte e os metadados. Por exemplo, um método que foi declarado no código-fonte e um método que foi importado de metadados são ambos representados por um IMethodSymbol com as mesmas propriedades.
Os símbolos são semelhantes em conceito ao sistema de tipo CLR representado pela System.Reflection API, mas são mais ricos na medida em que modelam mais do que apenas tipos. Namespaces, variáveis locais e rótulos são todos símbolos. Além disso, os símbolos são uma representação de conceitos de linguagem, não conceitos CLR. Há muita sobreposição, mas também há muitas distinções significativas. Por exemplo, um método iterador em C# ou Visual Basic é um único símbolo. No entanto, quando o método iterador é traduzido para metadados CLR, é um tipo e vários métodos.
Modelo semântico
Um modelo semântico representa todas as informações semânticas de um único arquivo de origem. Você pode usá-lo para descobrir o seguinte:
- Os símbolos referenciados em um local específico na fonte.
- O tipo resultante de qualquer expressão.
- Todos os diagnósticos, que são erros e avisos.
- Como as variáveis entram e saem das regiões de origem.
- As respostas a perguntas mais especulativas.