/// <summary> /// Checks that a result of a list of overloads conform to a base type. /// </summary> /// <param name="overloadList">The list of overloads.</param> /// <param name="index">Index of the result in the possible results.</param> /// <param name="baseType">The base type.</param> /// <param name="location">The location where to report errors.</param> /// <param name="errorList">The list of errors found.</param> public static bool JoinedResultCheck(IList <IQueryOverloadType> overloadList, int index, ICompiledType baseType, ISource location, IErrorList errorList) { bool Success = true; IList <IParameter> SameIndexList = new List <IParameter>(); foreach (IQueryOverloadType Overload in overloadList) { ISealableList <IParameter> ResultTable = Overload.ResultTable; if (index < ResultTable.Count) { SameIndexList.Add(ResultTable[index]); } } for (int i = 0; i < SameIndexList.Count; i++) { IParameter CurrentParameter = SameIndexList[i]; ICompiledType CurrentParameterType = CurrentParameter.ResolvedParameter.ResolvedEffectiveType.Item; if (!ObjectType.TypeConformToBase(CurrentParameterType, baseType, isConversionAllowed: false)) { errorList.AddError(new ErrorNonConformingType(location)); Success = false; } } return(Success); }
private static void GetCommonResultType(IList <IQueryOverloadType> overloadList, int index, out ITypeName resultTypeName, out ICompiledType resultType) { IList <IParameter> SameIndexList = new List <IParameter>(); foreach (IQueryOverloadType Overload in overloadList) { ISealableList <IParameter> ResultTable = Overload.ResultTable; if (index < ResultTable.Count) { SameIndexList.Add(ResultTable[index]); } } IParameter SelectedParameter = SameIndexList[0]; ITypeName SelectedParameterTypeName = SelectedParameter.ResolvedParameter.ResolvedEffectiveTypeName.Item; ICompiledType SelectedParameterType = SelectedParameter.ResolvedParameter.ResolvedEffectiveType.Item; for (int i = 1; i < SameIndexList.Count; i++) { IParameter CurrentParameter = SameIndexList[i]; ITypeName CurrentParameterTypeName = CurrentParameter.ResolvedParameter.ResolvedEffectiveTypeName.Item; ICompiledType CurrentParameterType = CurrentParameter.ResolvedParameter.ResolvedEffectiveType.Item; if (ObjectType.TypeConformToBase(SelectedParameterType, CurrentParameterType, isConversionAllowed: false)) { SelectedParameter = CurrentParameter; SelectedParameterTypeName = CurrentParameterTypeName; SelectedParameterType = CurrentParameterType; } } resultTypeName = SelectedParameterTypeName; resultType = SelectedParameterType; }
private static void PositionalArgumentMatching(IList <ISealableList <IParameter> > parameterTableList, IReadOnlyList <IExpressionType> arguments, int i, ref int maximumAllowedArgumentCount, ref ISealableList <IParameter> selectedOverload, ref int selectedIndex) { ISealableList <IParameter> OverloadParameterList = parameterTableList[i]; int j; bool IsMatching = true; for (j = 0; j < arguments.Count && j < OverloadParameterList.Count && IsMatching; j++) { ICompiledType ArgumentType = arguments[j].ValueType; IParameter OverloadParameter = OverloadParameterList[j]; ICompiledType ParameterType = TypeOfPositionalParameter(OverloadParameter); IsMatching &= ObjectType.TypeConformToBase(ArgumentType, ParameterType, isConversionAllowed: true); } if (IsMatching) { if (maximumAllowedArgumentCount < OverloadParameterList.Count) { maximumAllowedArgumentCount = OverloadParameterList.Count; } for (; j < OverloadParameterList.Count && IsMatching; j++) { IParameter OverloadParameter = OverloadParameterList[j]; IsMatching &= OverloadParameter.ResolvedParameter.DefaultValue.IsAssigned; } } if (IsMatching && j >= arguments.Count) { bool IsBetter = false; if (selectedOverload != null) { IsBetter = SelectMatchingOverload(OverloadParameterList, selectedOverload); } if (selectedOverload == null || IsBetter) { selectedOverload = OverloadParameterList; selectedIndex = i; } } }
private static bool SelectMatchingOverload(ISealableList <IParameter> overloadParameterList, ISealableList <IParameter> selectedOverload) { bool IsBetter = false; for (int j = 0; j < overloadParameterList.Count && j < selectedOverload.Count; j++) { IParameter OverloadParameter = overloadParameterList[j]; ICompiledType OverloadParameterType = TypeOfPositionalParameter(OverloadParameter); IParameter SelectedParameter = selectedOverload[j]; ICompiledType SelectedParameterType = TypeOfPositionalParameter(SelectedParameter); if (OverloadParameterType != SelectedParameterType) { IsBetter |= ObjectType.TypeConformToBase(OverloadParameterType, SelectedParameterType, isConversionAllowed: false); } } return(IsBetter); }
/// <summary> /// Checks the validity of an assignment of a source to a destination, with arguments. /// </summary> /// <param name="parameterTableList">The list of expected parameters.</param> /// <param name="resultTableList">The list of results.</param> /// <param name="argumentList">The list of actual arguments.</param> /// <param name="sourceExpression">Expression in the assignment.</param> /// <param name="destinationType">The expected type for the expression.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="source">The source to use when reporting errors.</param> /// <param name="featureCall">Details of the feature call.</param> public static bool CheckAssignmentConformance(IList <ISealableList <IParameter> > parameterTableList, IList <ISealableList <IParameter> > resultTableList, IList <IArgument> argumentList, IExpression sourceExpression, ICompiledType destinationType, IErrorList errorList, ISource source, out IFeatureCall featureCall) { featureCall = null; IResultType SourceResult = sourceExpression.ResolvedResult.Item; List <IExpressionType> MergedArgumentList = new List <IExpressionType>(); if (!Argument.Validate(argumentList, MergedArgumentList, out TypeArgumentStyles TypeArgumentStyle, errorList)) { return(false); } if (!Argument.ArgumentsConformToParameters(parameterTableList, MergedArgumentList, TypeArgumentStyle, errorList, source, out int SelectedIndex)) { return(false); } if (SourceResult.Count != 1) { errorList.AddError(new ErrorInvalidExpression(sourceExpression)); return(false); } ISealableList <IParameter> SelectedParameterList = parameterTableList[SelectedIndex]; ISealableList <IParameter> SelectedResultList = resultTableList[SelectedIndex]; ICompiledType SourceType = SourceResult.At(0).ValueType; if (!ObjectType.TypeConformToBase(SourceType, destinationType, errorList, sourceExpression, isConversionAllowed: true)) { errorList.AddError(new ErrorInvalidExpression(sourceExpression)); return(false); } featureCall = new FeatureCall(SelectedParameterList, SelectedResultList, argumentList, MergedArgumentList, TypeArgumentStyle); return(true); }
private static bool AssignmentArgumentsConformToParameters(IList <ISealableList <IParameter> > parameterTableList, IReadOnlyList <IExpressionType> arguments, IErrorList errorList, ISource source, out int selectedIndex) { ISealableList <IParameter> SelectedOverload = null; selectedIndex = -1; for (int i = 0; i < parameterTableList.Count; i++) { ISealableList <IParameter> OverloadParameterList = parameterTableList[i]; List <IParameter> UnassignedParameters = new List <IParameter>(OverloadParameterList); bool IsMatching = true; for (int j = 0; j < arguments.Count && IsMatching; j++) { ICompiledType ArgumentType = arguments[j].ValueType; string ArgumentName = arguments[j].Name; OnceReference <IParameter> MatchingParameter = new OnceReference <IParameter>(); foreach (IParameter p in OverloadParameterList) { if (p.Name == ArgumentName) { MatchingParameter.Item = p; break; } } if (!MatchingParameter.IsAssigned) { errorList.AddError(new ErrorArgumentNameMismatch(source, ArgumentName)); return(false); } IParameter OverloadParameter = MatchingParameter.Item; UnassignedParameters.Remove(OverloadParameter); ICompiledType ParameterType = OverloadParameter.ResolvedParameter.ResolvedEffectiveType.Item; IsMatching &= ObjectType.TypeConformToBase(ArgumentType, ParameterType, isConversionAllowed: true); } foreach (IParameter OverloadParameter in UnassignedParameters) { IsMatching &= OverloadParameter.ResolvedParameter.DefaultValue.IsAssigned; } if (IsMatching) { Debug.Assert(SelectedOverload == null); SelectedOverload = OverloadParameterList; selectedIndex = i; } } if (SelectedOverload == null) { errorList.AddError(new ErrorInvalidExpression(source)); return(false); } else { return(true); } }
/// <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); }