/// <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(ICommandInstruction node, IDictionary <ISourceTemplate, object> dataList, out object data) { data = null; bool Success = true; IQualifiedName Command = (IQualifiedName)node.Command; IList <IIdentifier> ValidPath = Command.ValidPath.Item; IClass EmbeddingClass = node.EmbeddingClass; IClassType BaseType = EmbeddingClass.ResolvedClassType.Item; ISealableDictionary <string, IScopeAttributeFeature> LocalScope = Scope.CurrentScope(node); if (!ObjectType.GetQualifiedPathFinalType(EmbeddingClass, BaseType, LocalScope, ValidPath, 0, ErrorList, out ICompiledFeature FinalFeature, out IDiscrete FinalDiscrete, out ITypeName FinalTypeName, out ICompiledType FinalType, out bool InheritBySideAttribute)) { return(false); } Debug.Assert(FinalFeature != null); IList <IArgument> ArgumentList = node.ArgumentList; List <IExpressionType> MergedArgumentList = new List <IExpressionType>(); if (!Argument.Validate(ArgumentList, MergedArgumentList, out TypeArgumentStyles ArgumentStyle, ErrorList)) { return(false); } IList <ISealableList <IParameter> > ParameterTableList = new List <ISealableList <IParameter> >(); ICommandOverloadType SelectedOverload = null; ISealableList <IParameter> SelectedParameterList = null; IProcedureType CommandFinalType = null; bool IsHandled = false; switch (FinalType) { case IFunctionType AsFunctionType: case IPropertyType AsPropertyType: AddSourceError(new ErrorInvalidInstruction(node)); Success = false; IsHandled = true; break; case IProcedureType AsProcedureType: foreach (ICommandOverloadType Overload in AsProcedureType.OverloadList) { ParameterTableList.Add(Overload.ParameterTable); } int SelectedIndex; if (!Argument.ArgumentsConformToParameters(ParameterTableList, MergedArgumentList, ArgumentStyle, ErrorList, node, out SelectedIndex)) { Success = false; } else { SelectedOverload = AsProcedureType.OverloadList[SelectedIndex]; SelectedParameterList = ParameterTableList[SelectedIndex]; CommandFinalType = AsProcedureType; } IsHandled = true; break; } Debug.Assert(IsHandled); if (Success) { ObjectType.FillResultPath(EmbeddingClass, BaseType, LocalScope, ValidPath, 0, Command.ValidResultTypePath.Item); IResultException ResolvedException = new ResultException(); foreach (IArgument Item in node.ArgumentList) { ResultException.Merge(ResolvedException, Item.ResolvedException.Item); } IList <IIdentifier> CommandInstructionException = SelectedOverload.ExceptionIdentifierList; ResultException.Merge(ResolvedException, CommandInstructionException); IFeatureCall FeatureCall = new FeatureCall(SelectedParameterList, new List <IParameter>(), ArgumentList, MergedArgumentList, ArgumentStyle); data = new Tuple <IResultException, ICompiledFeature, ICommandOverloadType, IFeatureCall, IProcedureType>(ResolvedException, FinalFeature, SelectedOverload, FeatureCall, CommandFinalType); } 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(IIndexAssignmentInstruction node, IDictionary <ISourceTemplate, object> dataList, out object data) { data = null; bool Success = true; IQualifiedName Destination = (IQualifiedName)node.Destination; IExpression Source = (IExpression)node.Source; IList <IIdentifier> ValidPath = Destination.ValidPath.Item; IClass EmbeddingClass = node.EmbeddingClass; IClassType BaseType = EmbeddingClass.ResolvedClassType.Item; ISealableDictionary <string, IScopeAttributeFeature> LocalScope = Scope.CurrentScope(node); if (!ObjectType.GetQualifiedPathFinalType(EmbeddingClass, BaseType, LocalScope, ValidPath, 0, ErrorList, out ICompiledFeature FinalFeature, out IDiscrete FinalDiscrete, out ITypeName FinalTypeName, out ICompiledType FinalType, out bool InheritBySideAttribute)) { return(false); } Debug.Assert(FinalFeature != null); FinalType = FinalFeature.ResolvedEffectiveType.Item; if (FinalType is IClassType AsClassType) { IClass IndexedBaseClass = AsClassType.BaseClass; ISealableDictionary <IFeatureName, IFeatureInstance> IndexedFeatureTable = IndexedBaseClass.FeatureTable; if (!IndexedFeatureTable.ContainsKey(FeatureName.IndexerFeatureName)) { AddSourceError(new ErrorMissingIndexer(node)); return(false); } IFeatureInstance IndexerInstance = IndexedFeatureTable[FeatureName.IndexerFeatureName]; IIndexerFeature Indexer = (IndexerFeature)IndexerInstance.Feature; IIndexerType AsIndexerType = (IndexerType)Indexer.ResolvedAgentType.Item; bool IsReadOnlyIndexer = Indexer.GetterBody.IsAssigned && !Indexer.SetterBody.IsAssigned; bool IsReadOnlyIndexerType = AsIndexerType.IndexerKind == BaseNode.UtilityType.ReadOnly; Debug.Assert(IsReadOnlyIndexerType == IsReadOnlyIndexer); if (IsReadOnlyIndexer) { AddSourceError(new ErrorInvalidInstruction(node)); return(false); } else { IList <ISealableList <IParameter> > ParameterTableList = new List <ISealableList <IParameter> >(); ParameterTableList.Add(AsIndexerType.ParameterTable); IList <ISealableList <IParameter> > ResultTableList = new List <ISealableList <IParameter> >(); ResultTableList.Add(new SealableList <IParameter>()); ICompiledType DestinationType = AsIndexerType.ResolvedEntityType.Item; if (!Argument.CheckAssignmentConformance(ParameterTableList, ResultTableList, node.ArgumentList, Source, DestinationType, ErrorList, node, out IFeatureCall FeatureCall)) { return(false); } ObjectType.FillResultPath(EmbeddingClass, BaseType, LocalScope, ValidPath, 0, Destination.ValidResultTypePath.Item); IResultException ResolvedException = new ResultException(); ResultException.Merge(ResolvedException, AsIndexerType.SetExceptionIdentifierList); foreach (IArgument Item in node.ArgumentList) { ResultException.Merge(ResolvedException, Item.ResolvedException.Item); } data = new Tuple <IResultException, IFeatureCall>(ResolvedException, FeatureCall); } } else { AddSourceError(new ErrorInvalidInstruction(node)); return(false); } return(Success); }