mirror of
https://github.com/ZuneDev/MicrosoftIris.git
synced 2026-07-27 13:13:29 -07:00
359 lines
17 KiB
C#
359 lines
17 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: Microsoft.Iris.Markup.Validation.ValidateProperty
|
|
// Assembly: UIX, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
|
|
// MVID: A56C6C9D-B7F6-46A9-8BDE-B3D9B8D60B11
|
|
// Assembly location: C:\Program Files\Zune\UIX.dll
|
|
|
|
using Microsoft.Iris.Library;
|
|
using Microsoft.Iris.Markup.UIX;
|
|
|
|
namespace Microsoft.Iris.Markup.Validation
|
|
{
|
|
internal class ValidateProperty : Microsoft.Iris.Markup.Validation.Validate
|
|
{
|
|
public const string c_requiredValue = "$Required";
|
|
public const string c_overrideProperty = "Override";
|
|
private string _propertyName;
|
|
private ValidateObject _value;
|
|
private bool _multipleValueProperty;
|
|
private int _valueCount;
|
|
private ValueApplyMode _valueApplyMode;
|
|
private PropertyAttribute _propertyAttributeList;
|
|
private bool _allowPropertyAttributes;
|
|
private PropertySchema _foundProperty;
|
|
private int _foundPropertyIndex;
|
|
private int _foundPropertyTypeIndex;
|
|
private bool _isPseudo;
|
|
private bool _shouldSkipDictionaryAddIfContains;
|
|
private ValidateProperty _next;
|
|
|
|
public ValidateProperty(SourceMarkupLoader owner, string propertyName, int line, int column)
|
|
: this(owner, propertyName, null, line, column)
|
|
{
|
|
}
|
|
|
|
public ValidateProperty(
|
|
SourceMarkupLoader owner,
|
|
string propertyName,
|
|
ValidateObject value,
|
|
int line,
|
|
int column)
|
|
: base(owner, line, column)
|
|
{
|
|
_propertyName = propertyName;
|
|
_value = value;
|
|
}
|
|
|
|
public string PropertyName => _propertyName;
|
|
|
|
public ValidateObject Value
|
|
{
|
|
get => _value;
|
|
set => _value = value;
|
|
}
|
|
|
|
public PropertyAttribute PropertyAttributeList => _propertyAttributeList;
|
|
|
|
public void AllowPropertyAttributes() => _allowPropertyAttributes = true;
|
|
|
|
public ValidateProperty Next
|
|
{
|
|
get => _next;
|
|
set => _next = value;
|
|
}
|
|
|
|
public void AppendToEnd(ValidateProperty item)
|
|
{
|
|
ValidateProperty validateProperty = this;
|
|
while (validateProperty.Next != null)
|
|
validateProperty = validateProperty.Next;
|
|
validateProperty.Next = item;
|
|
}
|
|
|
|
public void AddValue(ValidateObject value)
|
|
{
|
|
if (_value == null)
|
|
_value = value;
|
|
else if (_value is ValidateObjectTag && value is ValidateObjectTag)
|
|
_value.AppendToEnd(value);
|
|
else if (_value is ValidateCode && value is ValidateCode)
|
|
_value.AppendToEnd(value);
|
|
else
|
|
ReportError("Property '{0}' cannot contain both object-tag and script block values", _propertyName);
|
|
}
|
|
|
|
public void AddAttribute(PropertyAttribute attribute)
|
|
{
|
|
attribute.Next = _propertyAttributeList;
|
|
_propertyAttributeList = attribute;
|
|
}
|
|
|
|
public void Validate(ValidateObjectTag targetObject, ValidateContext context)
|
|
{
|
|
TypeSchema objectType = targetObject.ObjectType;
|
|
if (_propertyName == "Override" && ValidateOverrideProperty(targetObject, context))
|
|
return;
|
|
string name = _propertyName;
|
|
int length = _propertyName.IndexOf('.');
|
|
if (length >= 0 && _propertyName.Length > length + 1 && _propertyName.Substring(0, length) == targetObject.TypeIdentifier.TypeName)
|
|
name = _propertyName.Substring(length + 1);
|
|
_foundProperty = objectType.FindPropertyDeep(name);
|
|
if (_foundProperty == null)
|
|
{
|
|
if (_propertyName == "Name")
|
|
ValidateNameProperty(true, targetObject, context);
|
|
else if (_propertyName == targetObject.TypeIdentifier.TypeName)
|
|
ValidatePseudoConstructionProperty(targetObject, context);
|
|
else
|
|
ReportError("Property '{0}' does not exist on '{1}'", _propertyName, objectType.Name);
|
|
}
|
|
else
|
|
{
|
|
if (_propertyName == "Name")
|
|
ValidateNameProperty(false, targetObject, context);
|
|
UpdateFoundProperty(_foundProperty);
|
|
if (_propertyAttributeList != null && !_allowPropertyAttributes)
|
|
ReportError("Property attributes are not supported on property '{0}'", _propertyName);
|
|
if (IsCodeValue && ((ValidateCode)_value).Next != null)
|
|
{
|
|
ReportError("Property '{0}' does not support multi-value script blocks", _propertyName);
|
|
}
|
|
else
|
|
{
|
|
bool flag1 = DictionarySchema.Type.IsAssignableFrom(_foundProperty.PropertyType);
|
|
bool flag2 = ListSchema.Type.IsAssignableFrom(_foundProperty.PropertyType);
|
|
_multipleValueProperty = flag1 || flag2;
|
|
bool flag3 = IsObjectTagValue && ((ValidateObjectTag)_value).Next != null;
|
|
if (!_multipleValueProperty && flag3)
|
|
{
|
|
ReportError("Property '{0}' does not support multiple values (property type is '{1}')", _propertyName, _foundProperty.PropertyType.Name);
|
|
}
|
|
else
|
|
{
|
|
context.NotifyPropertyScopeEnter(this);
|
|
try
|
|
{
|
|
if (!_multipleValueProperty)
|
|
{
|
|
if (_value == null)
|
|
{
|
|
ReportError("Property '{0}' requires a value to be provided", _propertyName);
|
|
return;
|
|
}
|
|
_valueCount = 1;
|
|
_valueApplyMode = ValueApplyMode.SingleValueSet;
|
|
_value.Validate(new TypeRestriction(_foundProperty.PropertyType, _foundProperty.AlternateType), context);
|
|
if (_value.HasErrors)
|
|
{
|
|
MarkHasErrors();
|
|
return;
|
|
}
|
|
if (_foundProperty.RangeValidator != null && IsFromStringValue)
|
|
{
|
|
Result result = _foundProperty.RangeValidator(((ValidateFromString)_value).FromStringInstance);
|
|
if (result.Failed)
|
|
ReportError(result.Error);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TypeSchema primary = _foundProperty.AlternateType ?? ObjectSchema.Type;
|
|
_valueApplyMode = !flag1 ? ValueApplyMode.MultiValueList : ValueApplyMode.MultiValueDictionary;
|
|
if (_foundProperty.CanWrite && _foundProperty.PropertyType.HasDefaultConstructor)
|
|
_valueApplyMode |= ValueApplyMode.CollectionPopulateAndSet;
|
|
else
|
|
_valueApplyMode |= ValueApplyMode.CollectionAdd;
|
|
for (ValidateObject validateObject = _value; validateObject != null; validateObject = validateObject.ObjectSourceType != ObjectSourceType.ObjectTag ? null : (ValidateObject)((ValidateObjectTag)validateObject).Next)
|
|
{
|
|
++_valueCount;
|
|
TypeRestriction typeRestriction = !flag3 ? new TypeRestriction(primary, _foundProperty.PropertyType) : new TypeRestriction(primary);
|
|
validateObject.Validate(typeRestriction, context);
|
|
if (validateObject.HasErrors)
|
|
{
|
|
MarkHasErrors();
|
|
}
|
|
else
|
|
{
|
|
if (!flag3 && _foundProperty.PropertyType.IsAssignableFrom(validateObject.ObjectType))
|
|
{
|
|
bool flag4 = true;
|
|
if (flag1)
|
|
{
|
|
if (validateObject.ObjectSourceType == ObjectSourceType.ObjectTag && ((ValidateObjectTag)validateObject).Name != null)
|
|
flag4 = false;
|
|
}
|
|
else if (!_foundProperty.CanWrite)
|
|
flag4 = false;
|
|
if (flag4)
|
|
{
|
|
_valueApplyMode = ValueApplyMode.SingleValueSet;
|
|
break;
|
|
}
|
|
}
|
|
if (validateObject.ObjectSourceType != ObjectSourceType.ObjectTag)
|
|
{
|
|
ReportError("Collection property '{0}' may only have multiple values specified in expanded form", _propertyName);
|
|
break;
|
|
}
|
|
if ((_valueApplyMode & ValueApplyMode.MultiValueDictionary) != ValueApplyMode.SingleValueSet && ((ValidateObjectTag)validateObject).Name == null)
|
|
ReportError("Dictionary property '{0}' requires all values be named", _propertyName);
|
|
}
|
|
}
|
|
}
|
|
if (_valueApplyMode == ValueApplyMode.SingleValueSet)
|
|
{
|
|
if (_foundProperty.CanWrite)
|
|
return;
|
|
ReportError("Property '{0}' does not support setting", _foundProperty.Name);
|
|
}
|
|
else
|
|
{
|
|
if (_foundProperty.CanRead)
|
|
return;
|
|
ReportError("Property '{0}' must support reading to retrieve its collection for multiple value adds", _foundProperty.Name);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
context.NotifyPropertyScopeExit(this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ValidateNameProperty(
|
|
bool isPseudo,
|
|
ValidateObjectTag targetObject,
|
|
ValidateContext context)
|
|
{
|
|
if (isPseudo)
|
|
MarkAsPseudo();
|
|
if (!IsFromStringValue)
|
|
{
|
|
ReportError("Property '{0}' does not support expanded value syntax", _propertyName);
|
|
}
|
|
else
|
|
{
|
|
ValidateFromString validateFromString = (ValidateFromString)_value;
|
|
validateFromString.Validate(new TypeRestriction(StringSchema.Type), context);
|
|
if (validateFromString.HasErrors)
|
|
MarkHasErrors();
|
|
else
|
|
targetObject.Name = validateFromString.FromString;
|
|
}
|
|
}
|
|
|
|
private void ValidatePseudoConstructionProperty(
|
|
ValidateObjectTag targetObject,
|
|
ValidateContext context)
|
|
{
|
|
bool flag = false;
|
|
MarkAsPseudo();
|
|
if (IsObjectTagValue && ((ValidateObjectTag)_value).Next != null)
|
|
{
|
|
ReportError("Property '{0}' does not support multiple values (property type is '{1}')", _propertyName, targetObject.ObjectType.Name);
|
|
}
|
|
else
|
|
{
|
|
if (IsFromStringValue && ((ValidateFromString)_value).FromString == "$Required")
|
|
{
|
|
flag = true;
|
|
targetObject.PropertyIsRequiredForCreation = flag;
|
|
}
|
|
if (flag)
|
|
return;
|
|
_value.Validate(new TypeRestriction(targetObject.ObjectType, TypeSchemaDefinition.Type), context);
|
|
if (_value.HasErrors)
|
|
MarkHasErrors();
|
|
else if (targetObject.ObjectType.IsAssignableFrom(_value.ObjectType))
|
|
targetObject.IndirectedObject = _value;
|
|
else
|
|
targetObject.DynamicConstructionType = _value;
|
|
}
|
|
}
|
|
|
|
private bool ValidateOverrideProperty(ValidateObjectTag targetObject, ValidateContext context)
|
|
{
|
|
if (context.ActiveSymbolScope != SymbolOrigin.Properties)
|
|
return false;
|
|
bool result;
|
|
if (IsFromStringValue && bool.TryParse(((ValidateFromString)_value).FromString, out result))
|
|
{
|
|
if (targetObject.PropertySchemaExport != null && context.Owner.TypeExport != null)
|
|
{
|
|
PropertySchema propertySchema = null;
|
|
if (context.Owner.TypeExport.MarkupTypeBase != null)
|
|
propertySchema = context.Owner.TypeExport.MarkupTypeBase.FindPropertyDeep(targetObject.PropertySchemaExport.Name);
|
|
if (result && propertySchema == null)
|
|
ReportError("Property '{0}' was specified as Override='true' but no property was found to override", targetObject.PropertySchemaExport.Name);
|
|
else if (!result && propertySchema != null)
|
|
ReportError("Property '{0}' was specified as Override='false' but a base property was found", targetObject.PropertySchemaExport.Name);
|
|
}
|
|
}
|
|
else
|
|
ReportError("Property '{0}' must be Boolean 'true' or 'false'", "Override");
|
|
MarkAsPseudo();
|
|
return true;
|
|
}
|
|
|
|
public bool IsPseudo => _isPseudo;
|
|
|
|
public void MarkAsPseudo() => _isPseudo = true;
|
|
|
|
public void RepurposeProperty(string newName, PropertyAttribute newAttributes)
|
|
{
|
|
_propertyName = newName;
|
|
_propertyAttributeList = newAttributes;
|
|
}
|
|
|
|
public bool IsObjectTagValue => _value != null && _value.ObjectSourceType == ObjectSourceType.ObjectTag;
|
|
|
|
public bool IsFromStringValue => _value != null && _value.ObjectSourceType == ObjectSourceType.FromString;
|
|
|
|
public bool IsCodeValue => _value != null && _value.ObjectSourceType == ObjectSourceType.Code;
|
|
|
|
public bool IsExpressionValue => _value != null && _value.ObjectSourceType == ObjectSourceType.Expression;
|
|
|
|
public void UpdateFoundProperty(PropertySchema newFoundProperty)
|
|
{
|
|
_foundProperty = newFoundProperty;
|
|
_foundPropertyIndex = Owner.TrackImportedProperty(_foundProperty);
|
|
_foundPropertyTypeIndex = Owner.TrackImportedType(_foundProperty.PropertyType);
|
|
}
|
|
|
|
public PropertySchema FoundProperty => _foundProperty;
|
|
|
|
public int FoundPropertyIndex => _foundPropertyIndex;
|
|
|
|
public int FoundPropertyTypeIndex => _foundPropertyTypeIndex;
|
|
|
|
public int ValueCount => _valueCount;
|
|
|
|
public bool ShouldSkipDictionaryAddIfContains
|
|
{
|
|
get => _shouldSkipDictionaryAddIfContains;
|
|
set => _shouldSkipDictionaryAddIfContains = value;
|
|
}
|
|
|
|
public ValueApplyMode ValueApplyMode => _valueApplyMode;
|
|
|
|
public void ReversePropertyValues()
|
|
{
|
|
ValidateObjectTag next;
|
|
for (ValidateObjectTag validateObjectTag = (ValidateObjectTag)_value; validateObjectTag != null; validateObjectTag = next)
|
|
{
|
|
next = validateObjectTag.Next;
|
|
validateObjectTag.Next = null;
|
|
if (validateObjectTag != _value)
|
|
{
|
|
validateObjectTag.Next = (ValidateObjectTag)_value;
|
|
_value = validateObjectTag;
|
|
}
|
|
}
|
|
}
|
|
|
|
public override string ToString() => _value != null ? string.Format("{0} = {1}", _propertyName, _value.ToString()) : "Unavailable";
|
|
}
|
|
}
|