public MSBuildProject(ProjectFileInfo p) { AssemblyName = p.AssemblyName; Path = p.ProjectFilePath; TargetPath = p.TargetPath; ProjectGuid = p.ProjectId; TargetFramework = p.TargetFramework.ToString(); }
public static ProjectFileInfo Create(MSBuildOptions options, ILogger logger, string solutionDirectory, string projectFilePath, ICollection<MSBuildDiagnosticsMessage> diagnostics) { var projectFileInfo = new ProjectFileInfo(); projectFileInfo.ProjectFilePath = projectFilePath; #if DNX451 if (!PlatformHelper.IsMono) { var properties = new Dictionary<string, string> { { "DesignTimeBuild", "true" }, { "BuildProjectReferences", "false" }, { "_ResolveReferenceDependencies", "true" }, { "SolutionDir", solutionDirectory + Path.DirectorySeparatorChar } }; if (!string.IsNullOrWhiteSpace(options.VisualStudioVersion)) { properties.Add("VisualStudioVersion", options.VisualStudioVersion); } var collection = new ProjectCollection(properties); logger.LogInformation("Using toolset {0} for {1}", options.ToolsVersion ?? collection.DefaultToolsVersion, projectFilePath); var project = string.IsNullOrEmpty(options.ToolsVersion) ? collection.LoadProject(projectFilePath) : collection.LoadProject(projectFilePath, options.ToolsVersion); var projectInstance = project.CreateProjectInstance(); var buildResult = projectInstance.Build("ResolveReferences", new Microsoft.Build.Framework.ILogger[] { new MSBuildLogForwarder(logger, diagnostics) }); if (!buildResult) { return null; } projectFileInfo.AssemblyName = projectInstance.GetPropertyValue("AssemblyName"); projectFileInfo.Name = projectInstance.GetPropertyValue("ProjectName"); projectFileInfo.TargetFramework = new FrameworkName(projectInstance.GetPropertyValue("TargetFrameworkMoniker")); projectFileInfo.SpecifiedLanguageVersion = ToLanguageVersion(projectInstance.GetPropertyValue("LangVersion")); projectFileInfo.ProjectId = new Guid(projectInstance.GetPropertyValue("ProjectGuid").TrimStart('{').TrimEnd('}')); projectFileInfo.TargetPath = projectInstance.GetPropertyValue("TargetPath"); var outputType = projectInstance.GetPropertyValue("OutputType"); switch(outputType) { case "Library": projectFileInfo.OutputKind = OutputKind.DynamicallyLinkedLibrary; break; case "WinExe": projectFileInfo.OutputKind = OutputKind.WindowsApplication; break; default: case "Exe": projectFileInfo.OutputKind = OutputKind.ConsoleApplication; break; } projectFileInfo.SourceFiles = projectInstance.GetItems("Compile") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); projectFileInfo.References = projectInstance.GetItems("ReferencePath") .Where(p => !string.Equals("ProjectReference", p.GetMetadataValue("ReferenceSourceTarget"), StringComparison.OrdinalIgnoreCase)) .Select(p => p.GetMetadataValue("FullPath")) .ToList(); projectFileInfo.ProjectReferences = projectInstance.GetItems("ProjectReference") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); projectFileInfo.Analyzers = projectInstance.GetItems("Analyzer") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); var allowUnsafe = projectInstance.GetPropertyValue("AllowUnsafeBlocks"); if (!string.IsNullOrWhiteSpace(allowUnsafe)) { projectFileInfo.AllowUnsafe = Convert.ToBoolean(allowUnsafe); } var defineConstants = projectInstance.GetPropertyValue("DefineConstants"); if (!string.IsNullOrWhiteSpace(defineConstants)) { projectFileInfo.DefineConstants = defineConstants.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList(); } } else { // On mono we need to use this API since the ProjectCollection // isn't fully implemented #pragma warning disable CS0618 var engine = Engine.GlobalEngine; engine.DefaultToolsVersion = "4.0"; #pragma warning restore CS0618 // engine.RegisterLogger(new ConsoleLogger()); engine.RegisterLogger(new MSBuildLogForwarder(logger, diagnostics)); var propertyGroup = new BuildPropertyGroup(); propertyGroup.SetProperty("DesignTimeBuild", "true"); propertyGroup.SetProperty("BuildProjectReferences", "false"); // Dump entire assembly reference closure propertyGroup.SetProperty("_ResolveReferenceDependencies", "true"); propertyGroup.SetProperty("SolutionDir", solutionDirectory + Path.DirectorySeparatorChar); // propertyGroup.SetProperty("MSBUILDENABLEALLPROPERTYFUNCTIONS", "1"); engine.GlobalProperties = propertyGroup; var project = engine.CreateNewProject(); project.Load(projectFilePath); var buildResult = engine.BuildProjectFile(projectFilePath, new[] { "ResolveReferences" }, propertyGroup, null, BuildSettings.None, null); if (!buildResult) { return null; } var itemsLookup = project.EvaluatedItems.OfType<BuildItem>() .ToLookup(g => g.Name); var properties = project.EvaluatedProperties.OfType<BuildProperty>() .ToDictionary(p => p.Name); projectFileInfo.AssemblyName = properties["AssemblyName"].FinalValue; projectFileInfo.Name = Path.GetFileNameWithoutExtension(projectFilePath); projectFileInfo.TargetFramework = new FrameworkName(properties["TargetFrameworkMoniker"].FinalValue); if (properties.ContainsKey("LangVersion")) { projectFileInfo.SpecifiedLanguageVersion = ToLanguageVersion(properties["LangVersion"].FinalValue); } projectFileInfo.ProjectId = new Guid(properties["ProjectGuid"].FinalValue.TrimStart('{').TrimEnd('}')); projectFileInfo.TargetPath = properties["TargetPath"].FinalValue; // REVIEW: FullPath here returns the wrong physical path, we need to figure out // why. We must be setting up something incorrectly projectFileInfo.SourceFiles = itemsLookup["Compile"] .Select(b => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, b.FinalItemSpec))) .ToList(); projectFileInfo.References = itemsLookup["ReferencePath"] .Where(p => !p.HasMetadata("Project")) .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); projectFileInfo.ProjectReferences = itemsLookup["ProjectReference"] .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); projectFileInfo.Analyzers = itemsLookup["Analyzer"] .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); var allowUnsafe = properties["AllowUnsafeBlocks"].FinalValue; if (!string.IsNullOrWhiteSpace(allowUnsafe)) { projectFileInfo.AllowUnsafe = Convert.ToBoolean(allowUnsafe); } var defineConstants = properties["DefineConstants"].FinalValue; if (!string.IsNullOrWhiteSpace(defineConstants)) { projectFileInfo.DefineConstants = defineConstants.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList(); } } #else // TODO: Shell out to msbuild/xbuild here? #endif return projectFileInfo; }
public static ProjectFileInfo Create(ILogger logger, string solutionDirectory, string projectFilePath) { var projectFileInfo = new ProjectFileInfo(); projectFileInfo.ProjectFilePath = projectFilePath; #if ASPNET50 if (!PlatformHelper.IsMono) { var properties = new Dictionary<string, string> { { "DesignTimeBuild", "true" }, { "BuildProjectReferences", "false" }, { "_ResolveReferenceDependencies", "true" }, { "SolutionDir", solutionDirectory + Path.DirectorySeparatorChar } }; var collection = new ProjectCollection(properties); var project = collection.LoadProject(projectFilePath); var projectInstance = project.CreateProjectInstance(); var buildResult = projectInstance.Build("ResolveReferences", loggers: null); if (!buildResult) { return null; } projectFileInfo.AssemblyName = projectInstance.GetPropertyValue("AssemblyName"); projectFileInfo.Name = projectInstance.GetPropertyValue("ProjectName"); projectFileInfo.TargetFramework = new FrameworkName(projectInstance.GetPropertyValue("TargetFrameworkMoniker")); projectFileInfo.ProjectId = new Guid(projectInstance.GetPropertyValue("ProjectGuid").TrimStart('{').TrimEnd('}')); projectFileInfo.TargetPath = projectInstance.GetPropertyValue("TargetPath"); projectFileInfo.SourceFiles = projectInstance.GetItems("Compile") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); projectFileInfo.References = projectInstance.GetItems("ReferencePath") .Where(p => !string.Equals("ProjectReference", p.GetMetadataValue("ReferenceSourceTarget"), StringComparison.OrdinalIgnoreCase)) .Select(p => p.GetMetadataValue("FullPath")) .ToList(); projectFileInfo.ProjectReferences = projectInstance.GetItems("ProjectReference") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); projectFileInfo.Analyzers = projectInstance.GetItems("Analyzer") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); } else { // On mono we need to use this API since the ProjectCollection // isn't fully implemented #pragma warning disable CS0618 var engine = Engine.GlobalEngine; engine.DefaultToolsVersion = "4.0"; #pragma warning restore CS0618 // engine.RegisterLogger(new ConsoleLogger()); var propertyGroup = new BuildPropertyGroup(); propertyGroup.SetProperty("DesignTimeBuild", "true"); propertyGroup.SetProperty("BuildProjectReferences", "false"); // Dump entire assembly reference closure propertyGroup.SetProperty("_ResolveReferenceDependencies", "true"); propertyGroup.SetProperty("SolutionDir", solutionDirectory + Path.DirectorySeparatorChar); // propertyGroup.SetProperty("MSBUILDENABLEALLPROPERTYFUNCTIONS", "1"); engine.GlobalProperties = propertyGroup; var project = engine.CreateNewProject(); project.Load(projectFilePath); var buildResult = engine.BuildProjectFile(projectFilePath, new[] { "ResolveReferences" }, propertyGroup, null, BuildSettings.None, null); if (!buildResult) { return null; } var itemsLookup = project.EvaluatedItems.OfType<BuildItem>() .ToLookup(g => g.Name); var properties = project.EvaluatedProperties.OfType<BuildProperty>() .ToDictionary(p => p.Name); projectFileInfo.AssemblyName = properties["AssemblyName"].FinalValue; projectFileInfo.Name = Path.GetFileNameWithoutExtension(projectFilePath); projectFileInfo.TargetFramework = new FrameworkName(properties["TargetFrameworkMoniker"].FinalValue); projectFileInfo.ProjectId = new Guid(properties["ProjectGuid"].FinalValue.TrimStart('{').TrimEnd('}')); projectFileInfo.TargetPath = properties["TargetPath"].FinalValue; // REVIEW: FullPath here returns the wrong physical path, we need to figure out // why. We must be setting up something incorrectly projectFileInfo.SourceFiles = itemsLookup["Compile"] .Select(b => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, b.FinalItemSpec))) .ToList(); projectFileInfo.References = itemsLookup["ReferencePath"] .Where(p => !p.HasMetadata("Project")) .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); projectFileInfo.ProjectReferences = itemsLookup["ProjectReference"] .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); projectFileInfo.Analyzers = itemsLookup["Analyzer"] .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); } #else // TODO: Shell out to msbuild/xbuild here? #endif return projectFileInfo; }
private static IEnumerable <AnalyzerReference> ResolveAnalyzerReferencesForProject(ProjectFileInfo projectFileInfo, IAnalyzerAssemblyLoader analyzerAssemblyLoader) { foreach (var analyzerAssemblyPath in projectFileInfo.Analyzers.Distinct()) { analyzerAssemblyLoader.AddDependencyLocation(analyzerAssemblyPath); } return(projectFileInfo.Analyzers.Select(analyzerCandicatePath => new AnalyzerFileReference(analyzerCandicatePath, analyzerAssemblyLoader))); }
public static ImmutableDictionary <string, ReportDiagnostic> GetDiagnosticOptions(this ProjectFileInfo projectFileInfo) { var defaultSuppressions = CompilationOptionsHelper.GetDefaultSuppressedDiagnosticOptions(projectFileInfo.SuppressedDiagnosticIds); var specificRules = projectFileInfo.RuleSet?.SpecificDiagnosticOptions ?? ImmutableDictionary <string, ReportDiagnostic> .Empty; return(specificRules.Concat(defaultSuppressions.Where(x => !specificRules.Keys.Contains(x.Key))).ToImmutableDictionary()); }
public bool TryGetValue(string filePath, out ProjectFileInfo fileInfo) { return(_itemMap.TryGetValue(filePath, out fileInfo)); }
public static ProjectFileInfo Create( MSBuildOptions options, ILogger logger, string solutionDirectory, string projectFilePath, ICollection <MSBuildDiagnosticsMessage> diagnostics) { var projectFileInfo = new ProjectFileInfo(); projectFileInfo.ProjectFilePath = projectFilePath; if (!PlatformHelper.IsMono) { var properties = new Dictionary <string, string> { { "DesignTimeBuild", "true" }, { "BuildProjectReferences", "false" }, { "_ResolveReferenceDependencies", "true" }, { "SolutionDir", solutionDirectory + Path.DirectorySeparatorChar } }; if (!string.IsNullOrWhiteSpace(options.VisualStudioVersion)) { properties.Add("VisualStudioVersion", options.VisualStudioVersion); } var collection = new ProjectCollection(properties); logger.LogInformation("Using toolset {0} for {1}", options.ToolsVersion ?? collection.DefaultToolsVersion, projectFilePath); var project = string.IsNullOrEmpty(options.ToolsVersion) ? collection.LoadProject(projectFilePath) : collection.LoadProject(projectFilePath, options.ToolsVersion); var projectInstance = project.CreateProjectInstance(); var buildResult = projectInstance.Build("ResolveReferences", new Microsoft.Build.Framework.ILogger[] { new MSBuildLogForwarder(logger, diagnostics) }); if (!buildResult) { return(null); } projectFileInfo.AssemblyName = projectInstance.GetPropertyValue("AssemblyName"); projectFileInfo.Name = projectInstance.GetPropertyValue("ProjectName"); projectFileInfo.TargetFramework = new FrameworkName(projectInstance.GetPropertyValue("TargetFrameworkMoniker")); projectFileInfo.SpecifiedLanguageVersion = ToLanguageVersion(projectInstance.GetPropertyValue("LangVersion")); projectFileInfo.ProjectId = new Guid(projectInstance.GetPropertyValue("ProjectGuid").TrimStart('{').TrimEnd('}')); projectFileInfo.TargetPath = projectInstance.GetPropertyValue("TargetPath"); var outputType = projectInstance.GetPropertyValue("OutputType"); switch (outputType) { case "Library": projectFileInfo.OutputKind = OutputKind.DynamicallyLinkedLibrary; break; case "WinExe": projectFileInfo.OutputKind = OutputKind.WindowsApplication; break; default: case "Exe": projectFileInfo.OutputKind = OutputKind.ConsoleApplication; break; } projectFileInfo.SourceFiles = projectInstance.GetItems("Compile") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) { var framework = new NuGetFramework(projectFileInfo.TargetFramework.Identifier, projectFileInfo.TargetFramework.Version, projectFileInfo.TargetFramework.Profile); // CoreCLR MSBuild won't be able to resolve framework assemblies from mono now. projectFileInfo.References = projectInstance .GetItems("ReferencePath") .Where(p => !string.Equals("ProjectReference", p.GetMetadataValue("ReferenceSourceTarget"), StringComparison.OrdinalIgnoreCase)) .Select(p => { var fullpath = p.GetMetadataValue("FullPath"); if (!File.Exists(fullpath)) { string referenceName = Path.GetFileNameWithoutExtension(fullpath); string path; Version version; if (FrameworkReferenceResolver.Default.TryGetAssembly(referenceName, framework, out path, out version)) { logger.LogInformation($"Resolved refernce path: {referenceName} => {version} at {path}"); } else { logger.LogError($"Fail to resolve reference path for {referenceName}"); } return(path); } else { logger.LogInformation($"Resolved reference path {fullpath} by MSBuild."); return(fullpath); } }).ToList(); } else { projectFileInfo.References = projectInstance.GetItems("ReferencePath") .Where(p => !string.Equals("ProjectReference", p.GetMetadataValue("ReferenceSourceTarget"), StringComparison.OrdinalIgnoreCase)) .Select(p => p.GetMetadataValue("FullPath")) .ToList(); } projectFileInfo.ProjectReferences = projectInstance.GetItems("ProjectReference") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); projectFileInfo.Analyzers = projectInstance.GetItems("Analyzer") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); var allowUnsafe = projectInstance.GetPropertyValue("AllowUnsafeBlocks"); if (!string.IsNullOrWhiteSpace(allowUnsafe)) { projectFileInfo.AllowUnsafe = Convert.ToBoolean(allowUnsafe); } var defineConstants = projectInstance.GetPropertyValue("DefineConstants"); if (!string.IsNullOrWhiteSpace(defineConstants)) { projectFileInfo.DefineConstants = defineConstants.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList(); } var signAssembly = projectInstance.GetPropertyValue("SignAssembly"); if (!string.IsNullOrWhiteSpace(signAssembly)) { projectFileInfo.SignAssembly = Convert.ToBoolean(signAssembly); } projectFileInfo.AssemblyOriginatorKeyFile = projectInstance.GetPropertyValue("AssemblyOriginatorKeyFile"); var documentationFile = projectInstance.GetPropertyValue("DocumentationFile"); if (!string.IsNullOrWhiteSpace(documentationFile)) { projectFileInfo.GenerateXmlDocumentation = true; } } else { #if NET451 // On mono we need to use this API since the ProjectCollection // isn't fully implemented #pragma warning disable CS0618 var engine = Engine.GlobalEngine; engine.DefaultToolsVersion = "4.0"; #pragma warning restore CS0618 // engine.RegisterLogger(new ConsoleLogger()); engine.RegisterLogger(new MSBuildLogForwarder(logger, diagnostics)); var propertyGroup = new BuildPropertyGroup(); propertyGroup.SetProperty("DesignTimeBuild", "true"); propertyGroup.SetProperty("BuildProjectReferences", "false"); // Dump entire assembly reference closure propertyGroup.SetProperty("_ResolveReferenceDependencies", "true"); propertyGroup.SetProperty("SolutionDir", solutionDirectory + Path.DirectorySeparatorChar); // propertyGroup.SetProperty("MSBUILDENABLEALLPROPERTYFUNCTIONS", "1"); engine.GlobalProperties = propertyGroup; var project = engine.CreateNewProject(); project.Load(projectFilePath); var buildResult = engine.BuildProjectFile(projectFilePath, new[] { "ResolveReferences" }, propertyGroup, null, BuildSettings.None, null); if (!buildResult) { return(null); } var itemsLookup = project.EvaluatedItems.OfType <BuildItem>() .ToLookup(g => g.Name); var properties = project.EvaluatedProperties.OfType <BuildProperty>() .ToDictionary(p => p.Name); projectFileInfo.AssemblyName = properties["AssemblyName"].FinalValue; projectFileInfo.Name = Path.GetFileNameWithoutExtension(projectFilePath); projectFileInfo.TargetFramework = new FrameworkName(properties["TargetFrameworkMoniker"].FinalValue); if (properties.ContainsKey("LangVersion")) { projectFileInfo.SpecifiedLanguageVersion = ToLanguageVersion(properties["LangVersion"].FinalValue); } projectFileInfo.ProjectId = new Guid(properties["ProjectGuid"].FinalValue.TrimStart('{').TrimEnd('}')); projectFileInfo.TargetPath = properties["TargetPath"].FinalValue; // REVIEW: FullPath here returns the wrong physical path, we need to figure out // why. We must be setting up something incorrectly projectFileInfo.SourceFiles = itemsLookup["Compile"] .Select(b => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, b.FinalItemSpec))) .ToList(); projectFileInfo.References = itemsLookup["ReferencePath"] .Where(p => !p.HasMetadata("Project")) .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); projectFileInfo.ProjectReferences = itemsLookup["ProjectReference"] .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); projectFileInfo.Analyzers = itemsLookup["Analyzer"] .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); var allowUnsafe = properties.GetPropertyValue("AllowUnsafeBlocks"); if (!string.IsNullOrWhiteSpace(allowUnsafe)) { projectFileInfo.AllowUnsafe = Convert.ToBoolean(allowUnsafe); } var defineConstants = properties.GetPropertyValue("DefineConstants"); if (!string.IsNullOrWhiteSpace(defineConstants)) { projectFileInfo.DefineConstants = defineConstants.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList(); } var signAssembly = properties["SignAssembly"].FinalValue; if (!string.IsNullOrWhiteSpace(signAssembly)) { projectFileInfo.SignAssembly = Convert.ToBoolean(signAssembly); } projectFileInfo.AssemblyOriginatorKeyFile = properties["AssemblyOriginatorKeyFile"].FinalValue; var documentationFile = properties["DocumentationFile"].FinalValue; if (!string.IsNullOrWhiteSpace(documentationFile)) { projectFileInfo.GenerateXmlDocumentation = true; } #endif } return(projectFileInfo); }
public static ImmutableDictionary <string, ReportDiagnostic> GetDiagnosticOptions(this ProjectFileInfo projectFileInfo) { var suppressions = CompilationOptionsHelper.GetDefaultSuppressedDiagnosticOptions(projectFileInfo.SuppressedDiagnosticIds); var specificRules = projectFileInfo.RuleSet?.SpecificDiagnosticOptions ?? ImmutableDictionary <string, ReportDiagnostic> .Empty; // suppressions capture NoWarn and they have the highest priority var combinedRules = specificRules.Concat(suppressions.Where(x => !specificRules.Keys.Contains(x.Key))).ToDictionary(x => x.Key, x => x.Value); // then handle WarningsAsErrors foreach (var warningAsError in projectFileInfo.WarningsAsErrors) { if (!suppressions.ContainsKey(warningAsError)) { combinedRules[warningAsError] = ReportDiagnostic.Error; } } // WarningsNotAsErrors can overwrite WarningsAsErrors foreach (var warningNotAsError in projectFileInfo.WarningsNotAsErrors) { if (!suppressions.ContainsKey(warningNotAsError)) { combinedRules[warningNotAsError] = ReportDiagnostic.Warn; } } return(combinedRules.ToImmutableDictionary()); }
public static CSharpCompilationOptions CreateCompilationOptions(this ProjectFileInfo projectFileInfo) { var compilationOptions = new CSharpCompilationOptions(projectFileInfo.OutputKind); return(projectFileInfo.CreateCompilationOptions(compilationOptions)); }
public static ImmutableArray <AnalyzerFileReference> ResolveAnalyzerReferencesForProject(this ProjectFileInfo projectFileInfo, IAnalyzerAssemblyLoader analyzerAssemblyLoader) { if (!projectFileInfo.RunAnalyzers || !projectFileInfo.RunAnalyzersDuringLiveAnalysis) { return(ImmutableArray <AnalyzerFileReference> .Empty); } foreach (var analyzerAssemblyPath in projectFileInfo.Analyzers.Distinct()) { analyzerAssemblyLoader.AddDependencyLocation(analyzerAssemblyPath); } return(projectFileInfo.Analyzers.Select(analyzerCandicatePath => new AnalyzerFileReference(analyzerCandicatePath, analyzerAssemblyLoader)).ToImmutableArray()); }
public static ProjectFileInfo Create(ILogger logger, string solutionDirectory, string projectFilePath) { var projectFileInfo = new ProjectFileInfo(); projectFileInfo.ProjectFilePath = projectFilePath; #if ASPNET50 if (!PlatformHelper.IsMono) { var properties = new Dictionary <string, string> { { "DesignTimeBuild", "true" }, { "BuildProjectReferences", "false" }, { "_ResolveReferenceDependencies", "true" }, { "SolutionDir", solutionDirectory + Path.DirectorySeparatorChar } }; var collection = new ProjectCollection(properties); var project = collection.LoadProject(projectFilePath); var projectInstance = project.CreateProjectInstance(); var buildResult = projectInstance.Build("ResolveReferences", loggers: null); if (!buildResult) { return(null); } projectFileInfo.AssemblyName = projectInstance.GetPropertyValue("AssemblyName"); projectFileInfo.Name = projectInstance.GetPropertyValue("ProjectName"); projectFileInfo.TargetFramework = new FrameworkName(projectInstance.GetPropertyValue("TargetFrameworkMoniker")); projectFileInfo.ProjectId = new Guid(projectInstance.GetPropertyValue("ProjectGuid").TrimStart('{').TrimEnd('}')); projectFileInfo.TargetPath = projectInstance.GetPropertyValue("TargetPath"); projectFileInfo.SourceFiles = projectInstance.GetItems("Compile") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); projectFileInfo.References = projectInstance.GetItems("ReferencePath") .Where(p => !string.Equals("ProjectReference", p.GetMetadataValue("ReferenceSourceTarget"), StringComparison.OrdinalIgnoreCase)) .Select(p => p.GetMetadataValue("FullPath")) .ToList(); projectFileInfo.ProjectReferences = projectInstance.GetItems("ProjectReference") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); projectFileInfo.Analyzers = projectInstance.GetItems("Analyzer") .Select(p => p.GetMetadataValue("FullPath")) .ToList(); } else { // On mono we need to use this API since the ProjectCollection // isn't fully implemented #pragma warning disable CS0618 var engine = Engine.GlobalEngine; engine.DefaultToolsVersion = "4.0"; #pragma warning restore CS0618 // engine.RegisterLogger(new ConsoleLogger()); var propertyGroup = new BuildPropertyGroup(); propertyGroup.SetProperty("DesignTimeBuild", "true"); propertyGroup.SetProperty("BuildProjectReferences", "false"); // Dump entire assembly reference closure propertyGroup.SetProperty("_ResolveReferenceDependencies", "true"); propertyGroup.SetProperty("SolutionDir", solutionDirectory + Path.DirectorySeparatorChar); // propertyGroup.SetProperty("MSBUILDENABLEALLPROPERTYFUNCTIONS", "1"); engine.GlobalProperties = propertyGroup; var project = engine.CreateNewProject(); project.Load(projectFilePath); var buildResult = engine.BuildProjectFile(projectFilePath, new[] { "ResolveReferences" }, propertyGroup, null, BuildSettings.None, null); if (!buildResult) { return(null); } var itemsLookup = project.EvaluatedItems.OfType <BuildItem>() .ToLookup(g => g.Name); var properties = project.EvaluatedProperties.OfType <BuildProperty>() .ToDictionary(p => p.Name); projectFileInfo.AssemblyName = properties["AssemblyName"].FinalValue; projectFileInfo.Name = Path.GetFileNameWithoutExtension(projectFilePath); projectFileInfo.TargetFramework = new FrameworkName(properties["TargetFrameworkMoniker"].FinalValue); projectFileInfo.ProjectId = new Guid(properties["ProjectGuid"].FinalValue.TrimStart('{').TrimEnd('}')); projectFileInfo.TargetPath = properties["TargetPath"].FinalValue; // REVIEW: FullPath here returns the wrong physical path, we need to figure out // why. We must be setting up something incorrectly projectFileInfo.SourceFiles = itemsLookup["Compile"] .Select(b => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, b.FinalItemSpec))) .ToList(); projectFileInfo.References = itemsLookup["ReferencePath"] .Where(p => !p.HasMetadata("Project")) .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); projectFileInfo.ProjectReferences = itemsLookup["ProjectReference"] .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); projectFileInfo.Analyzers = itemsLookup["Analyzer"] .Select(p => Path.GetFullPath(Path.Combine(projectFileInfo.ProjectDirectory, p.FinalItemSpec))) .ToList(); } #else // TODO: Shell out to msbuild/xbuild here? #endif return(projectFileInfo); }
public static ImmutableDictionary <string, ReportDiagnostic> GetDiagnosticOptions(this ProjectFileInfo projectFileInfo) { var suppressions = CompilationOptionsHelper.GetDefaultSuppressedDiagnosticOptions(projectFileInfo.SuppressedDiagnosticIds); var specificRules = projectFileInfo.RuleSet?.SpecificDiagnosticOptions ?? ImmutableDictionary <string, ReportDiagnostic> .Empty; // suppressions capture NoWarn and they have the highest priority var combinedRules = specificRules.Concat(suppressions.Where(x => !specificRules.ContainsKey(x.Key))).ToDictionary(x => x.Key, x => x.Value); // then handle WarningsAsErrors foreach (var warningAsError in projectFileInfo.WarningsAsErrors) { if (string.Equals(warningAsError, "nullable", StringComparison.OrdinalIgnoreCase)) { foreach (var id in Errors.NullableWarnings) { AddIfNotSuppressed(id, ReportDiagnostic.Error); } } else { AddIfNotSuppressed(warningAsError, ReportDiagnostic.Error); } } // WarningsNotAsErrors can overwrite WarningsAsErrors foreach (var warningNotAsError in projectFileInfo.WarningsNotAsErrors) { AddIfNotSuppressed(warningNotAsError, ReportDiagnostic.Warn); } return(combinedRules.ToImmutableDictionary()); void AddIfNotSuppressed(string code, ReportDiagnostic diagnostic) { if (!suppressions.ContainsKey(code)) { combinedRules[code] = diagnostic; } } }