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); }
internal static bool TryGetWorkspace( this IAnalyzerResult analyzerResult, out Workspace ws) { ws = analyzerResult.GetWorkspace(); return(ws.CanBeUsedToGenerateCompilation()); }
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); }
/// <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); }
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); }
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); }
/// <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); }
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); }
/// <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); }
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"); } } }
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"); }
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); }
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); })); }
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); }
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); }
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); } }
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"); } } }
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 ****"); }
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")); }
public string GetInjectionFilePath(IAnalyzerResult analyzerResult) { return(Path.Combine( Path.GetDirectoryName(analyzerResult.GetAssemblyPath()), Path.GetFileName(ProjectUnderTestAnalyzerResult.GetAssemblyPath()))); }
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()); }