/// <summary> /// Finds the matching nodes of a <see cref="IResultOfExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The expression constant upon return.</param> public static bool ResolveCompilerReferences(IResultOfExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; IExpression Source = (IExpression)node.Source; IResultType ResolvedSourceResult = Source.ResolvedResult.Item; int ResultNameIndex = ResolvedSourceResult.ResultNameIndex; if (ResultNameIndex < 0) { errorList.AddError(new ErrorInvalidExpression(node)); return(false); } Debug.Assert(ResolvedSourceResult.Preferred != null); resolvedResult = new ResultType(ResolvedSourceResult.Preferred); constantSourceList.Add(Source); ResultException.Propagate(Source.ResolvedException, out resolvedException); #if COVERAGE Debug.Assert(node.IsComplex); #endif return(true); }
/// <summary> /// Finds the matching nodes of a <see cref="IUnaryNotExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The constant value upon return, if any.</param> public static bool ResolveCompilerReferences(IUnaryNotExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; IExpression RightExpression = (IExpression)node.RightExpression; IClass EmbeddingClass = node.EmbeddingClass; bool IsRightClassType = Expression.GetClassTypeOfExpression(RightExpression, errorList, out IClassType RightExpressionClassType); if (!IsRightClassType) { return(false); } Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName BooleanTypeName, out ICompiledType BooleanType); Expression.IsLanguageTypeAvailable(LanguageClasses.Event.Guid, node, out ITypeName EventTypeName, out ICompiledType EventType); Debug.Assert(RightExpressionClassType == BooleanType || RightExpressionClassType == EventType); node.SetIsEventExpression(RightExpressionClassType != BooleanType); constantSourceList.Add(RightExpression); resolvedResult = new ResultType(BooleanTypeName, BooleanType, string.Empty); ResultException.Propagate(RightExpression.ResolvedException, out resolvedException); #if COVERAGE Debug.Assert(node.IsComplex); #endif return(true); }
/// <summary> /// Finds the matching nodes of a <see cref="IClassConstantExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The expression constant upon return.</param> /// <param name="resolvedFinalFeature">The feature if the end of the path is a feature.</param> /// <param name="resolvedFinalDiscrete">The discrete if the end of the path is a discrete.</param> /// <param name="resolvedClassTypeName">The class type name upon return.</param> /// <param name="resolvedClassType">The class name upon return.</param> public static bool ResolveCompilerReferences(IClassConstantExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant, out IConstantFeature resolvedFinalFeature, out IDiscrete resolvedFinalDiscrete, out ITypeName resolvedClassTypeName, out IClassType resolvedClassType) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; resolvedFinalFeature = null; resolvedFinalDiscrete = null; resolvedClassTypeName = null; resolvedClassType = null; IIdentifier ClassIdentifier = (IIdentifier)node.ClassIdentifier; IIdentifier ConstantIdentifier = (IIdentifier)node.ConstantIdentifier; IClass EmbeddingClass = node.EmbeddingClass; string ValidClassText = ClassIdentifier.ValidText.Item; string ValidConstantText = ConstantIdentifier.ValidText.Item; ISealableDictionary <string, IImportedClass> ClassTable = EmbeddingClass.ImportedClassTable; if (!ClassTable.ContainsKey(ValidClassText)) { errorList.AddError(new ErrorUnknownIdentifier(ClassIdentifier, ValidClassText)); return(false); } IClass BaseClass = ClassTable[ValidClassText].Item; resolvedClassTypeName = BaseClass.ResolvedClassTypeName.Item; resolvedClassType = BaseClass.ResolvedClassType.Item; ITypeName ConstantTypeName; ICompiledType ConstantType; ISealableDictionary <IFeatureName, IDiscrete> DiscreteTable = BaseClass.DiscreteTable; ISealableDictionary <IFeatureName, IFeatureInstance> FeatureTable = BaseClass.FeatureTable; if (FeatureName.TableContain(DiscreteTable, ValidConstantText, out IFeatureName Key, out IDiscrete Discrete)) { if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Number.Guid, node, out ITypeName NumberTypeName, out ICompiledType NumberType)) { errorList.AddError(new ErrorNumberTypeMissing(node)); return(false); } if (Discrete.NumericValue.IsAssigned) { constantSourceList.Add((IExpression)Discrete.NumericValue.Item); } else { expressionConstant = new DiscreteLanguageConstant(Discrete); } resolvedFinalDiscrete = Discrete; ConstantTypeName = NumberTypeName; ConstantType = NumberType; }
/// <summary> /// Checks for errors before applying a rule. /// </summary> /// <param name="node">The node instance to check.</param> /// <param name="dataList">Optional data collected during inspection of sources.</param> /// <param name="data">Private data to give to Apply() upon return.</param> /// <returns>True if an error occured.</returns> public override bool CheckConsistency(IQueryOverloadType node, IDictionary <ISourceTemplate, object> dataList, out object data) { bool Success = true; data = null; ISealableList <IParameter> ParameterTable = new SealableList <IParameter>(); ISealableList <IParameter> ResultTable = new SealableList <IParameter>(); foreach (IEntityDeclaration Item in node.ParameterList) { IName ParameterName = (IName)Item.EntityName; Debug.Assert(ParameterName.ValidText.IsAssigned); string ValidText = ParameterName.ValidText.Item; IScopeAttributeFeature ParameterFeature = Item.ValidEntity.Item; if (Parameter.TableContainsName(ParameterTable, ValidText)) { AddSourceError(new ErrorDuplicateName(ParameterName, ValidText)); Success = false; } else { ParameterTable.Add(new Parameter(ValidText, ParameterFeature)); } } foreach (IEntityDeclaration Item in node.ResultList) { IName ResultName = (IName)Item.EntityName; Debug.Assert(ResultName.ValidText.IsAssigned); string ValidText = ResultName.ValidText.Item; IScopeAttributeFeature ResultFeature = Item.ValidEntity.Item; if (Parameter.TableContainsName(ResultTable, ValidText) || Parameter.TableContainsName(ParameterTable, ValidText)) { AddSourceError(new ErrorDuplicateName(ResultName, ValidText)); Success = false; } else { ResultTable.Add(new Parameter(ValidText, ResultFeature)); } } if (Success) { data = new Tuple <ISealableList <IParameter>, ISealableList <IParameter> >(ParameterTable, ResultTable); } return(Success); }
/// <summary> /// Checks for errors before applying a rule. /// </summary> /// <param name="node">The node instance to check.</param> /// <param name="dataList">Optional data collected during inspection of sources.</param> /// <param name="data">Private data to give to Apply() upon return.</param> /// <returns>True if an error occured.</returns> public override bool CheckConsistency(ICommandOverload node, IDictionary <ISourceTemplate, object> dataList, out object data) { bool Success = true; data = null; ISealableDictionary <string, IScopeAttributeFeature> CheckedScope = new SealableDictionary <string, IScopeAttributeFeature>(); ISealableList <IParameter> ParameterTable = new SealableList <IParameter>(); foreach (EntityDeclaration Item in node.ParameterList) { IName SourceName = (IName)Item.EntityName; string ValidName = SourceName.ValidText.Item; if (CheckedScope.ContainsKey(ValidName)) { AddSourceError(new ErrorDuplicateName(SourceName, ValidName)); Success = false; } else { CheckedScope.Add(ValidName, Item.ValidEntity.Item); ParameterTable.Add(new Parameter(ValidName, Item.ValidEntity.Item)); } } IList <string> ConflictList = new List <string>(); ScopeHolder.RecursiveCheck(CheckedScope, node.InnerScopes, ConflictList); foreach (IEntityDeclaration Item in node.ParameterList) { IScopeAttributeFeature LocalEntity = Item.ValidEntity.Item; string ValidFeatureName = LocalEntity.ValidFeatureName.Item.Name; if (ConflictList.Contains(ValidFeatureName)) { AddSourceError(new ErrorVariableAlreadyDefined(Item, ValidFeatureName)); Success = false; } } if (Success) { data = new Tuple <ISealableDictionary <string, IScopeAttributeFeature>, ISealableList <IParameter> >(CheckedScope, ParameterTable); } return(Success); }
/// <summary> /// Checks for errors before applying a rule. /// </summary> /// <param name="node">The node instance to check.</param> /// <param name="dataList">Optional data collected during inspection of sources.</param> /// <param name="data">Private data to give to Apply() upon return.</param> /// <returns>True if an error occured.</returns> public override bool CheckConsistency(IIndexerType node, IDictionary <ISourceTemplate, object> dataList, out object data) { bool Success = true; data = null; IObjectType BaseTypeItem = (IObjectType)node.BaseType; Debug.Assert(BaseTypeItem.ResolvedType.IsAssigned); IClassType BaseType = BaseTypeItem.ResolvedType.Item as IClassType; if (BaseType == null) { AddSourceError(new ErrorClassTypeRequired(node)); Success = false; } ISealableList <IParameter> ParameterTable = new SealableList <IParameter>(); foreach (IEntityDeclaration Item in node.IndexParameterList) { IName ParameterName = (IName)Item.EntityName; string ValidText = ParameterName.ValidText.Item; IScopeAttributeFeature ParameterFeature = Item.ValidEntity.Item; if (Parameter.TableContainsName(ParameterTable, ValidText)) { AddSourceError(new ErrorDuplicateName(ParameterName, ValidText)); Success = false; } else { ParameterTable.Add(new Parameter(ValidText, ParameterFeature)); } } if (Success) { data = new Tuple <IClassType, ISealableList <IParameter> >(BaseType, ParameterTable); } return(Success); }
/// <summary> /// Finds the matching nodes of a <see cref="IBinaryConditionalExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The constant value upon return, if any.</param> public static bool ResolveCompilerReferences(IBinaryConditionalExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; IExpression LeftExpression = (IExpression)node.LeftExpression; BaseNode.ConditionalTypes Conditional = node.Conditional; IExpression RightExpression = (IExpression)node.RightExpression; IClass EmbeddingClass = node.EmbeddingClass; bool IsLeftClassType = Expression.GetClassTypeOfExpression(LeftExpression, errorList, out IClassType LeftExpressionClassType); bool IsRightClassType = Expression.GetClassTypeOfExpression(RightExpression, errorList, out IClassType RightExpressionClassType); if (!IsLeftClassType || !IsRightClassType) { return(false); } Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName BooleanTypeName, out ICompiledType BooleanType); Expression.IsLanguageTypeAvailable(LanguageClasses.Event.Guid, node, out ITypeName EventTypeName, out ICompiledType EventType); Debug.Assert(LeftExpressionClassType == BooleanType || LeftExpressionClassType == EventType); Debug.Assert(RightExpressionClassType == BooleanType || RightExpressionClassType == EventType); if (LeftExpressionClassType != RightExpressionClassType) { errorList.AddError(new ErrorInvalidExpression(LeftExpression)); return(false); } bool IsEventExpression = LeftExpressionClassType != BooleanType; if (IsEventExpression) { if (!((node.ParentSource is IBinaryConditionalExpression) || (node.ParentSource is IConditional) || (node.ParentSource is ICheckInstruction))) { errorList.AddError(new ErrorInvalidExpression(node)); return(false); } resolvedResult = new ResultType(EventTypeName, EventType, string.Empty); } else { resolvedResult = new ResultType(BooleanTypeName, BooleanType, string.Empty); } constantSourceList.Add(LeftExpression); constantSourceList.Add(RightExpression); resolvedException = new ResultException(); ResultException.Merge(resolvedException, LeftExpression.ResolvedException); ResultException.Merge(resolvedException, RightExpression.ResolvedException); #if COVERAGE Debug.Assert(node.IsComplex); #endif return(true); }
/// <summary> /// Applies the rule. /// </summary> /// <param name="node">The node instance to modify.</param> /// <param name="data">Private data from CheckConsistency().</param> public override void Apply(IQueryOverload node, object data) { IClass EmbeddingClass = node.EmbeddingClass; IFeature EmbeddingFeature = node.EmbeddingFeature; ISealableList <IParameter> ParameterTable = new SealableList <IParameter>(); ISealableList <IParameter> ResultTable = new SealableList <IParameter>(); foreach (IEntityDeclaration Item in node.ParameterList) { IName SourceName = (IName)Item.EntityName; Debug.Assert(SourceName.ValidText.IsAssigned); string ValidName = SourceName.ValidText.Item; ParameterTable.Add(new Parameter(ValidName, Item.ValidEntity.Item)); } // Ensured since the root is valid. Debug.Assert(node.ResultList.Count > 0); foreach (IEntityDeclaration Item in node.ResultList) { IName SourceName = (IName)Item.EntityName; Debug.Assert(SourceName.ValidText.IsAssigned); string ValidName = SourceName.ValidText.Item; ResultTable.Add(new Parameter(ValidName, Item.ValidEntity.Item)); } node.ParameterTable.AddRange(ParameterTable); node.ParameterTable.Seal(); node.ResultTable.AddRange(ResultTable); node.ResultTable.Seal(); foreach (IParameter Parameter in ResultTable) { Debug.Assert(Parameter.ResolvedParameter.ResolvedEffectiveType.IsAssigned); node.ConformantResultTable.Add(Parameter.ResolvedParameter.ResolvedEffectiveType.Item); } Debug.Assert(ResultTable.Count > 0); ITypeName BestResultTypeName = null; ICompiledType BestResultType = null; foreach (IParameter Item in ResultTable) { Debug.Assert(Item.ResolvedParameter.ResolvedEffectiveTypeName.IsAssigned); Debug.Assert(Item.ResolvedParameter.ResolvedEffectiveType.IsAssigned); if (BestResultType == null || Item.Name == nameof(BaseNode.Keyword.Result)) { BestResultTypeName = Item.ResolvedParameter.ResolvedEffectiveTypeName.Item; BestResultType = Item.ResolvedParameter.ResolvedEffectiveType.Item; } } node.ResolvedResultTypeName.Item = BestResultTypeName; node.ResolvedResultType.Item = BestResultType; IBody QueryBody = (IBody)node.QueryBody; IQueryOverloadType AssociatedType = new QueryOverloadType(node.ParameterList, node.ParameterEnd, node.ResultList, QueryBody.RequireList, QueryBody.EnsureList, QueryBody.ExceptionIdentifierList); AssociatedType.ParameterTable.AddRange(ParameterTable); AssociatedType.ParameterTable.Seal(); AssociatedType.ResultTable.AddRange(ResultTable); AssociatedType.ResultTable.Seal(); foreach (IParameter Parameter in ResultTable) { Debug.Assert(Parameter.ResolvedParameter.ResolvedEffectiveType.IsAssigned); AssociatedType.ConformantResultTable.Add(Parameter.ResolvedParameter.ResolvedEffectiveType.Item); } node.ResolvedAssociatedType.Item = AssociatedType; Debug.Assert(!node.ConformantResultTable.IsSealed); Debug.Assert(!AssociatedType.ConformantResultTable.IsSealed); }
/// <summary> /// Finds the matching nodes of a <see cref="IEqualityExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The constant value upon return, if any.</param> public static bool ResolveCompilerReferences(IEqualityExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; IExpression LeftExpression = (IExpression)node.LeftExpression; IExpression RightExpression = (IExpression)node.RightExpression; IClass EmbeddingClass = node.EmbeddingClass; IResultType LeftResult = LeftExpression.ResolvedResult.Item; IResultType RightResult = RightExpression.ResolvedResult.Item; if (LeftResult.Count != RightResult.Count) { errorList.AddError(new ErrorExpressionResultMismatch(node)); return(false); } if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName ResultTypeName, out ICompiledType ResultType)) { errorList.AddError(new ErrorBooleanTypeMissing(node)); return(false); } if (LeftResult.Count > 1) { int MismatchingResultCount = 0; foreach (IExpressionType LeftItem in LeftResult) { ICompiledType LeftExpressionType = LeftItem.ValueType; bool MatchingNameFound = false; foreach (IExpressionType RightItem in RightResult) { if (LeftItem.Name == RightItem.Name) { MatchingNameFound = true; ICompiledType RightExpressionType = RightItem.ValueType; if (!ObjectType.TypeConformToBase(LeftExpressionType, RightExpressionType, isConversionAllowed: true) && !ObjectType.TypeConformToBase(RightExpressionType, LeftExpressionType, isConversionAllowed: true)) { MismatchingResultCount++; } break; } } if (!MatchingNameFound) { MismatchingResultCount++; } } if (MismatchingResultCount > 0) { errorList.AddError(new ErrorExpressionResultMismatch(node)); return(false); } } resolvedResult = new ResultType(ResultTypeName, ResultType, string.Empty); constantSourceList.Add(LeftExpression); constantSourceList.Add(RightExpression); resolvedException = new ResultException(); ResultException.Merge(resolvedException, LeftExpression.ResolvedException); ResultException.Merge(resolvedException, RightExpression.ResolvedException); #if COVERAGE Debug.Assert(node.IsComplex); #endif return(true); }
/// <summary> /// Finds the matching nodes of a <see cref="IUnaryOperatorExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The constant value upon return, if any.</param> /// <param name="selectedFeature">The matching feature upon return.</param> /// <param name="selectedOverload">The matching overload in <paramref name="selectedFeature"/> upon return.</param> /// <param name="selectedOverloadType">The matching overload type upon return.</param> public static bool ResolveCompilerReferences(IUnaryOperatorExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant, out IFunctionFeature selectedFeature, out IQueryOverload selectedOverload, out IQueryOverloadType selectedOverloadType) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; selectedFeature = null; selectedOverload = null; selectedOverloadType = null; IIdentifier Operator = (IIdentifier)node.Operator; string ValidText = Operator.ValidText.Item; IExpression RightExpression = (IExpression)node.RightExpression; IResultType RightResult = RightExpression.ResolvedResult.Item; if (!RightResult.TryGetResult(out ICompiledType RightExpressionType)) { errorList.AddError(new ErrorInvalidExpression(RightExpression)); return(false); } if (RightExpressionType is IClassType AsClassType) { ISealableDictionary <IFeatureName, IFeatureInstance> RightFeatureTable = AsClassType.FeatureTable; if (!FeatureName.TableContain(RightFeatureTable, ValidText, out IFeatureName Key, out IFeatureInstance Value)) { errorList.AddError(new ErrorUnknownIdentifier(RightExpression, ValidText)); return(false); } ICompiledFeature OperatorFeature = Value.Feature; ICompiledType OperatorType = OperatorFeature.ResolvedAgentType.Item; if (OperatorFeature is IFunctionFeature AsFunctionFeature && OperatorType is IFunctionType AsFunctionType) { IList <IQueryOverloadType> OperatorOverloadList = AsFunctionType.OverloadList; int SelectedOperatorIndex = -1; for (int i = 0; i < OperatorOverloadList.Count; i++) { IQueryOverloadType Overload = OperatorOverloadList[i]; if (Overload.ParameterList.Count == 0 && Overload.ResultList.Count == 1) { SelectedOperatorIndex = i; break; } } if (SelectedOperatorIndex < 0) { errorList.AddError(new ErrorInvalidOperator(Operator, ValidText)); return(false); } resolvedResult = Feature.CommonResultType(AsFunctionType.OverloadList); selectedFeature = AsFunctionFeature; selectedOverload = AsFunctionFeature.OverloadList[SelectedOperatorIndex]; selectedOverloadType = OperatorOverloadList[SelectedOperatorIndex]; resolvedException = new ResultException(selectedOverloadType.ExceptionIdentifierList); constantSourceList.Add(RightExpression); } else { errorList.AddError(new ErrorInvalidOperator(Operator, ValidText)); return(false); } }
/// <summary> /// Finds the matching nodes of a <see cref="IBinaryOperatorExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The constant value upon return, if any.</param> /// <param name="selectedFeature">The matching feature upon return.</param> /// <param name="selectedOverload">The matching overload in <paramref name="selectedFeature"/> upon return.</param> /// <param name="featureCall">Details of the feature call.</param> public static bool ResolveCompilerReferences(IBinaryOperatorExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant, out IFunctionFeature selectedFeature, out IQueryOverload selectedOverload, out IFeatureCall featureCall) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; selectedFeature = null; selectedOverload = null; featureCall = null; IExpression LeftExpression = (IExpression)node.LeftExpression; IIdentifier Operator = (IIdentifier)node.Operator; IExpression RightExpression = (IExpression)node.RightExpression; IResultType LeftResult = LeftExpression.ResolvedResult.Item; if (LeftResult.TryGetResult(out ICompiledType LeftExpressionType)) { if (LeftExpressionType is IClassType AsClassType) { string OperatorName = Operator.ValidText.Item; ISealableDictionary <IFeatureName, IFeatureInstance> LeftFeatureTable = AsClassType.FeatureTable; if (!FeatureName.TableContain(LeftFeatureTable, OperatorName, out IFeatureName Key, out IFeatureInstance Value)) { errorList.AddError(new ErrorUnknownIdentifier(Operator, OperatorName)); return(false); } Debug.Assert(Value.Feature != null); ICompiledFeature OperatorFeature = Value.Feature; ICompiledType OperatorType = OperatorFeature.ResolvedAgentType.Item; if (OperatorFeature is IFunctionFeature AsFunctionFeature && OperatorType is FunctionType AsFunctionType) { IList <ISealableList <IParameter> > ParameterTableList = new List <ISealableList <IParameter> >(); foreach (IQueryOverloadType Overload in AsFunctionType.OverloadList) { ParameterTableList.Add(Overload.ParameterTable); } IResultType RightResult = RightExpression.ResolvedResult.Item; if (!Argument.ArgumentsConformToParameters(ParameterTableList, RightResult.ToList(), TypeArgumentStyles.Positional, errorList, Operator, out int SelectedIndex)) { return(false); } IQueryOverloadType SelectedOverloadType = AsFunctionType.OverloadList[SelectedIndex]; resolvedResult = new ResultType(SelectedOverloadType.ResultTypeList); selectedFeature = AsFunctionFeature; selectedOverload = AsFunctionFeature.OverloadList[SelectedIndex]; IArgument FirstArgument = new PositionalArgument(RightExpression); IList <IArgument> ArgumentList = new List <IArgument>() { FirstArgument }; List <IExpressionType> MergedArgumentList = new List <IExpressionType>(); bool IsArgumentValid = Argument.Validate(ArgumentList, MergedArgumentList, out TypeArgumentStyles TypeArgumentStyle, errorList); Debug.Assert(IsArgumentValid); featureCall = new FeatureCall(SelectedOverloadType.ParameterTable, SelectedOverloadType.ResultTable, ArgumentList, MergedArgumentList, TypeArgumentStyle); resolvedException = new ResultException(SelectedOverloadType.ExceptionIdentifierList); constantSourceList.Add(LeftExpression); constantSourceList.Add(RightExpression); } else { errorList.AddError(new ErrorInvalidOperator(Operator, OperatorName)); return(false); } } else { errorList.AddError(new ErrorInvalidExpression(LeftExpression)); return(false); } }