示例#1
0
        public ImmutableDictionary <string, ImmutableDictionary <string, string> > DetermineConfigurations(IProjectRootElement projectRootElement)
        {
            var builder = ImmutableDictionary.CreateBuilder <string, ImmutableDictionary <string, string> >();

            foreach (var propertyGroup in projectRootElement.PropertyGroups)
            {
                if (MSBuildHelpers.ConditionToDimensionValues(propertyGroup.Condition, out var dimensionValues))
                {
                    var name = MSBuildHelpers.GetConfigurationName(dimensionValues);
                    builder.Add(name, dimensionValues.ToImmutableDictionary());
                }
            }

            return(builder.ToImmutable());
        }
示例#2
0
        public MSBuildWorkspace(ImmutableArray <string> paths, bool noBackup)
        {
            var items = ImmutableArray.CreateBuilder <MSBuildWorkspaceItem>();

            var globalProperties = ImmutableDictionary <string, string> .Empty;

            using var collection = new ProjectCollection();

            foreach (var path in paths)
            {
                var fileExtension = Path.GetExtension(path);
                if ((StringComparer.OrdinalIgnoreCase.Compare(fileExtension, ".fsproj") != 0) &&
                    (StringComparer.OrdinalIgnoreCase.Compare(fileExtension, ".csproj") != 0) &&
                    (StringComparer.OrdinalIgnoreCase.Compare(fileExtension, ".vbproj") != 0))
                {
                    Console.WriteLine($"'{path}' is not a .NET project, skipping it.");
                    continue;
                }

                var root = new MSBuildProjectRootElement(ProjectRootElement.Open(path, collection, preserveFormatting: true));
                if (IsSupportedProjectType(root))
                {
                    if (!noBackup)
                    {
                        File.Copy(path, path + ".old");
                    }

                    // Let them know about System.Web
                    if (MSBuildHelpers.IsProjectReferencingSystemWeb(root))
                    {
                        Console.WriteLine($"'{root.FullPath}' references System.Web, which is unsupported on .NET Core. You may have significant work remaining after conversion.");
                    }

                    var configurations = DetermineConfigurations(root);

                    var unconfiguredProject = new UnconfiguredProject(configurations);
                    unconfiguredProject.LoadProjects(collection, globalProperties, path);

                    var baseline = CreateSdkBaselineProject(path, unconfiguredProject.FirstConfiguredProject, root, configurations);
                    root.Reload(throwIfUnsavedChanges: false, preserveFormatting: true);

                    var item = new MSBuildWorkspaceItem(root, unconfiguredProject, baseline);
                    items.Add(item);
                }
            }

            WorkspaceItems = items.ToImmutable();
        }
示例#3
0
        /// <summary>
        /// Clear out the project's construction model and add a simple SDK-based project to get a baseline.
        /// We need to use the same name as the original csproj and same path so that all the default that derive
        /// from name\path get the right values (there are a lot of them).
        /// </summary>
        private BaselineProject CreateSdkBaselineProject(string projectFilePath, IProject project, IProjectRootElement root, ImmutableDictionary <string, ImmutableDictionary <string, string> > configurations)
        {
            var projectStyle = GetProjectStyle(root);
            var rootElement  = ProjectRootElement.Open(projectFilePath);

            rootElement.RemoveAllChildren();
            switch (projectStyle)
            {
            case ProjectStyle.Default:
            case ProjectStyle.DefaultSubset:
                rootElement.Sdk = MSBuildFacts.DefaultSDKAttribute;
                break;

            case ProjectStyle.WindowsDesktop:
                rootElement.Sdk = DesktopFacts.WinSDKAttribute;
                break;

            case ProjectStyle.DefaultWithCustomTargets:
                var imports = root.Imports;

                void CopyImport(ProjectImportElement import)
                {
                    var newImport = rootElement.AddImport(import.Project);

                    newImport.Condition = import.Condition;
                }

                CopyImport(imports.First());
                CopyImport(imports.Last());
                break;

            default:
                throw new NotSupportedException("This project has custom imports in a manner that's not supported.");
            }

            var propGroup = rootElement.AddPropertyGroup();

            propGroup.AddProperty(MSBuildFacts.TargetFrameworkNodeName, project.GetTargetFramework());
            propGroup.AddProperty(MSBuildFacts.OutputTypeNodeName, project.GetPropertyValue(MSBuildFacts.OutputTypeNodeName) ?? throw new InvalidOperationException("OutputType is not set!"));

            if (projectStyle == ProjectStyle.WindowsDesktop)
            {
                if (MSBuildHelpers.IsWinForms(root))
                {
                    MSBuildHelpers.AddUseWinForms(propGroup);
                }

                if (MSBuildHelpers.IsWPF(root))
                {
                    MSBuildHelpers.AddUseWPF(propGroup);
                }

                // User is referencing WindowsBase only
                if (MSBuildHelpers.IsDesktop(root) && !MSBuildHelpers.HasWPFOrWinForms(propGroup))
                {
                    MSBuildHelpers.AddUseWinForms(propGroup);
                }
            }

            // Create a new collection because a project with this name has already been loaded into the global collection.
            using var pc = new ProjectCollection();
            var newProject = new UnconfiguredProject(configurations);

            newProject.LoadProjects(pc, rootElement);

            // If the original project had the TargetFramework property don't touch it during conversion.
            var propertiesInTheBaseline = ImmutableArray.Create(MSBuildFacts.OutputTypeNodeName);

            if (project.GetProperty(MSBuildFacts.TargetFrameworkNodeName) is { })
示例#4
0
 /// <summary>
 /// Checks if an item is an explicit System.ValueTuple and if the given TFM correspondes with an in-box System.ValueTuple type.
 /// </summary>
 public static bool IsExplicitValueTupleReferenceThatCanBeRemoved(ProjectItemElement item, string tfm) =>
 item.ElementName.Equals(MSBuildFacts.MSBuildReferenceName, StringComparison.OrdinalIgnoreCase) &&
 item.Include.Equals(MSBuildFacts.SystemValueTupleName, StringComparison.OrdinalIgnoreCase) &&
 MSBuildHelpers.FrameworkHasAValueTuple(tfm);