|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics;
using Microsoft.Build.ObjectModelRemoting;
using Microsoft.Build.Shared;
#nullable disable
namespace Microsoft.Build.Construction
{
/// <summary>
/// UsingTaskParameterElement class represents the Parameter element in the MSBuild project.
/// </summary>
[DebuggerDisplay("Name={Name} ParameterType={ParameterType} Output={Output} Required={Required}")]
public class ProjectUsingTaskParameterElement : ProjectElement
{
private ProjectUsingTaskParameterElementLink TaskParameterLink => (ProjectUsingTaskParameterElementLink)Link;
/// <summary>
/// External projects support
/// </summary>
internal ProjectUsingTaskParameterElement(ProjectUsingTaskParameterElementLink link)
: base(link)
{
}
/// <summary>
/// Initialize a parented UsingTaskParameterElement instance
/// </summary>
internal ProjectUsingTaskParameterElement(XmlElementWithLocation xmlElement, UsingTaskParameterGroupElement parent, ProjectRootElement containingProject)
: base(xmlElement, parent, containingProject)
{
ErrorUtilities.VerifyThrowArgumentNull(parent);
}
/// <summary>
/// Initialize an unparented UsingTaskParameterElement instance
/// </summary>
private ProjectUsingTaskParameterElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject)
: base(xmlElement, null, containingProject)
{
}
/// <summary>
/// Condition should never be set, but the getter returns null instead of throwing
/// because a nonexistent condition is implicitly true
/// </summary>
public override string Condition
{
get => null;
set => ErrorUtilities.ThrowInvalidOperation("OM_CannotGetSetCondition");
}
/// <summary>
/// Gets and sets the name of the parameter's name
/// </summary>
public string Name
{
get => ElementName;
set
{
ErrorUtilities.VerifyThrowArgumentLength(value, nameof(Name));
if (Link != null) { TaskParameterLink.Name = value; return; }
// TODO: There seems to be a bug here
// the Name returns the element name (consistent with XML view aka:)
// <fooParam .../> => this.Name = fooParan
// while setter will "set" the "Name" attribute, instead of renaming the XML element aka
// <fooParam Name="newName".../> instead of (so this.Name still is "fooParam"
// <newName .../>
// i have changed the "link" to support either way, should check whether it has to be fix on real object as well.
XmlElementWithLocation newElement = XmlUtilities.RenameXmlElement(XmlElement, value, XmlElement.NamespaceURI);
ReplaceElement(newElement);
// SetOrRemoveAttribute(XMakeAttributes.name, value, "Set usingtaskparameter {0}", value);
}
}
/// <summary>
/// Gets or sets the Type attribute returns "System.String" if not set.
/// If null or empty is set the attribute will be removed from the element.
/// </summary>
public string ParameterType
{
get
{
string typeAttribute = GetAttributeValue(XMakeAttributes.parameterType);
return String.IsNullOrEmpty(typeAttribute) ? typeof(String).FullName : typeAttribute;
}
set
{
// If null or empty is passed in remove the attribute from the element
SetOrRemoveAttribute(XMakeAttributes.parameterType, value, "Set usingtaskparameter ParameterType {0}", value);
}
}
/// <summary>
/// Gets or sets the output attribute
/// </summary>
public string Output
{
get
{
string outputAttribute = GetAttributeValue(XMakeAttributes.output);
return String.IsNullOrEmpty(outputAttribute) ? bool.FalseString : outputAttribute;
}
set
{
SetOrRemoveAttribute(XMakeAttributes.output, value, "Set usingtaskparameter Output {0}", value);
}
}
/// <summary>
/// Gets or sets the required attribute
/// </summary>
public string Required
{
get
{
string requiredAttribute = GetAttributeValue(XMakeAttributes.required);
return String.IsNullOrEmpty(requiredAttribute) ? bool.FalseString : requiredAttribute;
}
set
{
SetOrRemoveAttribute(XMakeAttributes.required, value, "Set usingtaskparameter Required {0}", value);
}
}
/// <summary>
/// This does not allow conditions, so it should not be called.
/// </summary>
public override ElementLocation ConditionLocation
{
get
{
ErrorUtilities.ThrowInternalError("Should not evaluate this");
return null;
}
}
/// <summary>
/// Location of the Type attribute.
/// If there is no such attribute, returns the location of the element,
/// in lieu of the default value it uses for the attribute.
/// </summary>
public ElementLocation ParameterTypeLocation => GetAttributeLocation(XMakeAttributes.parameterType) ?? Location;
/// <summary>
/// Location of the Output attribute.
/// If there is no such attribute, returns the location of the element,
/// in lieu of the default value it uses for the attribute.
/// </summary>
public ElementLocation OutputLocation => GetAttributeLocation(XMakeAttributes.output) ?? Location;
/// <summary>
/// Location of the Required attribute.
/// If there is no such attribute, returns the location of the element,
/// in lieu of the default value it uses for the attribute.
/// </summary>
public ElementLocation RequiredLocation => GetAttributeLocation(XMakeAttributes.required) ?? Location;
/// <summary>
/// Creates an unparented UsingTaskParameterElement, wrapping an unparented XmlElement.
/// Caller should then ensure the element is added to a parent.
/// </summary>
internal static ProjectUsingTaskParameterElement CreateDisconnected(string parameterName, string output, string required, string parameterType, ProjectRootElement containingProject)
{
XmlUtilities.VerifyThrowArgumentValidElementName(parameterName);
XmlElementWithLocation element = containingProject.CreateElement(parameterName);
var parameter =
new ProjectUsingTaskParameterElement(element, containingProject)
{
Output = output,
Required = required,
ParameterType = parameterType
};
return parameter;
}
/// <summary>
/// Overridden to verify that the potential parent and siblings
/// are acceptable. Throws InvalidOperationException if they are not.
/// </summary>
internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer parent, ProjectElement previousSibling, ProjectElement nextSibling)
{
ErrorUtilities.VerifyThrowInvalidOperation(parent is UsingTaskParameterGroupElement, "OM_CannotAcceptParent");
}
/// <inheritdoc />
protected override ProjectElement CreateNewInstance(ProjectRootElement owner)
{
return owner.CreateUsingTaskParameterElement(Name, Output, Required, ParameterType);
}
}
}
|