Exemplo n.º 1
0
            /// <summary>
            /// Given the properties and dictionary of previously encountered item definitions, evaluates
            /// this specific item definition element and adds to the dictionary as necessary.
            /// </summary>
            /// <exception cref="InvalidProjectFileException">If the item definition is incorrectly defined</exception>
            private void EvaluateItemDefinitionElement(XmlElement itemDefinitionElement, BuildPropertyGroup properties, ItemDefinitionsDictionary itemDefinitionsDictionary)
            {
                ProjectXmlUtilities.VerifyThrowProjectValidNameAndNamespace(itemDefinitionElement);

                XmlAttribute conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(itemDefinitionElement, /* sole attribute */ true);
                string       condition          = ProjectXmlUtilities.GetAttributeValue(conditionAttribute);

                MetadataDictionary metadataDictionary = null;
                string             itemType           = itemDefinitionElement.Name;

                itemDefinitionsDictionary.TryGetValue(itemType, out metadataDictionary);

                Expander expander = new Expander(properties, itemType, metadataDictionary);

                if (!Utilities.EvaluateCondition(condition, conditionAttribute, expander, ParserOptions.AllowPropertiesAndItemMetadata, parentProject))
                {
                    return;
                }

                List <XmlElement> childElements = ProjectXmlUtilities.GetValidChildElements(itemDefinitionElement);

                foreach (XmlElement child in childElements)
                {
                    EvaluateItemDefinitionChildElement(child, properties, itemDefinitionsDictionary);
                }
            }
Exemplo n.º 2
0
            /// <summary>
            /// Given the properties and dictionary of previously encountered item definitions, evaluates
            /// this group of item definitions and adds to the dictionary as necessary.
            /// </summary>
            /// <exception cref="InvalidProjectFileException">If the item definitions are incorrectly defined</exception>
            internal void Evaluate(BuildPropertyGroup properties, ItemDefinitionsDictionary itemDefinitionsDictionary)
            {
                Expander expander = new Expander(properties);

                if (!Utilities.EvaluateCondition(condition, conditionAttribute, expander, ParserOptions.AllowProperties, parentProject))
                {
                    return;
                }

                List <XmlElement> childElements = ProjectXmlUtilities.GetValidChildElements(element);

                foreach (XmlElement child in childElements)
                {
                    EvaluateItemDefinitionElement(child, properties, itemDefinitionsDictionary);
                }
            }
Exemplo n.º 3
0
        internal BuildItemGroupChildXml(XmlElement element, ChildType childTypeExpected)
        {
            ErrorUtilities.VerifyThrow(element != null, "Need an XML node.");
            ErrorUtilities.VerifyThrowNoAssert(childTypeExpected != ChildType.Invalid, "Can't expect invalid childtype");
            ProjectXmlUtilities.VerifyThrowProjectValidNameAndNamespace(element);

            this.element = element;

            // Loop through each of the attributes on the item element.
            foreach (XmlAttribute attribute in element.Attributes)
            {
                switch (attribute.Name)
                {
                case XMakeAttributes.include:
                    this.includeAttribute = attribute;
                    break;

                case XMakeAttributes.exclude:
                    this.excludeAttribute = attribute;
                    break;

                case XMakeAttributes.condition:
                    this.conditionAttribute = attribute;
                    break;

                case XMakeAttributes.xmlns:
                    // We already verified that the namespace is correct
                    break;

                case XMakeAttributes.remove:
                    this.removeAttribute = attribute;
                    break;

                case XMakeAttributes.keepMetadata:
                case XMakeAttributes.removeMetadata:
                case XMakeAttributes.keepDuplicates:
                    // Ignore these - they are part of the new OM.
                    break;

                default:
                    ProjectXmlUtilities.ThrowProjectInvalidAttribute(attribute);
                    break;
                }
            }

            this.childType = ChildType.Invalid;

            // Default to modify, if that's one of the child types we are told to expect.
            if ((childTypeExpected & ChildType.BuildItemModify) == ChildType.BuildItemModify)
            {
                this.childType = ChildType.BuildItemModify;
            }

            if (this.includeAttribute != null)
            {
                ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute((childTypeExpected & ChildType.BuildItemAdd) == ChildType.BuildItemAdd, includeAttribute);
                ProjectErrorUtilities.VerifyThrowInvalidProject(Include.Length > 0, element, "MissingRequiredAttribute", XMakeAttributes.include, element.Name);
                ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute(removeAttribute == null, removeAttribute);
                this.childType = ChildType.BuildItemAdd;
            }

            if (this.excludeAttribute != null)
            {
                ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute((childTypeExpected & ChildType.BuildItemAdd) == ChildType.BuildItemAdd, excludeAttribute);
                ProjectErrorUtilities.VerifyThrowInvalidProject(Include.Length > 0, element, "MissingRequiredAttribute", XMakeAttributes.include, element.Name);
                ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute(removeAttribute == null, removeAttribute);
                this.childType = ChildType.BuildItemAdd;
            }

            if (this.removeAttribute != null)
            {
                ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute((childTypeExpected & ChildType.BuildItemRemove) == ChildType.BuildItemRemove, removeAttribute);
                ProjectErrorUtilities.VerifyThrowInvalidProject(Remove.Length > 0, element, "MissingRequiredAttribute", XMakeAttributes.remove, element.Name);
                ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute(includeAttribute == null, includeAttribute);
                ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute(excludeAttribute == null, excludeAttribute);
                this.childType = ChildType.BuildItemRemove;
            }

            if (this.childType == ChildType.Invalid)
            {
                // So the xml wasn't consistent with any of the child types that we were told to expect.
                // Figure out the most reasonable message to produce.
                if ((childTypeExpected & ChildType.BuildItemAdd) == ChildType.BuildItemAdd)
                {
                    ProjectErrorUtilities.VerifyThrowInvalidProject(Include.Length > 0, element, "MissingRequiredAttribute", XMakeAttributes.include, element.Name);
                }
                else if ((childTypeExpected & ChildType.BuildItemRemove) == ChildType.BuildItemRemove)
                {
                    ProjectErrorUtilities.VerifyThrowInvalidProject(Remove.Length > 0, element, "MissingRequiredAttribute", XMakeAttributes.remove, element.Name);
                }
                else
                {
                    ErrorUtilities.ThrowInternalError("Unexpected child type");
                }
            }

            // Validate each of the child nodes beneath the item.
            List <XmlElement> children = ProjectXmlUtilities.GetValidChildElements(element);

            if (this.childType == ChildType.BuildItemRemove && children.Count != 0)
            {
                ProjectErrorUtilities.ThrowInvalidProject(element, "ChildElementsBelowRemoveNotAllowed", children[0].Name);
            }

            foreach (XmlElement child in children)
            {
                ProjectXmlUtilities.VerifyThrowProjectValidNameAndNamespace(child);

                ProjectErrorUtilities.VerifyThrowInvalidProject(!FileUtilities.IsItemSpecModifier(child.Name), child, "ItemSpecModifierCannotBeCustomMetadata", child.Name);
                ProjectErrorUtilities.VerifyThrowInvalidProject(XMakeElements.IllegalItemPropertyNames[child.Name] == null, child, "CannotModifyReservedItemMetadata", child.Name);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Gets all child elements, ignoring whitespace and comments, and any conditions
        /// </summary>
        internal List <XmlElement> GetChildren()
        {
            List <XmlElement> children = ProjectXmlUtilities.GetValidChildElements(element);

            return(children);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Initializes a persisted target from an existing &lt;Target&gt; element which exists either in the main parent project
        /// file or one of the imported files.
        /// </summary>
        /// <param name="targetElement"></param>
        /// <param name="project"></param>
        /// <param name="importedFromAnotherProject"></param>
        internal Target
        (
            XmlElement targetElement,
            Project project,
            bool importedFromAnotherProject
        )
        {
            // Make sure a valid node has been given to us.
            error.VerifyThrow(targetElement != null, "Need a valid XML node.");

            // Make sure this really is the <target> node.
            ProjectXmlUtilities.VerifyThrowElementName(targetElement, XMakeElements.target);

            this.targetElement              = targetElement;
            this.parentProject              = project;
            this.parentEngine               = project.ParentEngine;
            this.conditionAttribute         = null;
            this.taskElementList            = null;
            this.importedFromAnotherProject = importedFromAnotherProject;
            this.buildState = BuildState.NotStarted;
            this.id         = project.ParentEngine.GetNextTargetId();

            // The target name and target dependendencies (dependencies on other
            // targets) are specified as attributes of the <target> element.

            XmlAttribute returnsAttribute = null;

            // Loop through all the attributes on the <target> element.
            foreach (XmlAttribute targetAttribute in targetElement.Attributes)
            {
                switch (targetAttribute.Name)
                {
                // Process the "condition" attribute.
                case XMakeAttributes.condition:
                    this.conditionAttribute = targetAttribute;
                    break;

                // Process the "name" attribute.
                case XMakeAttributes.name:
                    this.targetName = EscapingUtilities.UnescapeAll(targetAttribute.Value);

                    // Target names cannot contain MSBuild special characters, embedded properties,
                    // or item lists.
                    int indexOfSpecialCharacter = this.targetName.IndexOfAny(XMakeElements.illegalTargetNameCharacters);
                    if (indexOfSpecialCharacter >= 0)
                    {
                        ProjectErrorUtilities.VerifyThrowInvalidProject(false,
                                                                        targetAttribute, "NameInvalid", targetName, targetName[indexOfSpecialCharacter]);
                    }

                    break;

                // Process the "dependsOnTargets" attribute.
                case XMakeAttributes.dependsOnTargets:
                    this.dependsOnTargetsAttribute = targetAttribute;
                    break;

                case XMakeAttributes.inputs:
                    this.inputsAttribute           = targetAttribute;
                    recalculateBatchableParameters = true;
                    break;

                case XMakeAttributes.outputs:
                    this.outputsAttribute          = targetAttribute;
                    recalculateBatchableParameters = true;
                    break;

                // This is only recognized by the new OM:
                // so that the compat tests keep passing,
                // ignore it.
                case XMakeAttributes.keepDuplicateOutputs:
                    break;

                // This is only recognized by the new OM:
                // so that the compat tests keep passing,
                // ignore it.
                case XMakeAttributes.returns:
                    returnsAttribute = targetAttribute;
                    break;

                // These are only recognized by the new OM:
                // while the solution wrapper generator is using
                // the old OM to parse projects for dependencies,
                // we must make sure to not fail for these
                case XMakeAttributes.beforeTargets:
                case XMakeAttributes.afterTargets:
                    break;

                default:
                    ProjectXmlUtilities.ThrowProjectInvalidAttribute(targetAttribute);
                    break;
                }
            }

            // Hack to help the 3.5 engine at least pretend to still be able to build on top of
            // the 4.0 targets.  In cases where there is no Outputs attribute, just a Returns attribute,
            // we can approximate the correct behaviour by making the Returns attribute our "outputs" attribute.
            if (this.outputsAttribute == null && returnsAttribute != null)
            {
                this.outputsAttribute          = returnsAttribute;
                recalculateBatchableParameters = true;
            }

            // It's considered an error if a target does not have a name.
            ProjectErrorUtilities.VerifyThrowInvalidProject((targetName != null) && (targetName.Length > 0),
                                                            targetElement, "MissingRequiredAttribute", XMakeAttributes.name, XMakeElements.target);

            this.taskElementList = new ArrayList();

            // Process each of the child nodes beneath the <Target>.
            XmlElement        anyOnErrorElement = null;
            List <XmlElement> childElements     = ProjectXmlUtilities.GetValidChildElements(targetElement);

            foreach (XmlElement childElement in childElements)
            {
                bool onErrorOutOfOrder = false;
                switch (childElement.Name)
                {
                case XMakeElements.onError:
                    anyOnErrorElement = childElement;
                    break;

                default:
                    onErrorOutOfOrder = (anyOnErrorElement != null);
                    this.taskElementList.Add(new BuildTask(childElement,
                                                           this, this.importedFromAnotherProject));
                    break;
                }

                // Check for out-of-order OnError
                ProjectErrorUtilities.VerifyThrowInvalidProject(!onErrorOutOfOrder,
                                                                anyOnErrorElement, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name);
            }
        }