/// <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(IAttachmentInstruction node, object data) { IExpression AttachmentSource = (IExpression)node.Source; IResultType SourceTypeList = AttachmentSource.ResolvedResult.Item; IClass EmbeddingClass = node.EmbeddingClass; IList <IList <ITypeName> > FullAttachmentTypeNameList = ((Tuple <IList <IList <ITypeName> >, IList <IList <ICompiledType> > >)data).Item1; IList <IList <ICompiledType> > FullAttachmentTypeList = ((Tuple <IList <IList <ITypeName> >, IList <IList <ICompiledType> > >)data).Item2; for (int i = 0; i < node.EntityNameList.Count; i++) { IExpressionType Item = SourceTypeList.At(i); IName ItemName = node.EntityNameList[i]; string ValidText = ItemName.ValidText.Item; IList <ITypeName> AttachmentTypeNameList = FullAttachmentTypeNameList[i]; IList <ICompiledType> AttachmentTypeList = FullAttachmentTypeList[i]; for (int j = 0; j < node.AttachmentList.Count; j++) { IAttachment Attachment = node.AttachmentList[j]; ITypeName AttachmentTypeName = AttachmentTypeNameList[j]; ICompiledType AttachmentType = AttachmentTypeList[j]; IScopeAttributeFeature TypeFixedEntity = Attachment.FullScope[ValidText]; TypeFixedEntity.FixFeatureType(AttachmentTypeName, AttachmentType); Attachment.ResolvedLocalEntitiesList.Add(TypeFixedEntity); } } node.ResolvedInitResult.Item = ResultType.Empty; }
/// <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(IAttachmentInstruction node, IDictionary <ISourceTemplate, object> dataList, out object data) { data = null; bool Success = true; IExpression AttachmentSource = (IExpression)node.Source; IResultType SourceTypeList = AttachmentSource.ResolvedResult.Item; IClass EmbeddingClass = node.EmbeddingClass; IList <IList <ITypeName> > FullAttachmentTypeNameList = new List <IList <ITypeName> >(); IList <IList <ICompiledType> > FullAttachmentTypeList = new List <IList <ICompiledType> >(); if (SourceTypeList.Count < node.EntityNameList.Count) { AddSourceError(new ErrorInvalidInstruction(node)); Success = false; } else { for (int i = 0; i < node.EntityNameList.Count; i++) { IList <ITypeName> AttachmentTypeNameList = new List <ITypeName>(); IList <ICompiledType> AttachmentTypeList = new List <ICompiledType>(); FullAttachmentTypeNameList.Add(AttachmentTypeNameList); FullAttachmentTypeList.Add(AttachmentTypeList); } for (int i = 0; i < node.EntityNameList.Count; i++) { IExpressionType Item = SourceTypeList.At(i); IName ItemName = node.EntityNameList[i]; IList <ITypeName> AttachmentTypeNameList = FullAttachmentTypeNameList[i]; IList <ICompiledType> AttachmentTypeList = FullAttachmentTypeList[i]; foreach (IAttachment Attachment in node.AttachmentList) { IObjectType AttachedType = Attachment.AttachTypeList[i]; ISealableDictionary <string, IScopeAttributeFeature> CheckedScope = Attachment.FullScope; IList <IClass> AssignedSingleClassList = new List <IClass>(); IErrorList CheckErrorList = new ErrorList(); if (ScopeHolder.HasConflictingSingleAttributes(CheckedScope, node.InnerScopes, AssignedSingleClassList, node, CheckErrorList)) { AddSourceErrorList(CheckErrorList); Success = false; } AttachmentTypeNameList.Add(AttachedType.ResolvedTypeName.Item); AttachmentTypeList.Add(AttachedType.ResolvedType.Item); } } data = new Tuple <IList <IList <ITypeName> >, IList <IList <ICompiledType> > >(FullAttachmentTypeNameList, FullAttachmentTypeList); } return(Success); }
/// <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(IFunctionType node, object data) { IResultType CommonResults = (IResultType)data; int Index = CommonResults.ResultNameIndex >= 0 ? CommonResults.ResultNameIndex : 0; IExpressionType MostCommonResult = CommonResults.At(Index); node.MostCommonResult.Item = MostCommonResult; }
/// <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(IFunctionFeature node, object data) { IResultType CommonResults = (IResultType)data; int Index = CommonResults.ResultNameIndex >= 0 ? CommonResults.ResultNameIndex : 0; IExpressionType MostCommonResult = CommonResults.At(Index); node.MostCommonResult.Item = MostCommonResult; node.ResolvedEffectiveTypeName.Item = MostCommonResult.ValueTypeName; node.ResolvedEffectiveType.Item = MostCommonResult.ValueType; }
/// <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(IInspectInstruction node, IDictionary <ISourceTemplate, object> dataList, out object data) { data = null; IExpression Source = (IExpression)node.Source; IResultType ResolvedResult = Source.ResolvedResult.Item; IClass EmbeddingClass = node.EmbeddingClass; if (ResolvedResult.Count > 1) { AddSourceError(new ErrorInvalidExpression(Source)); return(false); } ICompiledType ValueType = ResolvedResult.At(0).ValueType; ISealableDictionary <IFeatureName, IDiscrete> EnforcedDiscreteTable = null; if (ValueType is IClassType AsClassType) { if (!CheckConsistencyClassType(node, AsClassType, ref EnforcedDiscreteTable)) { return(false); } } else { AddSourceError(new ErrorInvalidExpression(Source)); return(false); } if (!CheckConsistencyRange(node, EnforcedDiscreteTable)) { return(false); } IResultException ResolvedException = new ResultException(); ResultException.Merge(ResolvedException, Source.ResolvedException.Item); foreach (IWith Item in node.WithList) { ResultException.Merge(ResolvedException, Item.ResolvedException.Item); } if (node.ElseInstructions.IsAssigned) { IScope ElseInstructions = (IScope)node.ElseInstructions.Item; ResultException.Merge(ResolvedException, ElseInstructions.ResolvedException.Item); } data = ResolvedException; return(true); }
/// <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(IConditional node, IDictionary <ISourceTemplate, object> dataList, out object data) { data = null; bool Success = true; IExpression BooleanExpression = (IExpression)node.BooleanExpression; IScope Instructions = (IScope)node.Instructions; IResultType ResolvedResult = BooleanExpression.ResolvedResult.Item; IClass EmbeddingClass = node.EmbeddingClass; if (ResolvedResult.Count > 1) { AddSourceError(new ErrorInvalidExpression(BooleanExpression)); Success = false; } else { bool IsBooleanTypeAvailable = Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName BooleanTypeName, out ICompiledType BooleanType); bool IsEventTypeAvailable = Expression.IsLanguageTypeAvailable(LanguageClasses.Event.Guid, node, out ITypeName EventTypeName, out ICompiledType EventType); if (!IsBooleanTypeAvailable && !IsEventTypeAvailable) { AddSourceError(new ErrorBooleanTypeMissing(node)); Success = false; } else { ICompiledType ContractType = ResolvedResult.At(0).ValueType; if (!IsValidType(ContractType, IsBooleanTypeAvailable, BooleanType) && !IsValidType(ContractType, IsEventTypeAvailable, EventType)) { AddSourceError(new ErrorInvalidExpression(BooleanExpression)); Success = false; } else { IResultException ResolvedException = new ResultException(); ResultException.Merge(ResolvedException, BooleanExpression.ResolvedException.Item); ResultException.Merge(ResolvedException, Instructions.ResolvedException.Item); data = ResolvedException; } } } return(Success); }
private bool IsForLoopTypeAvailable(IForLoopInstruction node) { bool IsBooleanTypeAvailable = Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName BooleanTypeName, out ICompiledType BooleanType); bool IsNumberTypeAvailable = Expression.IsLanguageTypeAvailable(LanguageClasses.Number.Guid, node, out ITypeName NumberTypeName, out ICompiledType NumberType); if (node.Variant.IsAssigned && !IsNumberTypeAvailable) { AddSourceError(new ErrorNumberTypeMissing(node)); return(false); } if (!IsBooleanTypeAvailable) { AddSourceError(new ErrorBooleanTypeMissing(node)); return(false); } IExpression WhileCondition = (IExpression)node.WhileCondition; IResultType ResolvedResult = WhileCondition.ResolvedResult.Item; IExpressionType ContractType = ResolvedResult.At(0); if (ContractType.ValueType != BooleanType) { AddSourceError(new ErrorInvalidExpression(WhileCondition)); return(false); } bool Success = true; if (node.Variant.IsAssigned) { IExpression VariantCondition = (IExpression)node.Variant.Item; foreach (IExpressionType Item in VariantCondition.ResolvedResult.Item) { if (Item.ValueType != NumberType) { AddSourceError(new ErrorInvalidExpression(VariantCondition)); Success = false; } } } return(Success); }
/// <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) { ILanguageConstant ExpressionConstant = NeutralLanguageConstant.NotConstant; Debug.Assert(node.ConstantSourceList.Count == 2); IExpression LeftConstantSource = node.ConstantSourceList[0]; Debug.Assert(LeftConstantSource == node.LeftExpression); IExpression RightConstantSource = node.ConstantSourceList[1]; Debug.Assert(RightConstantSource == node.RightExpression); Debug.Assert(LeftConstantSource.ExpressionConstant.IsAssigned); ILanguageConstant LeftExpressionConstant = LeftConstantSource.ExpressionConstant.Item; Debug.Assert(RightConstantSource.ExpressionConstant.IsAssigned); ILanguageConstant RightExpressionConstant = RightConstantSource.ExpressionConstant.Item; if (LeftExpressionConstant != NeutralLanguageConstant.NotConstant && RightExpressionConstant != NeutralLanguageConstant.NotConstant) { Debug.Assert(node.ResolvedResult.IsAssigned); IResultType ResolvedResult = node.ResolvedResult.Item; if (ResolvedResult.Count == 1) { IExpressionType ConstantType = ResolvedResult.At(0); bool IsBooleanTypeAvailable = Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName BooleanTypeName, out ICompiledType BooleanType); bool IsNumberTypeAvailable = Expression.IsLanguageTypeAvailable(LanguageClasses.Number.Guid, node, out ITypeName NumberTypeName, out ICompiledType NumberType); if (IsBooleanTypeAvailable && ConstantType.ValueType == BooleanType) { ExpressionConstant = new BooleanLanguageConstant(); } else if (IsNumberTypeAvailable && ConstantType.ValueType == NumberType) { ExpressionConstant = new NumberLanguageConstant(); } } } node.ExpressionConstant.Item = ExpressionConstant; }
/// <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; // This is ensured because the root node is valid. Debug.Assert(node.OverloadList.Count > 0); IFunctionType ResolvedFeatureType = node.ResolvedAgentType.Item as IFunctionType; Debug.Assert(ResolvedFeatureType != null); foreach (IQueryOverloadType OverloadType in ResolvedFeatureType.OverloadList) { // TODO find why not // Debug.Assert(OverloadType.ConformantResultTable.IsSealed); Debug.Assert(OverloadType.ResultTypeList.Count == OverloadType.ResultTable.Count); } IList <IQueryOverloadType> OverloadTypeList = ResolvedFeatureType.OverloadList; IResultType CommonResults = Feature.CommonResultType(OverloadTypeList); IErrorList CheckErrorList = new ErrorList(); for (int i = 0; i < CommonResults.Count; i++) { Success &= Feature.JoinedResultCheck(OverloadTypeList, i, CommonResults.At(i).ValueType, node, CheckErrorList); } if (!Success) { Debug.Assert(!CheckErrorList.IsEmpty); AddSourceErrorList(CheckErrorList); } if (Success) { data = CommonResults; } return(Success); }
/// <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); }
/// <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> /// 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(IKeywordAssignmentInstruction node, IDictionary <ISourceTemplate, object> dataList, out object data) { data = null; bool Success = true; IExpression SourceExpression = (IExpression)node.Source; IResultType SourceResult = SourceExpression.ResolvedResult.Item; if (SourceResult.Count != 1) { AddSourceError(new ErrorAssignmentMismatch(node)); return(false); } IClass EmbeddingClass = node.EmbeddingClass; IClassType BaseType = EmbeddingClass.ResolvedClassType.Item; ICompiledType SourceType = SourceResult.At(0).ValueType; ICompiledType DestinationType = null; if (node.Destination == BaseNode.Keyword.Result) { if (node.EmbeddingFeature is IPropertyFeature AsPropertyFeature) { DestinationType = AsPropertyFeature.ResolvedEntityType.Item; } else if (node.EmbeddingFeature is IIndexerFeature AsIndexerFeature) { DestinationType = AsIndexerFeature.ResolvedEntityType.Item; } else if (node.EmbeddingOverload is IQueryOverload AsQueryOverload) { if (AsQueryOverload.ResultTable.Count == 1) { IParameter SingleResult = AsQueryOverload.ResultTable[0]; if (SingleResult.Name == nameof(BaseNode.Keyword.Result)) { DestinationType = SingleResult.ResolvedParameter.ResolvedEffectiveType.Item; } } } if (DestinationType == null) { AddSourceError(new ErrorInvalidAssignment(node)); return(false); } } else if (node.Destination == BaseNode.Keyword.Retry) { if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName BooleanTypeName, out ICompiledType BooleanType)) { AddSourceError(new ErrorBooleanTypeMissing(node)); return(false); } DestinationType = BooleanType; } else { AddSourceError(new ErrorInvalidAssignment(node)); return(false); } ISealableDictionary <string, IScopeAttributeFeature> LocalScope = Scope.CurrentScope(node); if (!ObjectType.TypeConformToBase(SourceType, DestinationType, ErrorList, node, isConversionAllowed: true)) { AddSourceError(new ErrorAssignmentMismatch(node)); return(false); } data = SourceExpression.ResolvedException.Item; 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(IAttachmentInstruction node, IDictionary <ISourceTemplate, object> dataList, out object data) { data = null; bool Success = true; IExpression SourceExpression = (IExpression)node.Source; IResultType SourceResult = SourceExpression.ResolvedResult.Item; IClass EmbeddingClass = node.EmbeddingClass; int MaxAttachmentCount = 0; foreach (IAttachment AttachmentItem in node.AttachmentList) { if (AttachmentItem.AttachTypeList.Count > SourceResult.Count) { AddSourceError(new ErrorInvalidAttachment(AttachmentItem)); return(false); } else if (MaxAttachmentCount < AttachmentItem.AttachTypeList.Count) { MaxAttachmentCount = AttachmentItem.AttachTypeList.Count; } } for (int i = 0; i < node.AttachmentList.Count; i++) { IAttachment Attachment = node.AttachmentList[i]; bool ConformanceError = true; for (int j = 0; j < MaxAttachmentCount; j++) { if (j < Attachment.AttachTypeList.Count) { ICompiledType SourceType = SourceResult.At(j).ValueType; IObjectType AttachType = Attachment.AttachTypeList[j]; ICompiledType DestinationType = AttachType.ResolvedType.Item; if (!ObjectType.TypesHaveCommonDescendant(EmbeddingClass, DestinationType, SourceType)) { AddSourceError(new ErrorInvalidAttachment(Attachment)); return(false); } else { ConformanceError &= CheckConsistencyTyped(node, i, j, DestinationType); } } } if (ConformanceError) { AddSourceError(new ErrorInvalidAttachment(Attachment)); return(false); } } if (Success) { IResultException ResolvedException = new ResultException(); ResultException.Merge(ResolvedException, SourceExpression.ResolvedException.Item); foreach (IAttachment Item in node.AttachmentList) { ResultException.Merge(ResolvedException, Item.ResolvedException.Item); } if (node.ElseInstructions.IsAssigned) { IScope ElseInstructions = (IScope)node.ElseInstructions.Item; ResultException.Merge(ResolvedException, ElseInstructions.ResolvedException.Item); } data = ResolvedException; } return(Success); }