Ejemplo n.º 1
0
        private IEnumerable <XElement> GetItems(MsbuildFile msbuildFile, Project project, string friendlyQualifierName)
        {
            if (project.Items.Count == 0)
            {
                return(EmptyArray <XElement>());
            }

            string evaluatedQualifierComparisonValue = null;

            if (friendlyQualifierName != null)
            {
                evaluatedQualifierComparisonValue = msbuildFile.GetQualifierComparisonValue(friendlyQualifierName);
            }

            var items = project.Items.OrderBy(grouping => grouping.Key).Select(
                grouping => new XElement(
                    ItemGroupXName,
                    string.IsNullOrEmpty(evaluatedQualifierComparisonValue)
                        ? EmptyArray <XAttribute>()
                        : (object)new XAttribute("Condition", $"'{msbuildFile.UnevaluatedQualifierComparisonProperty}' == '{evaluatedQualifierComparisonValue}'"),
                    grouping
                    .Where(item => !IsExcludedItemInclude(ValueToMsBuild(item.Include, msbuildFile)))
                    .OrderBy(item => ValueToMsBuild(item.Include, msbuildFile), StringComparer.OrdinalIgnoreCase)
                    .Select(
                        item => new XElement(
                            XName.Get(grouping.Key, MsBuildNamespace),
                            new XAttribute("Include", ValueToMsBuild(item.Include, msbuildFile)),
                            item.Metadata
                            .OrderBy(kv => kv.Key)
                            .Select(kv => new XElement(XName.Get(kv.Key, MsBuildNamespace), ValueToMsBuild(kv.Value, msbuildFile)))))));

            return(items);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Merge all projects which are generated from the same spec file with different qualifiers
        /// After merging them, we will have knowledge about which properties or items are conditioned.
        /// </summary>
        private static void CreateConditionedProjects(MsbuildFile msbuildFile)
        {
            // Create a new process project for each old process project. The new ones will not have items and properties.
            // We will put new items and properties below.
            var oldProjects = msbuildFile.ProjectsByQualifier.Values.ToArray();
            var numProjects = oldProjects.Length;

            if (numProjects == 0)
            {
                return;
            }

            // create new projects with same qualifiers
            var newProjects = new Project[oldProjects.Length];

            for (int i = 0; i < oldProjects.Length; i++)
            {
                newProjects[i] = new Project(oldProjects[i].FriendlyQualifier);
            }

            // Find the unconditioned items.
            HashSet <(string, object)> unconditionedValues = null;
            HashSet <(string, object)> projectValues       = new HashSet <ValueTuple <string, object> >();

            foreach (var project in oldProjects)
            {
                projectValues.Clear();
                projectValues.UnionWith(project.Items.SelectMany(grouping => grouping.Select(item => (grouping.Key, item.Include))));
                Context.HandledItemTypes.UnionWith(project.Items.Select(grouping => grouping.Key));

                if (unconditionedValues == null)
                {
                    unconditionedValues = new HashSet <(string, object)>(projectValues);
                }
                else
                {
                    unconditionedValues.IntersectWith(projectValues);
                }
            }

            // Create an unconditioned project with an empty qualifier and populate it with the unconditioned (common) values
            var unconditionedProject = new Project(string.Empty);

            for (int i = 0; i < oldProjects.Length; i++)
            {
                foreach (var itemGroup in oldProjects[i].Items)
                {
                    foreach (var item in itemGroup)
                    {
                        if (!unconditionedValues.Contains((itemGroup.Key, item.Include)))
                        {
                            newProjects[i].AddItem(itemGroup.Key, item);
                        }
Ejemplo n.º 3
0
        private IReadOnlyList <MsbuildFile> GenerateMsbuildFiles()
        {
            var msbuildFiles = new List <MsbuildFile>();

            // Retrieve Process pip nodes. Then, hydrate them and group by their spec path.
            var specFileGroupedProcessPips = m_context
                                             .ScheduledGraph
                                             .Nodes
                                             .Where(nodeId => m_context.PipGraph.PipTable.GetPipType(nodeId.ToPipId()) == PipType.Process)
                                             .Select(nodeId => m_context.PipGraph.PipTable.HydratePip(nodeId.ToPipId(), BuildXL.Pips.PipQueryContext.IdeGenerator))
                                             .GroupBy(p => p.Provenance.Token.Path);

            foreach (var processPips in specFileGroupedProcessPips)
            {
                var specFile             = processPips.Key;
                var categorizedProcesses = processPips
                                           .OfType <Process>()
                                           .Select(p => ProcessWithType.Categorize(m_context, p))
                                           .ToList();

                MsbuildFile msbuildFile = null;
                if (categorizedProcesses.Any(a => a.Type == ProcessType.Csc))
                {
                    msbuildFile = new CsprojFile(m_context, specFile);
                }
                else if (categorizedProcesses.Any(a => a.Type == ProcessType.Cl))
                {
                    msbuildFile = new VcxprojFile(m_context, specFile);
                }

                if (msbuildFile != null)
                {
                    msbuildFile.VisitProcesses(categorizedProcesses);

                    // SealDirectories might not be scheduled so look at the full graph to find them.
                    foreach (var directory in m_context.PipGraph.GetPipsPerSpecFile(specFile).OfType <SealDirectory>())
                    {
                        msbuildFile.VisitDirectory(directory);
                    }

                    msbuildFile.EndVisitingProject();
                    msbuildFiles.Add(msbuildFile);
                }
            }

            return(msbuildFiles);
        }
Ejemplo n.º 4
0
        private string ValueToMsBuild(object value, MsbuildFile msbuildFile, bool isProperty = false)
        {
            if (value is string)
            {
                return(ExpandString((string)value));
            }

            if (value is PathAtom)
            {
                return(((PathAtom)value).ToString(m_context.PathTable.StringTable));
            }

            if (value is AbsolutePath)
            {
                AbsolutePath absolutePath = (AbsolutePath)value;
                if (msbuildFile != null && msbuildFile.SpecDirectory != absolutePath)
                {
                    RelativePath relativePath;

                    // If it is a property, the relative path must be only to the enlistment root.
                    if (!isProperty && msbuildFile.SpecDirectory.TryGetRelative(m_context.PathTable, absolutePath, out relativePath))
                    {
                        var relativePathStr = relativePath.ToString(m_context.PathTable.StringTable);

                        // If we write the project files somewhere else (e.g., out\vs\projects\), combine it with SpecRoot.
                        if (!m_context.CanWriteToSrc)
                        {
                            return(Path.Combine("$(SpecRoot)", relativePathStr));
                        }

                        return(relativePathStr);
                    }
                }

                return(ExpandAbsolutePath(absolutePath));
            }

            if (value is RelativePath)
            {
                return(((RelativePath)value).ToString(m_context.PathTable.StringTable));
            }

            throw new InvalidOperationException("Unexpected content");
        }
Ejemplo n.º 5
0
        private IEnumerable <XElement> GetProperties(MsbuildFile msbuildFile, Project project, string friendlyQualifierName)
        {
            string evaluatedQualifierComparisonValue = null;

            if (friendlyQualifierName != null)
            {
                evaluatedQualifierComparisonValue = msbuildFile.GetQualifierComparisonValue(friendlyQualifierName);
            }

            var properties = new XElement(
                PropertyGroupXName,
                string.IsNullOrEmpty(evaluatedQualifierComparisonValue)
                        ? EmptyArray <XAttribute>()
                        : (object)new XAttribute("Condition", $"'{msbuildFile.UnevaluatedQualifierComparisonProperty}' == '{evaluatedQualifierComparisonValue}'"),
                project.Properties.OrderBy(kv => kv.Key, StringComparer.OrdinalIgnoreCase)
                .Select(kv => new XElement(XName.Get(kv.Key, MsBuildNamespace), ValueToMsBuild(kv.Value, msbuildFile, true))));

            if (properties.HasElements)
            {
                yield return(properties);
            }
        }
Ejemplo n.º 6
0
        private IEnumerable <XElement> GetItems(MsbuildFile msbuildFile, Project project)
        {
            if (project.Items.Count == 0)
            {
                return(EmptyArray <XElement>());
            }

            var items = project.Items.OrderBy(grouping => grouping.Key).Select(
                grouping => new XElement(
                    ItemGroupXName,
                    new XAttribute("Condition", msbuildFile.GenerateConditionalForProject(project)),
                    grouping
                    .Where(item => !IsExcludedItemInclude(ValueToMsBuild(item.Include, msbuildFile)))
                    .OrderBy(item => ValueToMsBuild(item.Include, msbuildFile), StringComparer.OrdinalIgnoreCase)
                    .Select(
                        item => new XElement(
                            XName.Get(grouping.Key),
                            new XAttribute("Include", ValueToMsBuild(item.Include, msbuildFile)),
                            item.Metadata
                            .OrderBy(kv => kv.Key)
                            .Select(kv => new XElement(XName.Get(kv.Key), ValueToMsBuild(kv.Value, msbuildFile)))))));

            return(items);
        }
Ejemplo n.º 7
0
 private IEnumerable <XElement> GetProperties(MsbuildFile msbuildFile, IEnumerable <KeyValuePair <string, object> > properties, string condition = null)
 {
     return(properties
            .OrderBy(kv => kv.Key, StringComparer.OrdinalIgnoreCase)
            .Select(kv => new XElement(XName.Get(kv.Key), ValueToMsBuild(kv.Value, msbuildFile, true))));
 }
Ejemplo n.º 8
0
 private bool EqualMsBuildValues(MsbuildFile msbuildFile, object lhs, object rhs)
 {
     return
         (ValueToMsBuild(lhs, msbuildFile, isProperty: true) ==
          ValueToMsBuild(rhs, msbuildFile, isProperty: true));
 }