BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Artigos Compiladores como Serviço: Garantia de Códigos mais Limpos, Rápidos e Leves

Compiladores como Serviço: Garantia de Códigos mais Limpos, Rápidos e Leves

Como os compiladores funcionam? Na carreira de um profissional de computação, poucas vezes precisamos nos preocupar com esta questão. Exceto em alguns nichos profissionais específicos, a grande maioria dos profissionais só reflete sobre esta questão durante alguns períodos na graduação.

Tradicionalmente, compiladores operam em um modelo de caixa-preta, ou seja, submetemos nosso código e o obtemos em forma executável. E em alguns cenários de exceção, recebemos uma relação de erros e alertas sobre aspectos que devemos tratar no nosso código.

Alguns compiladores são mais amigáveis ao seus usuários, por exemplo os compiladores para linguagem Java e C#, são muito eficazes em nos informar sobre os erros que cometemos. Outros compiladores são conhecidos pela ênfase na geração de um executável eficiente, mas oferecem pouca ajuda para os desenvolvedores (quem nunca ficou horas tentando interpretar o retorno de um compilador C++?).

Contudo, recentemente a Microsoft iniciou um movimento que poderá modificar profundamente a forma como nos relacionamos com compiladores. Trata-se do projeto Roslyn, uma nova plataforma de compiladores para .NET (atualmente suportando C# e Visual Basic). O Roslyn é totalmente open source (disponível no Github) e integrará o conjunto de ferramentas para desenvolvimento da plataforma.

O que torna o projeto Roslyn inovador é que, além do compilador, também é disponibilizada uma API que permite influenciar todo o processo de compilação - desde a análise sintática até a geração do código binário. Essa API servirá de base, por exemplo, para implementação de todas as ferramentas de interação com o código do Visual Studio; também poderá ser consumida para criação de ferramentas independentes.

Usos e Aplicações

Vamos considerar algumas possibilidades práticas da utilização da API do Roslyn. Há tempos se tem falado que métodos devem ter baixa complexidade. E se fosse possível que o compilador rejeitasse métodos com alta complexidade os considerando incorretos? E se isso acontecesse com um feedback rico no Visual Studio? Essa é apenas uma das muitas possibilidades desta nova tecnologia..

Observe o seguinte trecho de código:

var script = @"using System;
  public static class Program
  {
    public static void Main()
    {
      Console.WriteLine(""Hello World"");
    }
  }";
// Realiza parse do script transformando em uma SyntaxTree
var syntaxTree = CSharpSyntaxTree.ParseText(script);

Aqui é carregado uma pequena porção de código e submetida ao analisador sintático do compilador do C#, disponível através do Roslyn. O objetivo é obter a árvore sintática correspondente (ou uma lista de erros de sintaxe, caso existam).

Essa é absolutamente a mesma estratégia utilizada pelo plugin para Visual Studio, Syntax Tree Visualizer, também open source, para exploração do código fonte.

Mas, o que isso nos permite, afinal? Permite que façamos análise sintática dos nossos programas.

var root = (CompilationUnitSyntax)syntaxTree.GetRoot();
var firstMember = root.Members[0];
var helloWorldDeclaration = (NamespaceDeclarationSyntax)firstMember;
var programDeclaration = (ClassDeclarationSyntax)helloWorldDeclaration.Members[0];
var mainDeclaration = (MethodDeclarationSyntax)programDeclaration.Members[0];
var argsParameter = mainDeclaration.ParameterList.Parameters[0];
var declarations = root.DescendantNodes().OfType<MethodDeclarationSyntax>();
var firstParameters =
   from methodDeclaration in declarations
   where methodDeclaration.Identifier.ValueText == "Main"
   select methodDeclaration.ParameterList.Parameters.First();
   var argsParameter2 = firstParameters.Single();

Veja, a estrutura do nosso código está totalmente disponível através da árvore sintática. Podemos, inclusive fazermos consulta usando LINQ para o nosso código. É possível inspecionar detalhes como os nomes dos métodos, a quantidade de argumentos, os tipos desses argumentos, e assim por diante.

Com a árvore sintática carregada, podemos também executar análise de símbolos.

var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
var defaultReferences = new[] { "mscorlib.dll", "System.dll", "System.Core.dll" };
// Compila a  SyntaxTree para um  CSharpCompilation
var compilation = CSharpCompilation.Create("Script",
  syntaxTrees:  new[] { syntaxTree },
  references:  defaultReferences.Select(x =>    
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, x))),
  options:  new CSharpCompilationOptions(OutputKind.ConsoleApplication));

Essa análise de símbolos permite identificar, por exemplo, se um método privado é usado (logo, se precisa existir), ou se poderia ser removido com segurança. Permite também identificar todas as referências para um membro além de um "sem fim" de estratégias para extrair dados que possibilitam uma poderosa análise estática do código.

A geração da análise de símbolos também permite a geração de um assembly executável.

using (var outputStream = new MemoryStream())
using (var pdbStream = new MemoryStream())
{
  var result = compilation.Emit(outputStream, pdbStream: pdbStream);
  if (!result.Success)
  {
    return;
  }
  var assembly = Assembly.Load(outputStream.ToArray(), pdbStream.ToArray());
  assembly.EntryPoint.Invoke(null, null);
}

Ou seja, podemos "embutir" processos inteiros de compilação em nossas aplicações possibilitando estratégias de expansão sem precedentes.

Vimos que todo o poder do Roslyn pode ser consumido em todo o Visual Studio, e podemos desenvolver extensões para a IDE refinando nossa experiência de uso.

As lições deste artigo são derivadas da experiência e uso do Roslyn durante as minhas contribuições para o projeto Code Cracker, iniciativa da comunidade .net que pretende oferecer uma alternativa gratuita ao Resharper.


Sobre o autor

0bxH_due.jpeg

Elemar é Gerente de Pesquisa e Desenvolvimento na Promob. Na empresa há 16 anos. Desenvolve usando tecnologias Microsoft desde sua infância. Utiliza .net desde sua primeira versão. Em 2012, foi reconhecido como Microsoft MVP em C#. Especialista em computação gráfica, CAD e CAM.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT