/// <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); }
/// <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; }
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); } }
/// <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); } }
/// <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); }
/// <summary> /// Initializes a persisted target from an existing <Target> 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); } }