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>
        /// Constructor for the When block.  Parses the contents of the When block (property
        /// groups, item groups, and nested chooses) and stores them.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <owner>DavidLe</owner>
        /// <param name="parentProject"></param>
        /// <param name="parentGroupingCollection"></param>
        /// <param name="whenElement"></param>
        /// <param name="importedFromAnotherProject"></param>
        /// <param name="options"></param>
        /// <param name="nestingDepth">stack overflow guard</param>
        internal When(
            Project parentProject,
            GroupingCollection parentGroupingCollection,
            XmlElement whenElement,
            bool importedFromAnotherProject,
            Options options,
            int nestingDepth
            )
        {
            // Make sure the <When> node has been given to us.
            error.VerifyThrow(whenElement != null, "Need valid (non-null) <When> element.");

            // Make sure this really is the <When> node.
            error.VerifyThrow(whenElement.Name == XMakeElements.when || whenElement.Name == XMakeElements.otherwise,
                              "Expected <{0}> or <{1}> element; received <{2}> element.",
                              XMakeElements.when, XMakeElements.otherwise, whenElement.Name);

            this.propertyAndItemLists = new GroupingCollection(parentGroupingCollection);
            this.parentProject        = parentProject;

            string elementName = ((options == Options.ProcessWhen) ? XMakeElements.when : XMakeElements.otherwise);

            if (options == Options.ProcessWhen)
            {
                conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(whenElement, /*verify sole attribute*/ true);
                ProjectErrorUtilities.VerifyThrowInvalidProject(conditionAttribute != null, whenElement, "MissingCondition", XMakeElements.when);
            }
            else
            {
                ProjectXmlUtilities.VerifyThrowProjectNoAttributes(whenElement);
            }

            ProcessWhenChildren(whenElement, parentProject, importedFromAnotherProject, nestingDepth);
        }
Exemplo n.º 3
0
        /// <summary>
        /// BuildItemGroup element is provided
        /// </summary>
        internal BuildItemGroupXml(XmlElement element)
        {
            ErrorUtilities.VerifyThrowNoAssert(element != null, "Need a valid XML node.");
            ProjectXmlUtilities.VerifyThrowElementName(element, XMakeElements.itemGroup);

            this.element            = element;
            this.conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(element, true /*no other attributes allowed*/);
        }
Exemplo n.º 4
0
        /// <summary>
        /// This constructor allows all output data to be initialized.
        /// </summary>
        /// <owner>SumedhK</owner>
        /// <param name="node">The XML element for the Output tag.</param>
        internal TaskOutput(XmlElement node)
        {
            ErrorUtilities.VerifyThrow(node != null, "Need the XML for the <Output> tag.");

            ProjectXmlUtilities.VerifyThrowProjectNoChildElements(node);

            int    requiredData = 0;
            string taskName     = node.ParentNode.Name;

            foreach (XmlAttribute outputAttribute in node.Attributes)
            {
                switch (outputAttribute.Name)
                {
                case XMakeAttributes.taskParameter:
                    ProjectErrorUtilities.VerifyThrowInvalidProject(outputAttribute.Value.Length > 0, outputAttribute,
                                                                    "InvalidAttributeValue", outputAttribute.Value, outputAttribute.Name, XMakeElements.output);
                    ProjectErrorUtilities.VerifyThrowInvalidProject(!XMakeAttributes.IsSpecialTaskAttribute(outputAttribute.Value) && !XMakeAttributes.IsBadlyCasedSpecialTaskAttribute(outputAttribute.Value), outputAttribute,
                                                                    "BadlyCasedSpecialTaskAttribute", outputAttribute.Value, taskName, taskName);
                    this.taskParameterAttribute = outputAttribute;
                    break;

                case XMakeAttributes.itemName:
                    ProjectErrorUtilities.VerifyThrowInvalidProject(outputAttribute.Value.Length > 0, outputAttribute,
                                                                    "InvalidAttributeValue", outputAttribute.Value, outputAttribute.Name, XMakeElements.output);
                    this.itemNameAttribute = outputAttribute;
                    requiredData++;
                    break;

                case XMakeAttributes.propertyName:
                    ProjectErrorUtilities.VerifyThrowInvalidProject(outputAttribute.Value.Length > 0, outputAttribute,
                                                                    "InvalidAttributeValue", outputAttribute.Value, outputAttribute.Name, XMakeElements.output);
                    ProjectErrorUtilities.VerifyThrowInvalidProject(!ReservedPropertyNames.IsReservedProperty(outputAttribute.Value), node,
                                                                    "CannotModifyReservedProperty", outputAttribute.Value);
                    this.propertyNameAttribute = outputAttribute;
                    requiredData++;
                    break;

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

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

            /* NOTE:
             *  TaskParameter must be specified
             *  either ItemName or PropertyName must be specified
             *  if ItemName is specified, then PropertyName cannot be specified
             *  if PropertyName is specified, then ItemName cannot be specified
             *  only Condition is truly optional
             */
            ProjectErrorUtilities.VerifyThrowInvalidProject((this.taskParameterAttribute != null) && (requiredData == 1),
                                                            node, "InvalidTaskOutputSpecification", taskName);
        }
Exemplo n.º 5
0
            /// <summary>
            /// Read in and validate an &lt;ItemDefinitionGroup&gt; element and all its children.
            /// This is currently only called from ItemDefinitionLibrary. Projects don't know about it.
            /// </summary>
            internal BuildItemDefinitionGroupXml(XmlElement element, Project parentProject)
            {
                ProjectXmlUtilities.VerifyThrowElementName(element, XMakeElements.itemDefinitionGroup);
                ProjectXmlUtilities.VerifyThrowProjectValidNamespace(element);

                this.element            = element;
                this.parentProject      = parentProject;
                this.conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(element, /* sole attribute */ true);
                this.condition          = ProjectXmlUtilities.GetAttributeValue(conditionAttribute);

                // Currently, don't bother validating the children until evaluation time
            }
Exemplo n.º 6
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.º 7
0
            /// <summary>
            /// Given the properties and dictionary of previously encountered item definitions, evaluates
            /// this specific item definition child element and adds to the dictionary as necessary.
            /// </summary>
            /// <exception cref="InvalidProjectFileException">If the item definition is incorrectly defined</exception>
            private void EvaluateItemDefinitionChildElement(XmlElement itemDefinitionChildElement, BuildPropertyGroup properties, ItemDefinitionsDictionary itemDefinitionsDictionary)
            {
                ProjectXmlUtilities.VerifyThrowProjectValidNameAndNamespace(itemDefinitionChildElement);
                ProjectErrorUtilities.VerifyThrowInvalidProject(!FileUtilities.IsItemSpecModifier(itemDefinitionChildElement.Name), itemDefinitionChildElement, "ItemSpecModifierCannotBeCustomMetadata", itemDefinitionChildElement.Name);
                ProjectErrorUtilities.VerifyThrowInvalidProject(XMakeElements.IllegalItemPropertyNames[itemDefinitionChildElement.Name] == null, itemDefinitionChildElement, "CannotModifyReservedItemMetadata", itemDefinitionChildElement.Name);

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

                MetadataDictionary metadataDictionary = null;
                string             itemType           = itemDefinitionChildElement.ParentNode.Name;

                itemDefinitionsDictionary.TryGetValue(itemType, out metadataDictionary);

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

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

                string unevaluatedMetadataValue = Utilities.GetXmlNodeInnerContents(itemDefinitionChildElement);

                bool containsItemVector = ItemExpander.ExpressionContainsItemVector(unevaluatedMetadataValue);

                // We don't allow expressions like @(foo) in the value, as no items exist at this point.
                ProjectErrorUtilities.VerifyThrowInvalidProject(!containsItemVector, itemDefinitionChildElement, "MetadataDefinitionCannotContainItemVectorExpression", unevaluatedMetadataValue, itemDefinitionChildElement.Name);

                string evaluatedMetadataValue = expander.ExpandAllIntoStringLeaveEscaped(unevaluatedMetadataValue, itemDefinitionChildElement);

                if (metadataDictionary == null)
                {
                    metadataDictionary = new MetadataDictionary(StringComparer.OrdinalIgnoreCase);
                    itemDefinitionsDictionary.Add(itemType, metadataDictionary);
                }

                // We only store the evaluated value; build items store the unevaluated value as well, but apparently only to
                // gather recursive portions (its re-evaluation always goes back to the XML).
                // Overwrite any existing default value for this particular metadata
                metadataDictionary[itemDefinitionChildElement.Name] = evaluatedMetadataValue;
            }
Exemplo n.º 8
0
        /// <summary>
        /// Modifies items in the world - specifically, changes their metadata. Changes to items that are part of the project manifest are backed up, so
        /// they can be reverted when the project is reset after the end of the build.
        /// </summary>
        /// <param name="child"></param>
        /// <param name="bucket"></param>
        private void ExecuteModify(BuildItemGroupChildXml child, ItemBucket bucket)
        {
            if (!Utilities.EvaluateCondition(child.Condition, child.ConditionAttribute, bucket.Expander, ParserOptions.AllowAll, loggingServices, buildEventContext))
            {
                return;
            }

            BuildItemGroup group = (BuildItemGroup)bucket.Lookup.GetItems(child.Name);

            if (group == null)
            {
                // No items of this type to modify
                return;
            }

            // Figure out what metadata names and values we need to set
            Dictionary <string, string> metadataToSet = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            List <XmlElement> metadataElements = child.GetChildren();

            foreach (XmlElement metadataElement in metadataElements)
            {
                bool         metadataCondition  = true;
                XmlAttribute conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(metadataElement, true /*no other attributes allowed*/);

                if (conditionAttribute != null)
                {
                    metadataCondition = Utilities.EvaluateCondition(conditionAttribute.Value, conditionAttribute, bucket.Expander, ParserOptions.AllowAll, loggingServices, buildEventContext);
                }

                if (metadataCondition)
                {
                    string unevaluatedMetadataValue = Utilities.GetXmlNodeInnerContents(metadataElement);
                    string evaluatedMetadataValue   = bucket.Expander.ExpandAllIntoStringLeaveEscaped(unevaluatedMetadataValue, metadataElement);
                    // The last metadata with a particular name, wins, so we just set through the indexer here.
                    metadataToSet[metadataElement.Name] = evaluatedMetadataValue;
                }
            }

            bucket.Lookup.ModifyItems(child.Name, group, metadataToSet);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Sets or removes an attribute from the target element. Marks the target dirty after the update
        /// </summary>
        /// <param name="attributeName"></param>
        /// <param name="attributeValue"></param>
        /// <returns>XmlAttribute which has been updated</returns>
        internal XmlAttribute SetOrRemoveTargetAttribute
            (
            string attributeName,
            string attributeValue
            )
        {
            // If this Target object is not actually represented by a 
            // <Target> element in the parentProject.file, then do not allow
            // the caller to set the condition.
            error.VerifyThrowInvalidOperation(this.targetElement != null, "CannotSetCondition");

            // If this item was imported from another parentProject. we don't allow modifying it.
            error.VerifyThrowInvalidOperation(!this.importedFromAnotherProject, "CannotModifyImportedProjects");

            XmlAttribute updatedAttribute = ProjectXmlUtilities.SetOrRemoveAttribute(targetElement, attributeName, attributeValue);

            // Mark the project dirty after an attribute has been updated
            this.MarkTargetAsDirty();

            return updatedAttribute;
        }
Exemplo n.º 10
0
        /// <summary>
        /// Constructor, that initializes the property with cloned information.
        ///
        /// Callers -- Please ensure that the propertyValue passed into this constructor
        /// is actually computed by calling GetXmlNodeInnerContents on the propertyElement.
        /// </summary>
        /// <param name="propertyElement"></param>
        /// <param name="propertyValue"></param>
        /// <param name="propertyType"></param>
        /// <owner>rgoel</owner>
        private BuildProperty
        (
            XmlElement propertyElement,
            string propertyValue,
            PropertyType propertyType
        )
        {
            // Make sure the property node has been given to us.
            ErrorUtilities.VerifyThrow(propertyElement != null,
                                       "Need an XML node representing the property element.");

            // Validate that the property name doesn't contain any illegal characters.
            XmlUtilities.VerifyThrowProjectValidElementName(propertyElement);

            this.propertyElement = propertyElement;

            // Loop through the list of attributes on the property element.
            foreach (XmlAttribute propertyAttribute in propertyElement.Attributes)
            {
                switch (propertyAttribute.Name)
                {
                case XMakeAttributes.condition:
                    // We found the "condition" attribute.  Process it.
                    this.conditionAttribute = propertyAttribute;
                    break;

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

            this.propertyValue     = propertyValue;
            this.finalValueEscaped = propertyValue;
            this.type = propertyType;
        }
Exemplo n.º 11
0
        /// <summary>
        /// Used to load information about default MSBuild tasks i.e. tasks that do not need to be explicitly declared in projects
        /// with the &lt;UsingTask&gt; element. Default task information is read from special files, which are located in the same
        /// directory as the MSBuild binaries.
        /// </summary>
        /// <remarks>
        /// 1) a default tasks file needs the &lt;Project&gt; root tag in order to be well-formed
        /// 2) the XML declaration tag &lt;?xml ...&gt; is ignored
        /// 3) comment tags are always ignored regardless of their placement
        /// 4) the rest of the tags are expected to be &lt;UsingTask&gt; tags
        /// </remarks>
        private void RegisterDefaultTasks(BuildEventContext buildEventContext)
        {
            if (!defaultTasksRegistrationAttempted)
            {
                try
                {
                    this.defaultTaskRegistry = new TaskRegistry();

                    string[] defaultTasksFiles = { };

                    try
                    {
                        defaultTasksFiles = getFiles(toolset.ToolsPath, defaultTasksFilePattern);

                        if (defaultTasksFiles.Length == 0)
                        {
                            loggingServices.LogWarning(buildEventContext, new BuildEventFileInfo(/* this warning truly does not involve any file */ String.Empty),
                                                       "DefaultTasksFileLoadFailureWarning",
                                                       defaultTasksFilePattern, toolset.ToolsPath, String.Empty);
                        }
                    }
                    // handle security problems when finding the default tasks files
                    catch (UnauthorizedAccessException e)
                    {
                        loggingServices.LogWarning(buildEventContext, new BuildEventFileInfo(/* this warning truly does not involve any file */ String.Empty),
                                                   "DefaultTasksFileLoadFailureWarning",
                                                   defaultTasksFilePattern, toolset.ToolsPath, e.Message);
                    }
                    // handle problems when reading the default tasks files
                    catch (Exception e) // Catching Exception, but rethrowing unless it's an IO related exception.
                    {
                        if (ExceptionHandling.NotExpectedException(e))
                        {
                            throw;
                        }

                        loggingServices.LogWarning(buildEventContext, new BuildEventFileInfo(/* this warning truly does not involve any file */ String.Empty),
                                                   "DefaultTasksFileLoadFailureWarning",
                                                   defaultTasksFilePattern, toolset.ToolsPath, e.Message);
                    }

                    BuildPropertyGroup propertyBag = null;

                    foreach (string defaultTasksFile in defaultTasksFiles)
                    {
                        try
                        {
                            XmlDocument defaultTasks = loadXmlFromPath(defaultTasksFile);

                            // look for the first root tag that is not a comment or an XML declaration -- this should be the <Project> tag
                            // NOTE: the XML parser will guarantee there is only one real root element in the file
                            // but we need to find it amongst the other types of XmlNode at the root.
                            foreach (XmlNode topLevelNode in defaultTasks.ChildNodes)
                            {
                                if (XmlUtilities.IsXmlRootElement(topLevelNode))
                                {
                                    ProjectErrorUtilities.VerifyThrowInvalidProject(topLevelNode.LocalName == XMakeElements.project,
                                                                                    topLevelNode, "UnrecognizedElement", topLevelNode.Name);

                                    ProjectErrorUtilities.VerifyThrowInvalidProject((topLevelNode.Prefix.Length == 0) && (String.Equals(topLevelNode.NamespaceURI, XMakeAttributes.defaultXmlNamespace, StringComparison.OrdinalIgnoreCase)),
                                                                                    topLevelNode, "ProjectMustBeInMSBuildXmlNamespace", XMakeAttributes.defaultXmlNamespace);

                                    // the <Project> tag can only the XML namespace -- no other attributes
                                    foreach (XmlAttribute projectAttribute in topLevelNode.Attributes)
                                    {
                                        ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute(projectAttribute.Name == XMakeAttributes.xmlns, projectAttribute);
                                    }

                                    // look at all the child tags of the <Project> root tag we found
                                    foreach (XmlNode usingTaskNode in topLevelNode.ChildNodes)
                                    {
                                        if (usingTaskNode.NodeType != XmlNodeType.Comment)
                                        {
                                            ProjectErrorUtilities.VerifyThrowInvalidProject(usingTaskNode.Name == XMakeElements.usingTask,
                                                                                            usingTaskNode, "UnrecognizedElement", usingTaskNode.Name);

                                            // Initialize the property bag if it hasn't been already.
                                            if (propertyBag == null)
                                            {
                                                // Set the value of the MSBuildBinPath/ToolsPath properties.
                                                BuildPropertyGroup reservedPropertyBag = new BuildPropertyGroup();

                                                reservedPropertyBag.SetProperty(
                                                    new BuildProperty(ReservedPropertyNames.binPath, EscapingUtilities.Escape(toolset.ToolsPath),
                                                                      PropertyType.ReservedProperty));

                                                reservedPropertyBag.SetProperty(
                                                    new BuildProperty(ReservedPropertyNames.toolsPath, EscapingUtilities.Escape(toolset.ToolsPath),
                                                                      PropertyType.ReservedProperty));

                                                // Also set MSBuildAssemblyVersion so that the tasks file can tell between v4 and v12 MSBuild
                                                reservedPropertyBag.SetProperty(
                                                    new BuildProperty(ReservedPropertyNames.assemblyVersion, Constants.AssemblyVersion,
                                                                      PropertyType.ReservedProperty));

                                                propertyBag = new BuildPropertyGroup();
                                                propertyBag.ImportInitialProperties(parentEngine.EnvironmentProperties, reservedPropertyBag, BuildProperties, parentEngine.GlobalProperties);
                                            }

                                            defaultTaskRegistry.RegisterTask(new UsingTask((XmlElement)usingTaskNode, true), new Expander(propertyBag), loggingServices, buildEventContext);
                                        }
                                    }

                                    break;
                                }
                            }
                        }
                        // handle security problems when loading the default tasks file
                        catch (UnauthorizedAccessException e)
                        {
                            loggingServices.LogError(buildEventContext, new BuildEventFileInfo(defaultTasksFile), "DefaultTasksFileFailure", e.Message);
                            break;
                        }
                        // handle problems when loading the default tasks file
                        catch (IOException e)
                        {
                            loggingServices.LogError(buildEventContext, new BuildEventFileInfo(defaultTasksFile), "DefaultTasksFileFailure", e.Message);
                            break;
                        }
                        // handle XML errors in the default tasks file
                        catch (XmlException e)
                        {
                            ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(false, new BuildEventFileInfo(e),
                                                                                    "DefaultTasksFileFailure", e.Message);
                        }
                    }
                }
                finally
                {
                    defaultTasksRegistrationAttempted = true;
                }
            }
        }
Exemplo n.º 12
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.º 13
0
        /// <summary>
        /// Constructor for the Choose object.  Parses the contents of the Choose
        /// and sets up list of When blocks
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <owner>DavidLe</owner>
        /// <param name="parentProject"></param>
        /// <param name="parentGroupingCollection"></param>
        /// <param name="chooseElement"></param>
        /// <param name="importedFromAnotherProject"></param>
        /// <param name="nestingDepth">stack overflow guard</param>
        internal Choose
        (
            Project parentProject,
            GroupingCollection parentGroupingCollection,
            XmlElement chooseElement,
            bool importedFromAnotherProject,
            int nestingDepth
        )
        {
            whenClauseList = new ArrayList();

            error.VerifyThrow(chooseElement != null, "Need valid <Choose> element.");

            // Make sure this really is the <Choose> node.
            ProjectXmlUtilities.VerifyThrowElementName(chooseElement, XMakeElements.choose);

            // Stack overflow guard. The only way in the MSBuild file format that MSBuild elements can be
            // legitimately nested without limit is the <Choose> construct. So, enforce a nesting limit
            // to avoid blowing our stack.
            nestingDepth++;
            ProjectErrorUtilities.VerifyThrowInvalidProject(nestingDepth <= maximumChooseNesting, chooseElement, "ChooseOverflow", maximumChooseNesting);

            this.importedFromAnotherProject = importedFromAnotherProject;

            // This <Choose> is coming from an existing XML element, so
            // walk through all the attributes and child elements, creating the
            // necessary When objects.

            // No attributes on the <Choose> element, so don't allow any.
            ProjectXmlUtilities.VerifyThrowProjectNoAttributes(chooseElement);

            bool foundOtherwise = false;

            // Loop through the child nodes of the <Choose> element.
            foreach (XmlNode chooseChildNode in chooseElement)
            {
                switch (chooseChildNode.NodeType)
                {
                // Handle XML comments under the <PropertyGroup> node (just ignore them).
                case XmlNodeType.Comment:
                // fall through
                case XmlNodeType.Whitespace:
                    // ignore whitespace
                    break;

                case XmlNodeType.Element:
                    // The only two types of child nodes that a <Choose> element can contain
                    // is are <When> elements and zero or one <Otherwise> elements.

                    ProjectXmlUtilities.VerifyThrowProjectValidNamespace((XmlElement)chooseChildNode);

                    if (chooseChildNode.Name == XMakeElements.when)
                    {
                        // don't allow <When> to follow <Otherwise>
                        ProjectErrorUtilities.VerifyThrowInvalidProject(!foundOtherwise,
                                                                        chooseChildNode, "WhenNotAllowedAfterOtherwise");
                        When newWhen = new When(parentProject,
                                                parentGroupingCollection,
                                                (XmlElement)chooseChildNode,
                                                importedFromAnotherProject,
                                                When.Options.ProcessWhen,
                                                nestingDepth);
                        this.whenClauseList.Add(newWhen);
                    }
                    else if (chooseChildNode.Name == XMakeElements.otherwise)
                    {
                        ProjectErrorUtilities.VerifyThrowInvalidProject(!foundOtherwise,
                                                                        chooseChildNode, "MultipleOtherwise");
                        When newWhen = new When(parentProject,
                                                parentGroupingCollection,
                                                (XmlElement)chooseChildNode,
                                                importedFromAnotherProject,
                                                When.Options.ProcessOtherwise,
                                                nestingDepth);
                        otherwiseClause = newWhen;
                        foundOtherwise  = true;
                    }
                    else
                    {
                        ProjectXmlUtilities.ThrowProjectInvalidChildElement(chooseChildNode);
                    }
                    break;

                default:
                    // Unrecognized child element.
                    ProjectXmlUtilities.ThrowProjectInvalidChildElement(chooseChildNode);
                    break;
                }
            }
            ProjectErrorUtilities.VerifyThrowInvalidProject(this.whenClauseList.Count != 0,
                                                            chooseElement, "ChooseMustContainWhen");
        }
Exemplo n.º 14
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.º 15
0
        /// <summary>
        /// Internal constructor
        /// </summary>
        /// <param name="importElement"></param>
        /// <param name="isImported"></param>
        /// <owner>LukaszG</owner>
        internal Import(XmlElement importElement, Project parentProject, bool isImported)
        {
            this.importedFromAnotherProject = isImported;

            // Make sure the <Import> node has been given to us.
            ErrorUtilities.VerifyThrow(importElement != null,
                                       "Need an XML node representing the <Import> element.");

            this.importElement = importElement;

            // Make sure we have a valid parent Project
            ErrorUtilities.VerifyThrow(parentProject != null,
                                       "Need a parent Project object to instantiate an Import.");

            this.parentProject = parentProject;

            // Make sure this really is the <Import> node.
            ProjectXmlUtilities.VerifyThrowElementName(importElement, XMakeElements.import);

            // Loop through the list of attributes on the <Import> element.
            foreach (XmlAttribute importAttribute in importElement.Attributes)
            {
                switch (importAttribute.Name)
                {
                // The "project" attribute points us at the project file to import.
                case XMakeAttributes.project:
                    // Just store the attribute value at this point. We want to make sure that we evaluate any
                    // Condition attribute before looking at the Project attribute - if the Condition is going to be false,
                    // it's legitimate for the value of the Project attribute to be completely invalid.
                    // For example, <Import Project="$(A)" Condition="$(A)!=''"/> should not cause an error
                    // that the Project attribute is empty.
                    this.projectPathAttribute = importAttribute;
                    break;

                // If the "condition" attribute is present, then it must evaluate to "true".
                case XMakeAttributes.condition:
                    this.conditionAttribute = importAttribute;
                    break;

                // We've come across an attribute in the <Import> element that we
                // don't recognize.  Fail due to invalid project file.
                default:
                    ProjectXmlUtilities.ThrowProjectInvalidAttribute(importAttribute);
                    break;
                }
            }

            ProjectErrorUtilities.VerifyThrowInvalidProject((this.projectPathAttribute != null) && (this.projectPathAttribute.Value.Length != 0),
                                                            importElement, "MissingRequiredAttribute",
                                                            XMakeAttributes.project, XMakeElements.import);

            // Make sure this node has no children.  Our schema doesn't support having
            // children beneath the <Import> element.
            if (importElement.HasChildNodes)
            {
                // Don't put the "if" condition inside the first parameter to
                // VerifyThrow..., because we'll get null reference exceptions,
                // since the parameter importElement.FirstChild.Name is being
                // passed in regardless of whether the condition holds true or not.
                ProjectXmlUtilities.ThrowProjectInvalidChildElement(importElement.FirstChild);
            }
        }
Exemplo n.º 16
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);
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// Helper method for processing the children of a When. Only parses Choose,
        /// PropertyGroup, and ItemGroup. All other tags result in an error.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <owner>DavidLe</owner>
        /// <param name="parentNode"></param>
        /// <param name="parentProjectForChildren"></param>
        /// <param name="importedFromAnotherProject"></param>
        /// <param name="options"></param>
        /// <param name="nestingDepth">Number of parent &lt;Choose&gt; elements this is nested inside</param>
        private void ProcessWhenChildren
        (
            XmlElement parentNode,
            Project parentProjectForChildren, bool importedFromAnotherProject,
            int nestingDepth
        )
        {
            // Loop through the child nodes of the <When> element.
            foreach (XmlNode whenChildNode in parentNode)
            {
                switch (whenChildNode.NodeType)
                {
                // Handle XML comments under the <When> node (just ignore them).
                case XmlNodeType.Comment:
                // fall through
                case XmlNodeType.Whitespace:
                    // ignore whitespace
                    break;

                case XmlNodeType.Element:
                {
                    // Make sure this element doesn't have a custom namespace
                    ProjectXmlUtilities.VerifyThrowProjectValidNamespace((XmlElement)whenChildNode);

                    // The only three types of child nodes that a <When> element can contain
                    // are <PropertyGroup>, <ItemGroup> and <Choose>.
                    switch (whenChildNode.Name)
                    {
                    case XMakeElements.itemGroup:
                        BuildItemGroup newItemGroup = new BuildItemGroup((XmlElement)whenChildNode, importedFromAnotherProject, parentProjectForChildren);
                        this.propertyAndItemLists.InsertAtEnd(newItemGroup);
                        break;

                    // Process the <PropertyGroup> element.
                    case XMakeElements.propertyGroup:
                        BuildPropertyGroup newPropertyGroup = new BuildPropertyGroup(parentProjectForChildren, (XmlElement)whenChildNode, importedFromAnotherProject);
                        newPropertyGroup.EnsureNoReservedProperties();
                        this.propertyAndItemLists.InsertAtEnd(newPropertyGroup);
                        break;

                    // Process the <Choose> element.
                    case XMakeElements.choose:
                        Choose newChoose = new Choose(parentProjectForChildren, this.PropertyAndItemLists, (XmlElement)whenChildNode,
                                                      importedFromAnotherProject, nestingDepth);
                        this.propertyAndItemLists.InsertAtEnd(newChoose);
                        break;

                    default:
                    {
                        ProjectXmlUtilities.ThrowProjectInvalidChildElement(whenChildNode);
                        break;
                    }
                    }
                }
                break;

                default:
                {
                    ProjectXmlUtilities.ThrowProjectInvalidChildElement(whenChildNode);
                    break;
                }
                }
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Creates a new UsingTask object
        /// </summary>
        /// <param name="usingTaskNode"></param>
        /// <param name="isImported"></param>
        /// <owner>LukaszG</owner>
        internal UsingTask(XmlElement usingTaskNode, bool isImported)
        {
            this.importedFromAnotherProject = isImported;

            // make sure this really is a <UsingTask> tag
            ErrorUtilities.VerifyThrow(usingTaskNode.Name == XMakeElements.usingTask,
                                       "Expected <{0}> element; received <{1}> element.", XMakeElements.usingTask, usingTaskNode.Name);

            bool       illegalChildElementFound = false;
            XmlElement illegalChildElement      = null;

            foreach (XmlElement childElement in usingTaskNode.ChildNodes)
            {
                switch (childElement.Name)
                {
                case XMakeElements.usingTaskBody:
                    // ignore
                    break;

                case XMakeElements.usingTaskParameter:
                    // ignore
                    break;

                case XMakeElements.usingTaskParameterGroup:
                    // ignore
                    break;

                default:
                    illegalChildElementFound = true;
                    illegalChildElement      = childElement;
                    break;
                }

                if (illegalChildElementFound)
                {
                    break;
                }
            }

            // UsingTask has no valid child elements in 3.5 syntax, but in 4.0 syntax it does.
            // So ignore any valid 4.0 child elements and try to load the project as usual, but
            // still error out if something we don't expect is found.
            if (illegalChildElementFound)
            {
                ProjectXmlUtilities.ThrowProjectInvalidChildElement(illegalChildElement);
            }

            foreach (XmlAttribute usingTaskAttribute in usingTaskNode.Attributes)
            {
                switch (usingTaskAttribute.Name)
                {
                // get the task name
                case XMakeAttributes.taskName:
                    taskNameAttribute = usingTaskAttribute;
                    break;

                // get the assembly name or the assembly file/path, whichever is specified...
                case XMakeAttributes.assemblyName:
                    assemblyNameAttribute = usingTaskAttribute;
                    break;

                case XMakeAttributes.assemblyFile:
                    assemblyFileAttribute = usingTaskAttribute;
                    break;

                // ignore any RequiredRuntime XML attribute
                // (we'll make this actually do something when we run on a CLR other than v2.0)
                case XMakeAttributes.requiredRuntime:
                    // Do nothing
                    break;

                // get the condition, if any
                case XMakeAttributes.condition:
                    conditionAttribute = usingTaskAttribute;
                    break;

                // This is only recognized by the new OM:
                // Just ignore it
                case XMakeAttributes.requiredPlatform:
                    // Do nothing
                    break;

                // This is only recognized by the new OM:
                // Just ignore it
                case XMakeAttributes.taskFactory:
                    // Do nothing
                    break;

                // This is only recognized by the new OM:
                // Just ignore it
                case XMakeAttributes.runtime:
                    // Do nothing
                    break;

                // This is only recognized by the new OM:
                // Just ignore it
                case XMakeAttributes.architecture:
                    // Do nothing
                    break;

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

            ProjectErrorUtilities.VerifyThrowInvalidProject(taskNameAttribute != null,
                                                            usingTaskNode, "MissingRequiredAttribute", XMakeAttributes.taskName, XMakeElements.usingTask);
            ProjectErrorUtilities.VerifyThrowInvalidProject(taskNameAttribute.Value.Length > 0,
                                                            taskNameAttribute, "InvalidAttributeValue", taskNameAttribute.Value, XMakeAttributes.taskName, XMakeElements.usingTask);

            ProjectErrorUtilities.VerifyThrowInvalidProject((assemblyNameAttribute != null) || (assemblyFileAttribute != null),
                                                            usingTaskNode, "UsingTaskAssemblySpecification", XMakeElements.usingTask, XMakeAttributes.assemblyName, XMakeAttributes.assemblyFile);
            ProjectErrorUtilities.VerifyThrowInvalidProject((assemblyNameAttribute == null) || (assemblyFileAttribute == null),
                                                            usingTaskNode, "UsingTaskAssemblySpecification", XMakeElements.usingTask, XMakeAttributes.assemblyName, XMakeAttributes.assemblyFile);

            ProjectErrorUtilities.VerifyThrowInvalidProject((assemblyNameAttribute == null) || (assemblyNameAttribute.Value.Length > 0),
                                                            assemblyNameAttribute, "InvalidAttributeValue", String.Empty, XMakeAttributes.assemblyName, XMakeElements.usingTask);
            ProjectErrorUtilities.VerifyThrowInvalidProject((assemblyFileAttribute == null) || (assemblyFileAttribute.Value.Length > 0),
                                                            assemblyFileAttribute, "InvalidAttributeValue", String.Empty, XMakeAttributes.assemblyFile, XMakeElements.usingTask);
        }