mirror of
https://github.com/ZuneDev/MicrosoftIris.git
synced 2026-07-27 13:13:29 -07:00
270 lines
12 KiB
C#
270 lines
12 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: Microsoft.Iris.Markup.Validation.ValidateExpressionCall
|
|
// 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.Markup.UIX;
|
|
|
|
namespace Microsoft.Iris.Markup.Validation
|
|
{
|
|
internal class ValidateExpressionCall : ValidateExpression
|
|
{
|
|
private ValidateExpression _target;
|
|
private ValidateTypeIdentifier _typeIdentifier;
|
|
private string _memberName;
|
|
private ValidateParameter _parameterList;
|
|
private TypeSchema[] _foundParameterTypes;
|
|
private SchemaType _foundMemberType;
|
|
private int _foundMemberIndex = -1;
|
|
private bool _foundTargetIsStatic;
|
|
private object _foundCanonicalInstance;
|
|
private bool _isIndexAssignment;
|
|
|
|
public ValidateExpressionCall(
|
|
SourceMarkupLoader owner,
|
|
ValidateExpression target,
|
|
string memberName,
|
|
ValidateParameter parameterList,
|
|
int line,
|
|
int column)
|
|
: base(owner, line, column, ExpressionType.Call)
|
|
{
|
|
_target = target;
|
|
_memberName = memberName;
|
|
_parameterList = parameterList;
|
|
}
|
|
|
|
public ValidateExpressionCall(
|
|
SourceMarkupLoader owner,
|
|
ValidateTypeIdentifier typeIdentifier,
|
|
string memberName,
|
|
ValidateParameter parameterList,
|
|
int line,
|
|
int column)
|
|
: base(owner, line, column, ExpressionType.Call)
|
|
{
|
|
_typeIdentifier = typeIdentifier;
|
|
_memberName = memberName;
|
|
_parameterList = parameterList;
|
|
}
|
|
|
|
public ValidateExpression Target => !_foundTargetIsStatic ? _target : null;
|
|
|
|
public string MemberName => _memberName;
|
|
|
|
public ValidateParameter ParameterList => _parameterList;
|
|
|
|
public override void Validate(TypeRestriction typeRestriction, ValidateContext context)
|
|
{
|
|
int foundTargetTypeIndex = -1;
|
|
TypeSchema targetType;
|
|
if (_target != null)
|
|
{
|
|
if (_target.ExpressionType == ExpressionType.Symbol)
|
|
{
|
|
ValidateExpressionSymbol target = (ValidateExpressionSymbol)_target;
|
|
target.Validate(TypeRestriction.NotVoid, context, true);
|
|
foundTargetTypeIndex = target.FoundSymbolIndex;
|
|
_foundTargetIsStatic = target.FoundSymbolIsType;
|
|
}
|
|
else
|
|
_target.Validate(TypeRestriction.NotVoid, context);
|
|
if (_target.HasErrors)
|
|
{
|
|
MarkHasErrors();
|
|
return;
|
|
}
|
|
targetType = _target.ObjectType;
|
|
}
|
|
else
|
|
{
|
|
_typeIdentifier.Validate();
|
|
if (_typeIdentifier.HasErrors)
|
|
{
|
|
MarkHasErrors();
|
|
return;
|
|
}
|
|
targetType = _typeIdentifier.FoundType;
|
|
foundTargetTypeIndex = _typeIdentifier.FoundTypeIndex;
|
|
_foundTargetIsStatic = true;
|
|
}
|
|
ExpressionRestriction expressionRestriction = ExpressionRestriction.None;
|
|
bool canRead = true;
|
|
bool canWrite = false;
|
|
_foundParameterTypes = BuildParameterTypeList(context);
|
|
if (_foundParameterTypes == null)
|
|
return;
|
|
if (_target != null && _target.ExpressionType == ExpressionType.BaseClass)
|
|
ValidateBaseCall(typeRestriction, context);
|
|
else if (_parameterList == null)
|
|
{
|
|
if (!ValidatePropertyOrEvent(targetType, typeRestriction, context, foundTargetTypeIndex, ref expressionRestriction, ref canRead, ref canWrite))
|
|
return;
|
|
}
|
|
else if (!ValidateMethodCall(targetType, typeRestriction, context, ref expressionRestriction))
|
|
return;
|
|
if (expressionRestriction == ExpressionRestriction.NoAccess)
|
|
{
|
|
ReportError("Expression access to '{0}' is not available", _memberName);
|
|
}
|
|
else
|
|
{
|
|
if (Usage == ExpressionUsage.LValue && (!canWrite || expressionRestriction == ExpressionRestriction.ReadOnly))
|
|
ReportError("Expression access to '{0}' only supports read operations", _memberName);
|
|
if (Usage == ExpressionUsage.RValue && !canRead)
|
|
ReportError("Expression access to '{0}' only supports write operations", _memberName);
|
|
if (HasErrors)
|
|
return;
|
|
if (_foundMemberType == SchemaType.Property && Usage == ExpressionUsage.LValue)
|
|
context.Owner.NotifyFoundPropertyAssignment(this);
|
|
if (_foundMemberType != SchemaType.Method)
|
|
return;
|
|
context.Owner.NotifyFoundMethodCall(this);
|
|
}
|
|
}
|
|
|
|
private bool ValidatePropertyOrEvent(
|
|
TypeSchema targetType,
|
|
TypeRestriction typeRestriction,
|
|
ValidateContext context,
|
|
int foundTargetTypeIndex,
|
|
ref ExpressionRestriction expressionRestriction,
|
|
ref bool canRead,
|
|
ref bool canWrite)
|
|
{
|
|
PropertySchema propertyDeep = targetType.FindPropertyDeep(_memberName);
|
|
if (propertyDeep != null && (propertyDeep.IsStatic || !_foundTargetIsStatic))
|
|
{
|
|
_foundMemberType = SchemaType.Property;
|
|
_foundMemberIndex = Owner.TrackImportedProperty(propertyDeep);
|
|
expressionRestriction = propertyDeep.ExpressionRestriction;
|
|
canRead = propertyDeep.CanRead;
|
|
canWrite = propertyDeep.CanWrite && !propertyDeep.Owner.IsRuntimeImmutable;
|
|
DeclareEvaluationType(propertyDeep.PropertyType, typeRestriction);
|
|
if (!_foundTargetIsStatic && propertyDeep.NotifiesOnChange)
|
|
DeclareNotifies(context);
|
|
}
|
|
if (_foundMemberType == SchemaType.None && !_foundTargetIsStatic)
|
|
{
|
|
EventSchema eventDeep = targetType.FindEventDeep(_memberName);
|
|
if (eventDeep != null)
|
|
{
|
|
_foundMemberType = SchemaType.Event;
|
|
_foundMemberIndex = Owner.TrackImportedEvent(eventDeep);
|
|
expressionRestriction = ExpressionRestriction.ReadOnly;
|
|
DeclareEvaluationType(VoidSchema.Type, typeRestriction);
|
|
DeclareNotifies(context);
|
|
}
|
|
}
|
|
if (_foundMemberType == SchemaType.None && _foundTargetIsStatic)
|
|
{
|
|
object canonicalInstance = targetType.FindCanonicalInstance(_memberName);
|
|
if (canonicalInstance != null)
|
|
{
|
|
_foundMemberType = SchemaType.CanonicalInstance;
|
|
_foundMemberIndex = foundTargetTypeIndex;
|
|
_foundCanonicalInstance = canonicalInstance;
|
|
expressionRestriction = ExpressionRestriction.ReadOnly;
|
|
DeclareEvaluationType(targetType, typeRestriction);
|
|
}
|
|
}
|
|
if (_foundMemberType != SchemaType.None)
|
|
return true;
|
|
ReportError("Unable to find a Property, Event, or Method called \"{0}\" on '{1}'", _memberName, targetType.Name);
|
|
return false;
|
|
}
|
|
|
|
private bool ValidateMethodCall(
|
|
TypeSchema targetType,
|
|
TypeRestriction typeRestriction,
|
|
ValidateContext context,
|
|
ref ExpressionRestriction expressionRestriction)
|
|
{
|
|
expressionRestriction = ExpressionRestriction.ReadOnly;
|
|
TypeSchema[] foundParameterTypes = _foundParameterTypes;
|
|
MethodSchema methodDeep = targetType.FindMethodDeep(_memberName, foundParameterTypes);
|
|
if (methodDeep != null && (methodDeep.IsStatic || !_foundTargetIsStatic))
|
|
{
|
|
_foundMemberType = SchemaType.Method;
|
|
_foundMemberIndex = Owner.TrackImportedMethod(methodDeep);
|
|
DeclareEvaluationType(methodDeep.ReturnType, typeRestriction);
|
|
}
|
|
if (_foundMemberType != SchemaType.None)
|
|
return true;
|
|
if (foundParameterTypes.Length == 0)
|
|
{
|
|
ReportError("Unable to find a Property, Event, or Method called \"{0}\" on '{1}'", _memberName, targetType.Name);
|
|
return false;
|
|
}
|
|
string empty = string.Empty;
|
|
bool flag = true;
|
|
foreach (TypeSchema typeSchema in foundParameterTypes)
|
|
{
|
|
if (!flag)
|
|
empty += ", ";
|
|
empty += typeSchema.Name;
|
|
flag = false;
|
|
}
|
|
ReportError("Unable to find a Method \"{0}\" that accepts parameters '{1}' on '{2}'", _memberName, empty, targetType.Name);
|
|
return false;
|
|
}
|
|
|
|
private void ValidateBaseCall(TypeRestriction typeRestriction, ValidateContext context)
|
|
{
|
|
MarkupMethodSchema markupMethodSchema = context.CurrentMethod != null ? context.CurrentMethod.FoundBaseMethod : null;
|
|
if (markupMethodSchema != null)
|
|
{
|
|
if (_parameterList == null || _memberName != markupMethodSchema.Name)
|
|
ReportError("'base' keyword can only be used to call the base virtual method inside an override");
|
|
else if (new MethodSignatureKey(markupMethodSchema.Name, markupMethodSchema.ParameterTypes).Equals(new MethodSignatureKey(_memberName, _foundParameterTypes)))
|
|
{
|
|
_foundMemberType = SchemaType.Method;
|
|
_foundMemberIndex = Owner.TrackImportedMethod(markupMethodSchema);
|
|
DeclareEvaluationType(markupMethodSchema.ReturnType, typeRestriction);
|
|
}
|
|
else
|
|
ReportError("'base' keyword can only be used to call the base virtual method inside an override");
|
|
}
|
|
else
|
|
MarkHasErrors();
|
|
}
|
|
|
|
private TypeSchema[] BuildParameterTypeList(ValidateContext context)
|
|
{
|
|
TypeSchema[] typeSchemaArray = TypeSchema.EmptyList;
|
|
if (_parameterList != ValidateParameter.EmptyList)
|
|
{
|
|
int length = 0;
|
|
for (ValidateParameter validateParameter = _parameterList; validateParameter != null; validateParameter = validateParameter.Next)
|
|
{
|
|
validateParameter.Validate(context);
|
|
if (validateParameter.HasErrors)
|
|
MarkHasErrors();
|
|
++length;
|
|
}
|
|
if (HasErrors)
|
|
return null;
|
|
typeSchemaArray = new TypeSchema[length];
|
|
int index = 0;
|
|
for (ValidateParameter validateParameter = _parameterList; validateParameter != null; validateParameter = validateParameter.Next)
|
|
{
|
|
typeSchemaArray[index] = validateParameter.FoundParameterType;
|
|
++index;
|
|
}
|
|
}
|
|
return typeSchemaArray;
|
|
}
|
|
|
|
public void SetAsIndexAssignment() => _isIndexAssignment = true;
|
|
|
|
public SchemaType FoundMemberType => _foundMemberType;
|
|
|
|
public int FoundMemberIndex => _foundMemberIndex;
|
|
|
|
public object FoundCanonicalInstance => _foundCanonicalInstance;
|
|
|
|
public bool IsIndexAssignment => _isIndexAssignment;
|
|
}
|
|
}
|