/// <summary> /// Initializes a new instance of the <see cref="CSharpUnaryOperatorExpression"/> class. /// </summary> /// <param name="context">The creation context.</param> /// <param name="source">The Easly expression from which the C# expression is created.</param> protected CSharpUnaryOperatorExpression(ICSharpContext context, IUnaryOperatorExpression source) : base(context, source) { RightExpression = Create(context, (IExpression)source.RightExpression); Operator = context.GetFeature(source.SelectedFeature.Item) as ICSharpFunctionFeature; Debug.Assert(Operator != null); FeatureCall = new CSharpFeatureCall(context, new FeatureCall()); IResultType ResolvedRightResult = RightExpression.Source.ResolvedResult.Item; IExpressionType PreferredRightResult = ResolvedRightResult.Preferred; Debug.Assert(PreferredRightResult != null); if (PreferredRightResult.ValueType is IClassType AsClassType) { if (AsClassType.BaseClass.ClassGuid == LanguageClasses.Number.Guid) { IsCallingNumberFeature = true; } } if (IsCallingNumberFeature) { Debug.Assert(ResolvedRightResult.Count == 1); } Debug.Assert(Source.SelectedOverload.IsAssigned); IQueryOverload Overload = Source.SelectedOverload.Item; IQueryOverloadType ResolvedAssociatedType = Overload.ResolvedAssociatedType.Item; SelectedOverloadType = CSharpQueryOverloadType.Create(context, ResolvedAssociatedType, Operator.Owner); }
/// <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(IUnaryOperatorExpression node, object data) { IResultType ResolvedResult = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IQueryOverloadType>)data).Item1; IResultException ResolvedException = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IQueryOverloadType>)data).Item2; ISealableList <IExpression> ConstantSourceList = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IQueryOverloadType>)data).Item3; ILanguageConstant ExpressionConstant = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IQueryOverloadType>)data).Item4; IFunctionFeature SelectedFeature = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IQueryOverloadType>)data).Item5; IQueryOverload SelectedOverload = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IQueryOverloadType>)data).Item6; IQueryOverloadType SelectedOverloadType = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IQueryOverloadType>)data).Item7; node.ResolvedException.Item = ResolvedException; }
/// <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(IBinaryOperatorExpression node, object data) { IResultType ResolvedResult = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IFeatureCall>)data).Item1; IResultException ResolvedException = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IFeatureCall>)data).Item2; ISealableList <IExpression> ConstantSourceList = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IFeatureCall>)data).Item3; ILanguageConstant ExpressionConstant = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IFeatureCall>)data).Item4; IFunctionFeature SelectedFeature = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IFeatureCall>)data).Item5; IQueryOverload SelectedOverload = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IFeatureCall>)data).Item6; IFeatureCall FeatureCall = ((Tuple <IResultType, IResultException, ISealableList <IExpression>, ILanguageConstant, IFunctionFeature, IQueryOverload, IFeatureCall>)data).Item7; node.ResolvedResult.Item = ResolvedResult; node.ConstantSourceList.AddRange(ConstantSourceList); node.ConstantSourceList.Seal(); node.SelectedFeature.Item = SelectedFeature; node.SelectedOverload.Item = SelectedOverload; node.FeatureCall.Item = FeatureCall; }
/// <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(IFunctionFeature node, IDictionary <ISourceTemplate, object> dataList, out object data) { data = null; bool Success = true; IName EntityName = (IName)((IFeatureWithName)node).EntityName; // This is ensured because the root node is valid. Debug.Assert(node.OverloadList.Count > 0); IQueryOverload FirstOverload = node.OverloadList[0]; ICompiledBody FirstOverloadBody = (ICompiledBody)FirstOverload.QueryBody; for (int i = 1; i < node.OverloadList.Count; i++) { IQueryOverload ThisOverload = node.OverloadList[i]; ICompiledBody ThisOverloadBody = (ICompiledBody)ThisOverload.QueryBody; if (ThisOverloadBody.IsDeferredBody != FirstOverloadBody.IsDeferredBody) { ErrorList.AddError(new ErrorBodyTypeMismatch(ThisOverload, EntityName.ValidText.Item)); Success = false; break; } } IErrorList CheckErrorList = new ErrorList(); IList <IQueryOverloadType> OverloadTypeList = new List <IQueryOverloadType>(); foreach (IQueryOverload Overload in node.OverloadList) { Debug.Assert(Overload.ResolvedAssociatedType.IsAssigned); OverloadTypeList.Add(Overload.ResolvedAssociatedType.Item); } if (!Feature.DisjoinedParameterCheck(OverloadTypeList, CheckErrorList)) { Debug.Assert(!CheckErrorList.IsEmpty); AddSourceErrorList(CheckErrorList); Success = false; } return(Success); }
private static bool CheckQueryConsistency(ISource source, IQueryOverload innerQueryOverload, IErrorList errorList, out ITypeName resultTypeName, out ICompiledType resultType) { resultTypeName = null; resultType = null; bool Success = false; foreach (IParameter Item in innerQueryOverload.ResultTable) { if (Item.Name == nameof(BaseNode.Keyword.Result)) { resultTypeName = Item.ResolvedParameter.ResolvedEffectiveTypeName.Item; resultType = Item.ResolvedParameter.ResolvedEffectiveType.Item; Success = true; break; } } if (!Success) { errorList.AddError(new ErrorResultNotReturned(source)); } return(Success); }
/// <summary> /// Initializes a new instance of the <see cref="CSharpBinaryOperatorExpression"/> class. /// </summary> /// <param name="source">The Easly expression from which the C# expression is created.</param> /// <param name="context">The creation context.</param> protected CSharpBinaryOperatorExpression(ICSharpContext context, IBinaryOperatorExpression source) : base(context, source) { LeftExpression = Create(context, (IExpression)source.LeftExpression); RightExpression = Create(context, (IExpression)source.RightExpression); Operator = context.GetFeature(source.SelectedFeature.Item) as ICSharpFunctionFeature; Debug.Assert(Operator != null); IResultType ResolvedLeftResult = LeftExpression.Source.ResolvedResult.Item; IExpressionType PreferredLeftResult = ResolvedLeftResult.Preferred; Debug.Assert(PreferredLeftResult != null); if (PreferredLeftResult.ValueType is IClassType AsClassType) { if (AsClassType.BaseClass.ClassGuid == LanguageClasses.Number.Guid || AsClassType.BaseClass.ClassGuid == LanguageClasses.Integer.Guid) { IsCallingNumberFeature = true; } } if (IsCallingNumberFeature) { IResultType ResolvedRightResult = RightExpression.Source.ResolvedResult.Item; Debug.Assert(ResolvedRightResult.Count == 1); } else { if (!LeftExpression.IsSingleResult) { IResultType LeftResultType = LeftExpression.Source.ResolvedResult.Item; LeftNameList = new List <string>(); LeftResultNameIndex = LeftResultType.ResultNameIndex; for (int i = 0; i < LeftResultType.Count; i++) { IExpressionType DestinationType = LeftResultType.At(i); string Text = DestinationType.Name; LeftNameList.Add(Text); } } if (!RightExpression.IsSingleResult) { IResultType RightResultType = RightExpression.Source.ResolvedResult.Item; RightNameList = new List <string>(); RightResultNameIndex = RightResultType.ResultNameIndex; for (int i = 0; i < RightResultType.Count; i++) { IExpressionType DestinationType = RightResultType.At(i); string Text = DestinationType.Name; RightNameList.Add(Text); } } } FeatureCall = new CSharpFeatureCall(context, Source.FeatureCall.Item); Debug.Assert(Source.SelectedOverload.IsAssigned); IQueryOverload Overload = Source.SelectedOverload.Item; IQueryOverloadType ResolvedAssociatedType = Overload.ResolvedAssociatedType.Item; SelectedOverloadType = CSharpQueryOverloadType.Create(context, ResolvedAssociatedType, Operator.Owner); }
/// <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); } }