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