Ejemplo n.º 1
0
 private static ExitCode AnalyseTracing(
     TracingAnalyser analyser,
     CSharpCommandLineArguments compilerArguments,
     Options options,
     CanonicalPathCache canonicalPathCache,
     Stopwatch stopwatch)
 {
     return(Analyse(stopwatch, analyser, options,
                    references => ResolveReferences(compilerArguments, analyser, canonicalPathCache, references),
                    (analyser, syntaxTrees) =>
     {
         return ReadSyntaxTrees(
             compilerArguments.SourceFiles.Select(src => canonicalPathCache.GetCanonicalPath(src.Path)),
             analyser,
             compilerArguments.ParseOptions,
             compilerArguments.Encoding,
             syntaxTrees);
     },
                    (syntaxTrees, references) =>
     {
         // csc.exe (CSharpCompiler.cs) also provides CompilationOptions
         // .WithMetadataReferenceResolver(),
         // .WithXmlReferenceResolver() and
         // .WithSourceReferenceResolver().
         // These would be needed if we hadn't explicitly provided the source/references
         // already.
         return CSharpCompilation.Create(
             compilerArguments.CompilationName,
             syntaxTrees,
             references,
             compilerArguments.CompilationOptions
             .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default)
             .WithStrongNameProvider(new DesktopStrongNameProvider(compilerArguments.KeyFileSearchPaths))
             .WithMetadataImportOptions(MetadataImportOptions.All)
             );
     },
                    (compilation, options) => analyser.EndInitialize(compilerArguments, options, compilation),
                    () => analyser.AnalyseCompilation(),
                    performance => analyser.LogPerformance(performance),
                    () => { }));
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Command-line driver for the extractor.
        /// </summary>
        ///
        /// <remarks>
        /// The extractor can be invoked in one of two ways: Either as an "analyser" passed in via the /a
        /// option to csc.exe, or as a stand-alone executable. In this case, we need to faithfully
        /// drive Roslyn in the way that csc.exe would.
        /// </remarks>
        ///
        /// <param name="args">Command line arguments as passed to csc.exe</param>
        /// <returns><see cref="ExitCode"/></returns>
        public static ExitCode Run(string[] args)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            Entities.Compilation.Settings = (Directory.GetCurrentDirectory(), args);

            var options    = Options.CreateWithEnvironment(Entities.Compilation.Settings.Args);
            var fileLogger = new FileLogger(options.Verbosity, GetCSharpLogPath());

            using var logger = options.Console
                ? new CombinedLogger(new ConsoleLogger(options.Verbosity), fileLogger)
                : (ILogger)fileLogger;

            if (Environment.GetEnvironmentVariable("SEMMLE_CLRTRACER") == "1" && !options.ClrTracer)
            {
                logger.Log(Severity.Info, "Skipping extraction since already extracted from the CLR tracer");
                return(ExitCode.Ok);
            }

            var canonicalPathCache = CanonicalPathCache.Create(logger, 1000);
            var pathTransformer    = new PathTransformer(canonicalPathCache);

            using var analyser = new TracingAnalyser(new LogProgressMonitor(logger), logger, options.AssemblySensitiveTrap, pathTransformer);

            try
            {
                if (options.ProjectsToLoad.Any())
                {
                    AddSourceFilesFromProjects(options.ProjectsToLoad, options.CompilerArguments, logger);
                }

                var compilerVersion = new CompilerVersion(options);

                if (compilerVersion.SkipExtraction)
                {
                    logger.Log(Severity.Warning, "  Unrecognized compiler '{0}' because {1}", compilerVersion.SpecifiedCompiler, compilerVersion.SkipReason);
                    return(ExitCode.Ok);
                }

                var compilerArguments = CSharpCommandLineParser.Default.Parse(
                    compilerVersion.ArgsWithResponse,
                    Entities.Compilation.Settings.Cwd,
                    compilerVersion.FrameworkPath,
                    compilerVersion.AdditionalReferenceDirectories
                    );

                if (compilerArguments is null)
                {
                    var sb = new StringBuilder();
                    sb.Append("  Failed to parse command line: ").AppendList(" ", Entities.Compilation.Settings.Args);
                    logger.Log(Severity.Error, sb.ToString());
                    ++analyser.CompilationErrors;
                    return(ExitCode.Failed);
                }

                if (!analyser.BeginInitialize(compilerVersion.ArgsWithResponse))
                {
                    logger.Log(Severity.Info, "Skipping extraction since files have already been extracted");
                    return(ExitCode.Ok);
                }

                return(AnalyseTracing(analyser, compilerArguments, options, canonicalPathCache, stopwatch));
            }
            catch (Exception ex)  // lgtm[cs/catch-of-all-exceptions]
            {
                logger.Log(Severity.Error, "  Unhandled exception: {0}", ex);
                return(ExitCode.Errors);
            }
        }