示例#1
0
        private IEnumerable <string> ExtractProjectFolders(IAnalyzerResult projectAnalyzerResult)
        {
            var projectFilePath  = projectAnalyzerResult.ProjectFilePath;
            var projectFile      = _fileSystem.File.OpenText(projectFilePath);
            var xDocument        = XDocument.Load(projectFile);
            var folders          = new List <string>();
            var projectDirectory = _fileSystem.Path.GetDirectoryName(projectFilePath);

            folders.Add(projectDirectory);

            foreach (var sharedProject in FindSharedProjects(xDocument))
            {
                var sharedProjectName = ReplaceMsbuildProperties(sharedProject, projectAnalyzerResult);

                if (!_fileSystem.File.Exists(_fileSystem.Path.Combine(projectDirectory, sharedProjectName)))
                {
                    throw new FileNotFoundException($"Missing shared project {sharedProjectName}");
                }

                var directoryName = _fileSystem.Path.GetDirectoryName(sharedProjectName);
                folders.Add(_fileSystem.Path.Combine(projectDirectory, directoryName));
            }

            return(folders);
        }
示例#2
0
 internal static bool TryGetWorkspace(
     this IAnalyzerResult analyzerResult,
     out Workspace ws)
 {
     ws = analyzerResult.GetWorkspace();
     return(ws.CanBeUsedToGenerateCompilation());
 }
示例#3
0
        private ProjectAnalysisResult BuildIncremental(string WorkspacePath)
        {
            Queue <string> queue    = new Queue <string>();
            ISet <string>  existing = new HashSet <string>();

            queue.Enqueue(WorkspacePath);
            existing.Add(WorkspacePath);

            /*
             * We need to resolve all the project dependencies to avoid compilation errors.
             * If we have compilation errors, we might miss some of the semantic values.
             */
            while (queue.Count > 0)
            {
                var path = queue.Dequeue();
                Logger.LogInformation("Building: " + path);

                IProjectAnalyzer projectAnalyzer = _analyzerManager.GetProject(path);

                if (!TryGetRequiresNetFramework(projectAnalyzer.ProjectFile, out bool requiresNetFramework))
                {
                    continue;
                }
                IAnalyzerResult analyzerResult = projectAnalyzer.Build(GetEnvironmentOptions(requiresNetFramework, projectAnalyzer.ProjectFile.ToolsVersion)).FirstOrDefault();

                if (analyzerResult == null)
                {
                    Logger.LogDebug("Building complete for {0} - {1}", path, "Fail");
                    return(new ProjectAnalysisResult()
                    {
                        ProjectAnalyzer = projectAnalyzer
                    });
                }

                if (!DictAnalysisResult.ContainsKey(analyzerResult.ProjectGuid))
                {
                    DictAnalysisResult[analyzerResult.ProjectGuid] = analyzerResult;
                    projectAnalyzer.AddToWorkspace(_workspaceIncremental);

                    foreach (var pref in analyzerResult.ProjectReferences)
                    {
                        if (!existing.Contains(pref))
                        {
                            existing.Add(pref);
                            queue.Enqueue(pref);
                        }
                    }
                }
            }

            Project project = _workspaceIncremental.CurrentSolution?.Projects.FirstOrDefault(x => x.FilePath.Equals(WorkspacePath));

            Logger.LogDebug("Building complete for {0} - {1}", WorkspacePath, DictAnalysisResult[project.Id.Id].Succeeded ? "Success" : "Fail");
            return(new ProjectAnalysisResult()
            {
                Project = project,
                AnalyzerResult = DictAnalysisResult[project.Id.Id],
                ProjectAnalyzer = _analyzerManager.Projects.Values.FirstOrDefault(p => p.ProjectGuid.Equals(project.Id.Id))
            });
        }
        public static IEnumerable <ISourceGenerator> GetSourceGenerators(this IAnalyzerResult analyzerResult, ILogger logger = null)
        {
            var generators = new List <ISourceGenerator>();

            foreach (var analyzer in analyzerResult.AnalyzerReferences)
            {
                try
                {
                    var assembly = System.Reflection.Assembly.LoadFile(analyzer);
                    foreach (var type in assembly.ExportedTypes)
                    {
                        if (type.GetInterface("ISourceGenerator") != null)
                        {
                            var generator = type.GetConstructor(Type.EmptyTypes).Invoke(null);
                            generators.Add(generator as ISourceGenerator);
                        }
                    }
                }
                catch (Exception e)
                {
                    logger?.LogWarning(e,
                                       $"Analyzer assembly {analyzer} could not be loaded. {Environment.NewLine}" +
                                       $"Generated source code may be missing.");

                    continue;
                }
            }
            return(generators);
        }
示例#5
0
        /// <summary>
        /// Adds a result to an existing Roslyn workspace.
        /// </summary>
        /// <param name="analyzerResult">The results from building a Buildalyzer project analyzer.</param>
        /// <param name="workspace">A Roslyn workspace.</param>
        /// <param name="addProjectReferences">
        /// <c>true</c> to add projects to the workspace for project references that exist in the same <see cref="AnalyzerManager"/>.
        /// If <c>true</c> this will trigger (re)building all referenced projects. Directly add <see cref="AnalyzerResult"/> instances instead if you already have them available.
        /// </param>
        /// <returns>The newly added Roslyn project.</returns>
        public static Project AddToWorkspace(this IAnalyzerResult analyzerResult, Workspace workspace, bool addProjectReferences = false)
        {
            if (analyzerResult == null)
            {
                throw new ArgumentNullException(nameof(analyzerResult));
            }
            if (workspace == null)
            {
                throw new ArgumentNullException(nameof(workspace));
            }

            // Get or create an ID for this project
            ProjectId projectId = ProjectId.CreateFromSerialized(analyzerResult.ProjectGuid);

            // Cache the project references
            analyzerResult.Manager.WorkspaceProjectReferences[projectId.Id] = analyzerResult.ProjectReferences.ToArray();

            // Create and add the project
            ProjectInfo projectInfo = GetProjectInfo(analyzerResult, workspace, projectId);
            Solution    solution    = workspace.CurrentSolution.AddProject(projectInfo);

            // Check if this project is referenced by any other projects in the workspace
            foreach (Project existingProject in solution.Projects.ToArray())
            {
                if (!existingProject.Id.Equals(projectId) &&
                    analyzerResult.Manager.WorkspaceProjectReferences.TryGetValue(existingProject.Id.Id, out string[] existingReferences) &&
        public static IEnumerable <ISourceGenerator> GetSourceGenerators(this IAnalyzerResult analyzerResult, ILogger logger = null)
        {
            var generators = new List <ISourceGenerator>();

            foreach (var analyzer in analyzerResult.AnalyzerReferences)
            {
                try
                {
                    var analyzerFileReference = new AnalyzerFileReference(analyzer, AnalyzerAssemblyLoader.Instance);
                    analyzerFileReference.AnalyzerLoadFailed += (sender, e) => throw e.Exception ?? new InvalidOperationException(e.Message);
                    foreach (var generator in analyzerFileReference.GetGenerators(LanguageNames.CSharp))
                    {
                        generators.Add(generator);
                    }
                }
                catch (Exception e)
                {
                    logger?.LogWarning(e,
                                       $"Analyzer/Generator assembly {analyzer} could not be loaded. {Environment.NewLine}" +
                                       "Generated source code may be missing.");
                }
            }

            return(generators);
        }
示例#7
0
        private FsharpFolderComposite FindProjectFilesUsingBuildalyzer(IAnalyzerResult analyzerResult)
        {
            var inputFiles          = new FsharpFolderComposite();
            var projectUnderTestDir = Path.GetDirectoryName(analyzerResult.ProjectFilePath);
            var projectRoot         = Path.GetDirectoryName(projectUnderTestDir);
            var rootFolderComposite = new FsharpFolderComposite()
            {
                FullPath     = projectRoot,
                RelativePath = string.Empty
            };
            var cache = new Dictionary <string, FsharpFolderComposite> {
                [string.Empty] = rootFolderComposite
            };

            // Save cache in a singleton so we can use it in other parts of the project
            FolderCompositeCache <FsharpFolderComposite> .Instance.Cache = cache;

            inputFiles.Add(rootFolderComposite);

            var fSharpChecker = FSharpChecker.Create(projectCacheSize: null, keepAssemblyContents: null, keepAllBackgroundResolutions: null, legacyReferenceResolver: null, tryGetMetadataSnapshot: null, suggestNamesForErrors: null, keepAllBackgroundSymbolUses: null, enableBackgroundItemKeyStoreAndSemanticClassification: null);

            foreach (var sourceFile in analyzerResult.SourceFiles)
            {
                // Skip xamarin UI generated files
                if (sourceFile.EndsWith(".xaml.cs"))
                {
                    continue;
                }

                var relativePath    = Path.GetRelativePath(projectUnderTestDir, sourceFile);
                var folderComposite = GetOrBuildFolderComposite(cache, Path.GetDirectoryName(relativePath), projectUnderTestDir, projectRoot, inputFiles);
                var fileName        = Path.GetFileName(sourceFile);

                var file = new FsharpFileLeaf()
                {
                    SourceCode   = FileSystem.File.ReadAllText(sourceFile),
                    RelativePath = FileSystem.Path.Combine(folderComposite.RelativePath, fileName),
                    FullPath     = sourceFile
                };

                // Get the syntax tree for the source file
                Tuple <FSharpProjectOptions, FSharpList <FSharpErrorInfo> > fSharpOptions = FSharpAsync.RunSynchronously(fSharpChecker.GetProjectOptionsFromScript(filename: file.FullPath, sourceText: SourceText.ofString(file.SourceCode), previewEnabled: null, loadedTimeStamp: null, otherFlags: null, useFsiAuxLib: null, useSdkRefs: null, assumeDotNetFramework: null, extraProjectInfo: null, optionsStamp: null, userOpName: null), timeout: null, cancellationToken: null);
                FSharpParseFileResults result = FSharpAsync.RunSynchronously(fSharpChecker.ParseFile(fileName, SourceText.ofString(file.SourceCode), fSharpChecker.GetParsingOptionsFromProjectOptions(fSharpOptions.Item1).Item1, userOpName: null), timeout: null, cancellationToken: null);

                if (result.ParseTree.Value.IsImplFile)
                {
                    var syntaxTree = (ImplFile)result.ParseTree.Value;

                    file.SyntaxTree = syntaxTree;
                    folderComposite.Add(file);
                }
                else
                {
                    var message = $"Cannot make Fsharp SyntaxTree from .fsi filetype (SyntaxTree.ParsedImplFileInput class wanted)";
                    throw new InputException(message);
                }
            }
            return(inputFiles);
        }
示例#8
0
 public void Dispose()
 {
     Compilation     = null;
     AnalyzerResult  = null;
     ProjectAnalyzer = null;
     Project         = null;
     Logger          = null;
 }
 public static Language GetLanguage(this IAnalyzerResult analyzerResult)
 {
     return(analyzerResult.GetPropertyOrDefault("Language") switch
     {
         "F#" => Language.Fsharp,
         "C#" => Language.Csharp,
         _ => Language.Undefined,
     });
        private CsharpFolderComposite FindProjectFilesUsingBuildalyzer(IAnalyzerResult analyzerResult, StrykerOptions options)
        {
            var projectUnderTestDir             = Path.GetDirectoryName(analyzerResult.ProjectFilePath);
            var generatedAssemblyInfo           = analyzerResult.AssemblyAttributeFileName();
            var projectUnderTestFolderComposite = new CsharpFolderComposite()
            {
                FullPath     = projectUnderTestDir,
                RelativePath = null,
            };
            var cache = new Dictionary <string, CsharpFolderComposite> {
                [string.Empty] = projectUnderTestFolderComposite
            };

            // Save cache in a singleton so we can use it in other parts of the project
            FolderCompositeCache <CsharpFolderComposite> .Instance.Cache = cache;

            CSharpParseOptions cSharpParseOptions = BuildCsharpParseOptions(analyzerResult, options);

            InjectMutantHelpers(projectUnderTestFolderComposite, cSharpParseOptions);

            foreach (var sourceFile in analyzerResult.SourceFiles)
            {
                var relativePath    = Path.GetRelativePath(projectUnderTestDir, sourceFile);
                var folderComposite = GetOrBuildFolderComposite(cache, Path.GetDirectoryName(relativePath), projectUnderTestDir, projectUnderTestFolderComposite);

                var file = new CsharpFileLeaf()
                {
                    SourceCode   = FileSystem.File.ReadAllText(sourceFile),
                    FullPath     = sourceFile,
                    RelativePath = Path.GetRelativePath(projectUnderTestDir, sourceFile)
                };

                // Get the syntax tree for the source file
                var syntaxTree = CSharpSyntaxTree.ParseText(file.SourceCode,
                                                            path: file.FullPath,
                                                            encoding: Encoding.UTF32,
                                                            options: cSharpParseOptions);

                // don't mutate auto generated code
                if (syntaxTree.IsGenerated())
                {
                    // we found the generated assemblyinfo file
                    if (FileSystem.Path.GetFileName(sourceFile).ToLowerInvariant() == generatedAssemblyInfo)
                    {
                        // add the mutated text
                        syntaxTree = InjectMutationLabel(syntaxTree);
                    }
                    _logger.LogDebug("Skipping auto-generated code file: {fileName}", file.FullPath);
                    folderComposite.AddCompilationSyntaxTree(syntaxTree); // Add the syntaxTree to the list of compilationSyntaxTrees
                    continue;                                             // Don't add the file to the folderComposite as we're not reporting on the file
                }

                file.SyntaxTree = syntaxTree;
                folderComposite.Add(file);
            }

            return(projectUnderTestFolderComposite);
        }
示例#11
0
        /// <summary>
        /// Gets a Roslyn workspace for the analyzed results.
        /// </summary>
        /// <param name="analyzerResult">The results from building a Buildalyzer project analyzer.</param>
        /// <param name="addProjectReferences">
        /// <c>true</c> to add projects to the workspace for project references that exist in the same <see cref="AnalyzerManager"/>.
        /// If <c>true</c> this will trigger (re)building all referenced projects. Directly add <see cref="AnalyzerResult"/> instances instead if you already have them available.
        /// </param>
        /// <returns>A Roslyn workspace.</returns>
        public static AdhocWorkspace GetWorkspace(this IAnalyzerResult analyzerResult, bool addProjectReferences = false)
        {
            if (analyzerResult == null)
            {
                throw new ArgumentNullException(nameof(analyzerResult));
            }
            AdhocWorkspace workspace = new AdhocWorkspace();

            analyzerResult.AddToWorkspace(workspace, addProjectReferences);
            return(workspace);
        }
 public static Framework GetTargetFramework(this IAnalyzerResult analyzerResult)
 {
     try
     {
         return(ParseTargetFramework(analyzerResult.TargetFramework));
     }
     catch (ArgumentException)
     {
         throw new StrykerInputException($"Unable to parse framework version string {analyzerResult.TargetFramework}. Please fix the framework version in the csproj.");
     }
 }
        internal static NuGetFramework GetNuGetFramework(this IAnalyzerResult analyzerResult)
        {
            var framework = NuGetFramework.Parse(analyzerResult.TargetFramework ?? "");

            if (framework == NuGetFramework.UnsupportedFramework)
            {
                var atPath  = string.IsNullOrEmpty(analyzerResult.ProjectFilePath) ? "" : $" at '{analyzerResult.ProjectFilePath}'";
                var message = $"The target framework '{analyzerResult.TargetFramework}' is not supported. Please fix the target framework in the csproj{atPath}.";
                throw new InputException(message);
            }
            return(framework);
        }
示例#14
0
        private bool DidPerformCoreCompile(IAnalyzerResult result)
        {
            if (result == null)
            {
                return(false);
            }

            var sourceCount    = result.SourceFiles?.Length ?? 0;
            var compilerInputs = result.GetCompileInputs()?.Length ?? 0;

            return(compilerInputs > 0 && sourceCount > 0);
        }
示例#15
0
        /// <summary>
        /// Recursively scans the given directory for files to mutate
        /// </summary>
        private FsharpFolderComposite FindInputFiles(string path, IAnalyzerResult analyzerResult)
        {
            var rootFolderComposite = new FsharpFolderComposite
            {
                FullPath     = Path.GetFullPath(path),
                RelativePath = Path.GetFileName(path),
            };

            rootFolderComposite.Add(
                FindInputFiles(path, Path.GetDirectoryName(analyzerResult.ProjectFilePath), rootFolderComposite.RelativePath)
                );
            return(rootFolderComposite);
        }
示例#16
0
        private async Task <IAnalyzerResult> BuildProjectAsync(IAnalyzerResult result)
        {
            if (result != null)
            {
                return(result);
            }

            using (await DirectoryAccessor.TryLockAsync())
            {
                using (var operation = Log.OnEnterAndConfirmOnExit())
                {
                    try
                    {
                        operation.Info("Building package {name}", Name);
                        await DotnetBuild();

                        operation.Info("Workspace built");
                        operation.Succeed();
                    }
                    catch (Exception exception)
                    {
                        operation.Error("Exception building workspace", exception);
                        throw;
                    }

                    var binLog = this.FindLatestBinLog();

                    if (binLog == null)
                    {
                        throw new InvalidOperationException("Failed to build");
                    }

                    var results = await TryLoadAnalyzerResultsAsync(binLog);

                    if (results?.Count == 0)
                    {
                        throw new InvalidOperationException("The build log seems to contain no solutions or projects");
                    }

                    result = results?.FirstOrDefault(p => p.ProjectFilePath == _projectFile.FullName);

                    if (result?.Succeeded == true)
                    {
                        return(result);
                    }

                    throw new InvalidOperationException("Failed to build");
                }
            }
        }
示例#17
0
 private Task <Workspace> BuildWorkspaceAsync(IAnalyzerResult result)
 {
     if (result.TryGetWorkspace(out var ws))
     {
         var projectId          = ws.CurrentSolution.ProjectIds.FirstOrDefault();
         var references         = result.References;
         var metadataReferences = references.GetMetadataReferences();
         var solution           = ws.CurrentSolution;
         solution = solution.WithProjectMetadataReferences(projectId, metadataReferences);
         ws.TryApplyChanges(solution);
         return(Task.FromResult(ws));
     }
     throw new InvalidOperationException("Failed creating workspace");
 }
示例#18
0
        public static string[] GetCompileInputs(this IAnalyzerResult analyzerResult)
        {
            string[] files;
            lock (CompilerInputs)
            {
                if (!CompilerInputs.TryGetValue(analyzerResult, out files))
                {
                    var projectDirectory = Path.GetDirectoryName(analyzerResult.ProjectFilePath);
                    var found            = analyzerResult.Items.TryGetValue("Compile", out var inputFiles);
                    files = found ? inputFiles.Select(pi => Path.Combine(projectDirectory, pi.ItemSpec)).ToArray() : Array.Empty <string>();
                    CompilerInputs.Add(analyzerResult, files);
                }
            }

            return(files);
        }
        public static IList <string> GetDefineConstants(this IAnalyzerResult analyzerResult)
        {
            var constants = analyzerResult?.GetPropertyOrDefault("DefineConstants", "").Split(";").Where(x => !string.IsNullOrWhiteSpace(x)).ToList() ?? new List <string>();

            var(frameworkSupportsAppDomain, frameworkSupportsPipes) = CompatibilityModes(analyzerResult);

            if (!frameworkSupportsAppDomain)
            {
                constants.Add("STRYKER_NO_DOMAIN");
            }
            if (!frameworkSupportsPipes)
            {
                constants.Add("STRYKER_NO_PIPE");
            }

            return(constants);
        }
        public static CSharpCompilationOptions GetCompilationOptions(this IAnalyzerResult analyzerResult)
        {
            var compilationOptions = new CSharpCompilationOptions(analyzerResult.GetOutputKind())
                                     .WithNullableContextOptions(analyzerResult.GetNullableContextOptions())
                                     .WithAllowUnsafe(analyzerResult.GetPropertyOrDefault("AllowUnsafeBlocks", true))
                                     .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default)
                                     .WithConcurrentBuild(true)
                                     .WithModuleName(analyzerResult.GetAssemblyName())
                                     .WithOverflowChecks(analyzerResult.GetPropertyOrDefault("CheckForOverflowUnderflow", false));

            if (analyzerResult.IsSignedAssembly())
            {
                compilationOptions = compilationOptions.WithCryptoKeyFile(analyzerResult.GetAssemblyOriginatorKeyFile())
                                     .WithStrongNameProvider(new DesktopStrongNameProvider());
            }
            return(compilationOptions);
        }
示例#21
0
        private static string ReplaceMsbuildProperties(string projectReference, IAnalyzerResult projectAnalyzerResult)
        {
            var propertyRegex = new Regex(@"\$\(([a-zA-Z_][a-zA-Z0-9_\-.]*)\)");
            var properties    = projectAnalyzerResult.Properties;

            return(propertyRegex.Replace(projectReference,
                                         m =>
            {
                var property = m.Groups[1].Value;
                if (properties.TryGetValue(property, out var propertyValue))
                {
                    return propertyValue;
                }

                var message = $"Missing MSBuild property ({property}) in project reference ({projectReference}). Please check your project file ({projectAnalyzerResult.ProjectFilePath}) and try again.";
                throw new StrykerInputException(message);
            }));
        }
示例#22
0
        private FsharpFolderComposite FindProjectFilesScanningProjectFolders(IAnalyzerResult analyzerResult)
        {
            var inputFiles          = new FsharpFolderComposite();
            var projectUnderTestDir = Path.GetDirectoryName(analyzerResult.ProjectFilePath);

            foreach (var dir in ExtractProjectFolders(analyzerResult))
            {
                var folder = FileSystem.Path.Combine(Path.GetDirectoryName(projectUnderTestDir), dir);

                _logger.LogDebug($"Scanning {folder}");
                if (!FileSystem.Directory.Exists(folder))
                {
                    throw new DirectoryNotFoundException($"Can't find {folder}");
                }

                inputFiles.Add(FindInputFiles(projectUnderTestDir, analyzerResult));
            }

            return(inputFiles);
        }
示例#23
0
        private CSharpCompilation RunSourceGenerators(IAnalyzerResult analyzerResult, CSharpCompilation compilation)
        {
            var generators = analyzerResult.GetSourceGenerators(_logger);

            _ = CSharpGeneratorDriver
                .Create(generators)
                .RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics);

            var errors = diagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error && diagnostic.Location == Location.None);

            if (errors.Any())
            {
                foreach (var diagnostic in errors)
                {
                    _logger.LogError("Failed to generate source code for mutated assembly: {0}", diagnostic);
                }
                throw new CompilationException("Source Generator Failure");
            }
            return(outputCompilation as CSharpCompilation);
        }
示例#24
0
        protected async Task <IAnalyzerResult> DesignTimeBuild()
        {
            using (var operation = _log.OnEnterAndConfirmOnExit())
            {
                IAnalyzerResult result;
                var             csProj    = this.GetProjectFile();
                var             logWriter = new StringWriter();

                using (await FileLock.TryCreateAsync(Directory))
                {
                    var manager = new AnalyzerManager(new AnalyzerManagerOptions
                    {
                        LogWriter = logWriter
                    });
                    var analyzer = manager.GetProject(csProj.FullName);
                    analyzer.AddBinaryLogger(Path.Combine(Directory.FullName, DesignTimeBuildBinlogFileName));
                    var languageVersion = csProj.SuggestedLanguageVersion();
                    analyzer.SetGlobalProperty("langVersion", languageVersion);
                    result = analyzer.Build().Results.First();
                }

                DesignTimeBuildResult = result;
                LastDesignTimeBuild   = Clock.Current.Now();
                if (result.Succeeded == false)
                {
                    var logData = logWriter.ToString();
                    File.WriteAllText(
                        LastBuildErrorLogFile.FullName,
                        string.Join(Environment.NewLine, "Design Time Build Error", logData));
                }
                else if (LastBuildErrorLogFile.Exists)
                {
                    LastBuildErrorLogFile.Delete();
                }

                operation.Succeed();

                return(result);
            }
        }
示例#25
0
        private async Task <IAnalyzerResult> BuildProjectAsync(IAnalyzerResult result)
        {
            if (result != null)
            {
                return(result);
            }

            using (await DirectoryAccessor.TryLockAsync())
            {
                {
                    await DotnetBuild();

                    var binLog = this.FindLatestBinLog();

                    if (binLog == null)
                    {
                        throw new InvalidOperationException("Failed to build");
                    }

                    var results = await TryLoadAnalyzerResultsAsync(binLog);

                    if (results?.Count == 0)
                    {
                        throw new InvalidOperationException("The build log seems to contain no solutions or projects");
                    }

                    result = results?.FirstOrDefault(p => p.ProjectFilePath == _projectFile.FullName);

                    if (result?.Succeeded == true)
                    {
                        return(result);
                    }

                    throw new InvalidOperationException("Failed to build");
                }
            }
        }
示例#26
0
        private void LogAnalyzerResult(IAnalyzerResult analyzerResult)
        {
            // dump all properties as it can help diagnosing build issues for user project.
            _logger.LogDebug("**** Buildalyzer result ****");

            _logger.LogDebug("Project: {0}", analyzerResult.ProjectFilePath);
            _logger.LogDebug("TargetFramework: {0}", analyzerResult.TargetFramework);

            foreach (var property in analyzerResult?.Properties ?? new Dictionary <string, string>())
            {
                _logger.LogDebug("Property {0}={1}", property.Key, property.Value);
            }
            foreach (var sourceFile in analyzerResult?.SourceFiles ?? Enumerable.Empty <string>())
            {
                _logger.LogDebug("SourceFile {0}", sourceFile);
            }
            foreach (var reference in analyzerResult?.References ?? Enumerable.Empty <string>())
            {
                _logger.LogDebug("References: {0}", reference);
            }
            _logger.LogDebug("Succeeded: {0}", analyzerResult.Succeeded);

            _logger.LogDebug("**** Buildalyzer result ****");
        }
示例#27
0
        public static CSharpParseOptions GetCSharpParseOptions(this IAnalyzerResult analyzerResult)
        {
            var parseOptions = new CSharpParseOptions();

            // Add any constants
            var constants = analyzerResult.GetProperty("DefineConstants");

            if (!string.IsNullOrWhiteSpace(constants))
            {
                parseOptions = parseOptions
                               .WithPreprocessorSymbols(constants.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()));
            }

            // Get language version
            var langVersion = analyzerResult.GetProperty("LangVersion");

            if (!string.IsNullOrWhiteSpace(langVersion) &&
                LanguageVersionFacts.TryParse(langVersion, out var languageVersion))
            {
                parseOptions = parseOptions.WithLanguageVersion(languageVersion);
            }

            return(parseOptions);
        }
 public static string?GetProjectAssetsFilePath(this IAnalyzerResult result)
 {
     return(result?.GetProperty("ProjectAssetsFile"));
 }
示例#29
0
 public string GetInjectionFilePath(IAnalyzerResult analyzerResult)
 {
     return(Path.Combine(
                Path.GetDirectoryName(analyzerResult.GetAssemblyPath()),
                Path.GetFileName(ProjectUnderTestAnalyzerResult.GetAssemblyPath())));
 }
示例#30
0
        public void Build()
        {
            /* Uncomment the below code to debug issues with msbuild */

            /*var writer = new StreamWriter(Console.OpenStandardOutput());
             * writer.AutoFlush = true;
             *
             * Console.SetOut(writer);
             * Console.SetError(writer);*/

            if (IsSolutionFile())
            {
                Logger.LogInformation("Loading the Workspace (Solution): " + WorkspacePath);

                AnalyzerManager analyzerManager = new AnalyzerManager(WorkspacePath,
                                                                      new AnalyzerManagerOptions
                {
                    LogWriter = _writer
                });

                Logger.LogInformation("Loading the Solution Done: " + WorkspacePath);

                // AnalyzerManager builds the projects based on their dependencies
                // After this, code does not depend on Buildalyzer
                BuildSolution(analyzerManager);
            }
            else
            {
                AnalyzerManager analyzerManager = new AnalyzerManager(new AnalyzerManagerOptions
                {
                    LogWriter = _writer
                });

                var dict = new Dictionary <Guid, IAnalyzerResult>();
                using (AdhocWorkspace workspace = new AdhocWorkspace())
                {
                    Queue <string> queue    = new Queue <string>();
                    ISet <string>  existing = new HashSet <string>();

                    queue.Enqueue(WorkspacePath);
                    existing.Add(WorkspacePath);

                    /*
                     * We need to resolve all the project dependencies to avoid compilation errors.
                     * If we have compilation errors, we might miss some of the semantic values.
                     */
                    while (queue.Count > 0)
                    {
                        var path = queue.Dequeue();
                        Logger.LogInformation("Building: " + path);

                        IProjectAnalyzer projectAnalyzer = analyzerManager.GetProject(path);

                        if (!TryGetRequiresNetFramework(projectAnalyzer.ProjectFile, out bool requiresNetFramework))
                        {
                            continue;
                        }

                        IAnalyzerResults analyzerResults = projectAnalyzer.Build(GetEnvironmentOptions(requiresNetFramework, projectAnalyzer.ProjectFile.ToolsVersion));
                        IAnalyzerResult  analyzerResult  = analyzerResults.First();

                        if (analyzerResult == null)
                        {
                            FailedProjects.Add(new ProjectAnalysisResult()
                            {
                                ProjectAnalyzer = projectAnalyzer
                            });
                        }

                        dict[analyzerResult.ProjectGuid] = analyzerResult;
                        analyzerResult.AddToWorkspace(workspace);

                        foreach (var pref in analyzerResult.ProjectReferences)
                        {
                            if (!existing.Contains(pref))
                            {
                                existing.Add(pref);
                                queue.Enqueue(pref);
                            }
                        }
                    }

                    foreach (var project in workspace.CurrentSolution.Projects)
                    {
                        try
                        {
                            var result = dict[project.Id.Id];

                            var projectAnalyzer = analyzerManager.Projects.Values.FirstOrDefault(p =>
                                                                                                 p.ProjectGuid.Equals(project.Id.Id));

                            Projects.Add(new ProjectAnalysisResult()
                            {
                                Project         = project,
                                AnalyzerResult  = result,
                                ProjectAnalyzer = projectAnalyzer
                            });
                        }
                        catch (Exception ex)
                        {
                            Logger.LogDebug(ex.StackTrace);
                        }
                    }
                }
            }

            Logger.LogDebug(_sb.ToString());
            _writer.Flush();
            _writer.Close();
            ProcessLog(_writer.ToString());
        }