Example #1
0
 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;
        }
Example #3
0
        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());
        }
Example #11
0
        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;
                }
            }
        }