2016-03-05 10 views
7

Ho creato il sorgente Roslyn come described here.Passaggio del compilatore C# di Roslyn

vorrei aggiungere un punto di interruzione nel compilatore C# e scorrere la compliation di questo semplice programma:

using System; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var result = 1 + 2; 

      Console.WriteLine(result); 
     } 
    } 
} 

Dove devo impostare un punto di interruzione? Dovrebbe essere all'inizio del processo di compilazione come mi piacerebbe passare attraverso l'analisi e persino lexing.

Se si imposta CompilerExtension come progetto di avvio e si preme F5 (Avvia debug), viene lanciata una copia di Visual Studio con il compilatore appena compilato. Mi piacerebbe evitare di dover avviare una nuova istanza di Visual Studio ogni volta che mi piacerebbe passare attraverso il compilatore. Qual è un buon modo per impostare un piccolo programma che invochi direttamente il codice del compilatore sulla sorgente di cui sopra?

+5

È possibile aggiungere un nuovo progetto alla soluzione Roslyn, aggiungere riferimenti ai progetti Microsoft.CodeAnalysis corretti e quindi chiamare 'CSharpSyntaxTree.ParseText()' e 'Compilation.Emit()'. Quindi potresti passare attraverso il codice di analisi o di emissione che ti interessa. – JoshVarty

+0

Grazie Josh! Ho aggiunto una risposta che dimostra 'ParseText'. @JoshVarty – dharmatech

+1

Ho scritto un articolo sul blog in qualche modo basato su ciò che @JoshVarty suggerisce qui e in uno dei suoi articoli sul blog. Questo può essere di interesse per chiunque voglia giocare con gli interni di Roslyn. https://renniestechblog.com/information/33-modifying-roslyn-step-1-initial-test – RenniePet

risposta

5

Ecco un approccio come suggerito da Josh in un commento sopra.

  • Aggiungere un nuovo progetto "Console Application" alla soluzione Roslyn.

  • Aggiungere questi due riferimenti al progetto:

enter image description here

Un semplice programma per testare il parser:

using Microsoft.CodeAnalysis.CSharp; 

namespace TestCompiler 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var program_text = @" 

       using System; 

       namespace ConsoleApplication2 
       { 
        class Program 
        { 
         static void Main(string[] args) 
         { var result = 2 + 3; Console.WriteLine(result); } 
        } 
       } 
      "; 

      var result = CSharpSyntaxTree.ParseText(program_text); 
     } 
    } 
} 
  • Aggiungere un punto di interruzione alla linea che chiama ParseText.

  • "Avvia debug" e passa a quella riga per approfondire il parser.

Un semplice programma per testare il compilatore via Emit:

using System; 
using System.IO; 
using Microsoft.CodeAnalysis; 
using Microsoft.CodeAnalysis.CSharp; 

namespace TestCompiler 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var program_text = @" 

       using System; 

       namespace ConsoleApplication2 
       { 
        class Program 
        { 
         static void Main(string[] args) 
         { var result = 2 + 3; Console.WriteLine(result); } 
        } 
       } 
      "; 

      var syntax_tree = CSharpSyntaxTree.ParseText(program_text); 

      var compilation = CSharpCompilation.Create(
       Guid.NewGuid().ToString("D"), 
       new[] { syntax_tree }, 
       new[] { MetadataReference.CreateFromFile(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\mscorlib.dll") }); 

      var emit_result = compilation.Emit(new MemoryStream()); 
     } 
    } 
} 
+1

Per la versione corrente di Roslyn e Visual Studio 2017 è inoltre necessario aggiungere un riferimento al pacchetto NuGet per System.Reflection .Metadata, versione = 1.4.2. Fino a quando non ho stabilito che (e mi ci è voluto molto tempo) stavo ottenendo "L'applicazione è in modalità interruzione" e non è stata in grado di fare nulla. Ciò potrebbe essere dovuto a un bug in Visual Studio https://developercommunity.visualstudio.com/content/problem/104485/the-application-is-in-break-mode-1.html Che cosa ha fornito finalmente l'indizio sul vero problema è stato quando ho fatto doppio clic sul file .exe generato, quindi ho ricevuto un errore nella finestra della console. – RenniePet

2

Se si vuole avere un semplice programma che richiama il compilatore, basta considerare utilizzando csc come progetto di avvio. È possibile specificare gli argomenti da passare (come i file di origine) dalle impostazioni di debug sul progetto.

+0

Grazie Jason! Attualmente sto esplorando l'approccio menzionato da Josh in un commento sopra. Sembra che funzioni bene finora. Ho aggiunto una risposta che descrive questo approccio. – dharmatech

+0

Questo sembra un modo logico per testare il compilatore Roslyn sotto il debugger di Visual Studio. Ma ci sono così tanti argomenti possibili per csc.exe. Hai un link o un suggerimento su quali argomenti sono necessari e quali argomenti aggiuntivi potrebbero essere una buona idea da usare? – RenniePet

Problemi correlati