Slides
Transcrição
Slides
Compiladores como Serviço Hoje: Garantia de Códigos mais Limpos, Rápidos e Leves Elemar Jr @elemarjr linkedin.com/in/elemarjr Disclaimer Como vemos compiladores hoje Compilador Como vemos compiladores hoje Código Compilador Como vemos compiladores hoje Código Compilador Como vemos compiladores hoje Código Compilador Executável Como vemos compiladores hoje Código Compilador Executável Como vemos compiladores hoje Código Compilador Executável Como vemos compiladores hoje Código Compilador Executável Como vemos compiladores hoje IntelliSense Refactoring Go To Definition Código Compilador Executável Code Analysis Find All References Metrics Como vemos compiladores hoje IntelliSense Refactoring Go To Definition Código Compilador Executável Code Analysis Find All References Metrics Uma visão mais “madura” E se existisse uma API? E se a IDE consumisse essa API? E se a IDE consumisse essa API? Hello World! Obtendo a árvore sintática var script = @"using System; using System.Collections.Generic; using System.Text; public static class Program { public static void Main() { Console.WriteLine(""Hello World""); } }"; // Parse the script to a SyntaxTree var syntaxTree = CSharpSyntaxTree.ParseText(script); Gerando a compilação // Parse the script to a SyntaxTree var syntaxTree = CSharpSyntaxTree.ParseText(script); // Compile the SyntaxTree to a CSharpCompilation var compilation = CSharpCompilation.Create("Script", new[] { syntaxTree }, defaultReferences.Select(x => MetadataReference.CreateFromFile(Path.Combine(assemblyPath, x))), new CSharpCompilationOptions(OutputKind.ConsoleApplication)); Saída e execução using (var outputStream = new MemoryStream()) using (var pdbStream = new MemoryStream()) { // Emit assembly to streams. var result = compilation.Emit(outputStream, pdbStream: pdbStream); if (!result.Success) { return; } // Load the emitted assembly. var assembly = Assembly.Load(outputStream.ToArray(), pdbStream.ToArray()); // Invoke the entry point. assembly.EntryPoint.Invoke(null, null); } Análise Sintática SyntaxTree tree = CSharpSyntaxTree.ParseText( @" using System; using System.Collections; using System.Linq; using System.Text; namespace HelloWorld { class Program { static void Main(string[] args) { Console.WriteLine(""Hello, World!""); } } }"); var var var var var var root = (CompilationUnitSyntax)tree.GetRoot(); firstMember = root.Members[0]; helloWorldDeclaration = (NamespaceDeclarationSyntax)firstMember; programDeclaration = (ClassDeclarationSyntax)helloWorldDeclaration.Members[0]; mainDeclaration = (MethodDeclarationSyntax)programDeclaration.Members[0]; argsParameter = mainDeclaration.ParameterList.Parameters[0]; Linq To Code 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(); Análise Semântica O que há no Namespace var var var var root = (CompilationUnitSyntax)syntaxTree.GetRoot(); model = compilation.GetSemanticModel(syntaxTree); nameInfo = model.GetSymbolInfo(root.Usings[0].Name); systemSymbol = (INamespaceSymbol)nameInfo.Symbol; foreach (var ns in systemSymbol.GetNamespaceMembers()) { Console.WriteLine(ns.Name); } O que há em uma String var helloWorldString = root.DescendantNodes() .OfType<LiteralExpressionSyntax>() .First(); var literalInfo = model.GetTypeInfo(helloWorldString); var stringTypeSymbol = (INamedTypeSymbol)literalInfo.Type; var stringMethodsNames = (from method in stringTypeSymbol.GetMembers().OfType<IMethodSymbol>() where method.ReturnType.Equals(stringTypeSymbol) && method.DeclaredAccessibility == Accessibility.Public select method.Name).Distinct(); foreach (var name in stringMethodsNames) { Console.WriteLine(name); } Transformações Transformação SyntaxTree tree = CSharpSyntaxTree.ParseText( @"using System; using System.Collections; using System.Linq; using System.Text; namespace HelloWorld { class Program { static void Main(string[] args) { Console.WriteLine(""Hello, World!""); } } }"); NameSyntax name = SyntaxFactory.IdentifierName("System"); name = SyntaxFactory.QualifiedName(name, SyntaxFactory.IdentifierName("Collections")); name = SyntaxFactory.QualifiedName(name, SyntaxFactory.IdentifierName("Generic")); var root = (CompilationUnitSyntax)tree.GetRoot(); var oldUsing = root.Usings[1]; var newUsing = oldUsing.WithName(name); root = root.ReplaceNode(oldUsing, newUsing); Expandindo o VS https://github.com/code-cracker/code-cracker https://github.com/dotnet/roslyn Obrigado!