示例#1
0
        static void FieldNameAnalyzerTest()
        {
            //
            // Construct a syntax tree and a compilation.
            //

            var tree = CSharpSyntaxTree.ParseText(@"
class Person
{
    private int _age;
}");

            var mscorlib = new MetadataFileReference(typeof(object).Assembly.Location);

            var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

            var comp = CSharpCompilation.Create("Demo")
                       .AddSyntaxTrees(tree)
                       .AddReferences(mscorlib)
                       .WithOptions(options);


            //
            // Get diagnostics.
            //

            var diags = AnalyzerDriver.GetDiagnostics(comp, new[] { new FieldNameAnalyzer() }, null, CancellationToken.None);

            foreach (var diag in diags)
            {
                Console.WriteLine(diag);
            }
        }
示例#2
0
        static void ConfigureAwaitAnalyzerTest()
        {
            //
            // Construct a syntax tree and a compilation.
            //

            var tree = CSharpSyntaxTree.ParseText(@"
using System.Threading.Tasks;

class Foo
{
    async Task Bar(Task t)
    {
        await t;
    }

    async Task<int> Baz(Task<int> t)
    {
        return await t;
    }

    async Task Qux(Task t)
    {
        await t.ConfigureAwait(false);
    }
}");

            var mscorlib = new MetadataFileReference(typeof(object).Assembly.Location);

            var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

            var comp = CSharpCompilation.Create("Demo")
                       .AddSyntaxTrees(tree)
                       .AddReferences(mscorlib)
                       .WithOptions(options);


            //
            // Get diagnostics.
            //

            var diags = AnalyzerDriver.GetDiagnostics(comp, new[] { new ConfigureAwaitAnalyzer() }, null, CancellationToken.None);

            foreach (var diag in diags)
            {
                Console.WriteLine(diag);
            }
        }
        /// <summary>
        /// Given an analyzer and a document to apply it to, run the analyzer and gather an array of diagnostics found in it.
        /// The returned diagnostics are then ordered by location in the source document.
        /// </summary>
        /// <param name="analyzer">The analyzer to run on the documents</param>
        /// <param name="documents">The Documents that the analyzer will be run on</param>
        /// <param name="spans">Optional TextSpan indicating where a Diagnostic will be found</param>
        /// <returns>An IEnumerable of Diagnostics that surfaced in teh source code, sorted by Location</returns>
        protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(IDiagnosticAnalyzer analyzer, Document[] documents)
        {
            var projects = new HashSet <Project>();

            foreach (var document in documents)
            {
                projects.Add(document.Project);
            }

            var diagnostics = new List <Diagnostic>();

            foreach (var project in projects)
            {
                var compilation = project.GetCompilationAsync().Result;
                var diags       = AnalyzerDriver.GetDiagnostics(compilation, new[] { analyzer }, null, CancellationToken.None);
                foreach (var diag in diags)
                {
                    if (diag.Location == Location.None || diag.Location.IsInMetadata)
                    {
                        diagnostics.Add(diag);
                    }
                    else
                    {
                        for (int i = 0; i < documents.Length; i++)
                        {
                            var document = documents[i];
                            var tree     = document.GetSyntaxTreeAsync().Result;
                            if (tree == diag.Location.SourceTree)
                            {
                                diagnostics.Add(diag);
                            }
                        }
                    }
                }
            }

            var results = SortDiagnostics(diagnostics);

            diagnostics.Clear();
            return(results);
        }
示例#4
0
        /// <summary>
        /// csc.exe and vbc.exe entry point.
        /// </summary>
        public virtual int Run(TextWriter consoleOutput, CancellationToken cancellationToken)
        {
            Debug.Assert(!Arguments.IsInteractive);

            cancellationToken.ThrowIfCancellationRequested();

            if (Arguments.DisplayLogo)
            {
                PrintLogo(consoleOutput);
            }

            if (Arguments.DisplayHelp)
            {
                PrintHelp(consoleOutput);
                return(Succeeded);
            }

            if (PrintErrors(Arguments.Errors, consoleOutput))
            {
                return(Failed);
            }

            var touchedFilesLogger = (Arguments.TouchedFilesPath != null) ? new TouchedFileLogger() : null;

            Compilation compilation = CreateCompilation(consoleOutput, touchedFilesLogger);

            if (compilation == null)
            {
                return(Failed);
            }

            var diagnostics = new List <DiagnosticInfo>();
            var analyzers   = Arguments.ResolveAnalyzersFromArguments(diagnostics, MessageProvider, touchedFilesLogger);

            if (PrintErrors(diagnostics, consoleOutput))
            {
                return(Failed);
            }

            cancellationToken.ThrowIfCancellationRequested();

            EmitResult emitResult;

            // EDMAURER: Don't yet know if there are method body errors. don't overwrite
            // any existing output files until the compilation is known to be successful.
            string tempExeFilename = null;
            string tempPdbFilename = null;

            // NOTE: as native compiler does, we generate the documentation file
            // NOTE: 'in place', replacing the contents of the file if it exists

            try
            {
                tempExeFilename = CreateTempFile(consoleOutput);

                // Can happen when temp directory is "full"
                if (tempExeFilename == null)
                {
                    return(Failed);
                }

                FileStream output = OpenFile(tempExeFilename, consoleOutput);
                if (output == null)
                {
                    return(Failed);
                }

                string finalOutputPath;
                string finalPdbFilePath;
                string finalXmlFilePath;

                using (output)
                {
                    FileStream pdb = null;
                    FileStream xml = null;

                    cancellationToken.ThrowIfCancellationRequested();

                    if (Arguments.CompilationOptions.DebugInformationKind != DebugInformationKind.None)
                    {
                        tempPdbFilename = CreateTempFile(consoleOutput);

                        if (tempPdbFilename == null)
                        {
                            return(Failed);
                        }

                        pdb = OpenFile(tempPdbFilename, consoleOutput);
                        if (pdb == null)
                        {
                            return(Failed);
                        }
                    }

                    cancellationToken.ThrowIfCancellationRequested();

                    finalXmlFilePath = Arguments.DocumentationPath;
                    if (finalXmlFilePath != null)
                    {
                        xml = OpenFile(finalXmlFilePath, consoleOutput, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete);
                        if (xml == null)
                        {
                            return(Failed);
                        }
                        xml.SetLength(0);
                    }

                    cancellationToken.ThrowIfCancellationRequested();

                    IEnumerable <DiagnosticInfo> errors;
                    using (var win32Res = GetWin32Resources(Arguments, compilation, out errors))
                        using (pdb)
                            using (xml)
                            {
                                if (PrintErrors(errors, consoleOutput))
                                {
                                    return(Failed);
                                }

                                cancellationToken.ThrowIfCancellationRequested();

                                string outputName = GetOutputFileName(compilation, cancellationToken);

                                finalOutputPath  = Path.Combine(Arguments.OutputDirectory, outputName);
                                finalPdbFilePath = Arguments.PdbPath ?? Path.ChangeExtension(finalOutputPath, ".pdb");

                                // NOTE: Unlike the PDB path, the XML doc path is not embedded in the assembly, so we don't need to pass it to emit.
                                emitResult = compilation.Emit(output, outputName, finalPdbFilePath, pdb, xml, cancellationToken, win32Res, Arguments.ManifestResources);
                            }
                }

                GenerateSqmData(Arguments.CompilationOptions, emitResult.Diagnostics);

                if (PrintErrors(emitResult.Diagnostics, consoleOutput))
                {
                    return(Failed);
                }

                cancellationToken.ThrowIfCancellationRequested();

                var analyzerDiagnostics = AnalyzerDriver.GetDiagnostics(compilation, analyzers, default(CancellationToken));
                if (PrintErrors(analyzerDiagnostics, consoleOutput))
                {
                    return(Failed);
                }

                cancellationToken.ThrowIfCancellationRequested();

                if (!TryDeleteFile(finalOutputPath, consoleOutput) || !TryMoveFile(tempExeFilename, finalOutputPath, consoleOutput))
                {
                    return(Failed);
                }

                cancellationToken.ThrowIfCancellationRequested();

                if (tempPdbFilename != null)
                {
                    if (!TryDeleteFile(finalPdbFilePath, consoleOutput) || !TryMoveFile(tempPdbFilename, finalPdbFilePath, consoleOutput))
                    {
                        return(Failed);
                    }
                }

                cancellationToken.ThrowIfCancellationRequested();

                if (Arguments.TouchedFilesPath != null)
                {
                    Debug.Assert(touchedFilesLogger != null);

                    touchedFilesLogger.AddWritten(tempExeFilename);
                    touchedFilesLogger.AddWritten(finalOutputPath);
                    if (tempPdbFilename != null)
                    {
                        touchedFilesLogger.AddWritten(tempPdbFilename);
                        touchedFilesLogger.AddWritten(finalPdbFilePath);
                    }
                    if (finalXmlFilePath != null)
                    {
                        touchedFilesLogger.AddWritten(finalXmlFilePath);
                    }


                    var readStream = OpenFile(Arguments.TouchedFilesPath + ".read", consoleOutput, FileMode.OpenOrCreate);
                    if (readStream == null)
                    {
                        return(Failed);
                    }

                    using (var writer = new StreamWriter(readStream))
                    {
                        touchedFilesLogger.WriteReadPaths(writer);
                    }

                    var writtenStream = OpenFile(Arguments.TouchedFilesPath + ".write", consoleOutput, FileMode.OpenOrCreate);
                    if (writtenStream == null)
                    {
                        return(Failed);
                    }

                    using (var writer = new StreamWriter(writtenStream))
                    {
                        touchedFilesLogger.WriteWrittenPaths(writer);
                    }
                }


                return(Succeeded);
            }
            finally
            {
                if (tempExeFilename != null)
                {
                    TryDeleteFile(tempExeFilename, consoleOutput: null);
                }

                if (tempPdbFilename != null)
                {
                    TryDeleteFile(tempPdbFilename, consoleOutput: null);
                }
            }
        }
示例#5
0
        static void SingleStatementBodyAnalyzerTest()
        {
            //
            // Construct a syntax tree and a compilation.
            //

            var tree = CSharpSyntaxTree.ParseText(@"
using System;

class Foo
{
    void If(int x)
    {
        if (x > 0)
            Console.WriteLine(x);
        else if (x == 0)
            Console.WriteLine(0);
        else if (x < 0)
            Console.WriteLine(-x);
    }

    void For()
    {
        for (int i = 0; i < 10; i++)
            Console.WriteLine(i);
    }

    void ForEach()
    {
        foreach (var x in new[] { 1, 2, 3 })
            Console.WriteLine(x);
    }

    void While()
    {
        while (true)
            Console.Write('.');
    }
}");

            var mscorlib = new MetadataFileReference(typeof(object).Assembly.Location);

            var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

            var comp = CSharpCompilation.Create("Demo")
                       .AddSyntaxTrees(tree)
                       .AddReferences(mscorlib)
                       .WithOptions(options);


            //
            // Get diagnostics.
            //

            var diags = AnalyzerDriver.GetDiagnostics(comp, new[] { new SingleStatementBodyAnalyzer() }, null, CancellationToken.None);

            foreach (var diag in diags)
            {
                Console.WriteLine(diag);
            }
        }
示例#6
0
        public void AnalyzerDriverIsSafeAgainstAnalyzerExceptions()
        {
            var compilation = CreateCompilationWithMscorlib45(TestResource.AllInOneCSharpCode);

            ThrowingDiagnosticAnalyzer <SyntaxKind> .VerifyAnalyzerEngineIsSafeAgainstExceptions(analyzer =>
                                                                                                 AnalyzerDriver.GetDiagnostics(compilation, new[] { analyzer }, CancellationToken.None), typeof(AnalyzerDriver).Name);
        }
 public static TCompilation VerifyAnalyzerDiagnostics <TCompilation>(this TCompilation c, IDiagnosticAnalyzer[] analyzers, params DiagnosticDescription[] expected)
     where TCompilation : Compilation
 {
     AnalyzerDriver.GetDiagnostics(c, analyzers, default(CancellationToken)).Verify(expected);
     return(c);
 }