/// <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(IOverLoopInstruction node, IDictionary <ISourceTemplate, object> dataList, out object data)
        {
            data = null;
            bool Success = true;

            IExpression OverList         = (IExpression)node.OverList;
            IResultType OverTypeList     = OverList.ResolvedResult.Item;
            IScope      LoopInstructions = (IScope)node.LoopInstructions;
            IClass      EmbeddingClass   = node.EmbeddingClass;

            bool IsOverLoopSourceTypeAvailable = Expression.IsLanguageTypeAvailable(LanguageClasses.OverLoopSource.Guid, node, out ITypeName OverLoopSourceTypeName, out ICompiledType OverLoopSourceType);
            bool IsNumberTypeAvailable         = Expression.IsLanguageTypeAvailable(LanguageClasses.Number.Guid, node, out ITypeName NumberTypeName, out ICompiledType NumberType);

            foreach (IExpressionType Item in OverTypeList)
            {
                ICompiledType ResultType                   = Item.ValueType;
                IErrorList    OverSourceErrorList          = new ErrorList();
                bool          IsConformantToEnumerable     = false;
                bool          IsConformantToNumericIndexer = false;

                if (IsOverLoopSourceTypeAvailable && ObjectType.TypeConformToBase(ResultType, OverLoopSourceType, isConversionAllowed: true))
                {
                    IsConformantToEnumerable = true;
                }

                if (IsNumberTypeAvailable && ResultType.FeatureTable.ContainsKey(FeatureName.IndexerFeatureName))
                {
                    IFeatureInstance IndexerInstance = ResultType.FeatureTable[FeatureName.IndexerFeatureName];
                    IIndexerFeature  IndexerFeature  = IndexerInstance.Feature as IIndexerFeature;
                    Debug.Assert(IndexerFeature != null);

                    if (IndexerFeature.IndexParameterList.Count == 1)
                    {
                        IEntityDeclaration IndexParameterDeclaration = IndexerFeature.IndexParameterList[0];
                        if (IndexParameterDeclaration.ValidEntity.Item.ResolvedEffectiveType.Item == NumberType)
                        {
                            IsConformantToNumericIndexer = true;
                        }
                    }
                }

                Debug.Assert(IsConformantToEnumerable != IsConformantToNumericIndexer);
            }

            IResultException ResolvedException = new ResultException();

            ResultException.Merge(ResolvedException, OverList.ResolvedException.Item);
            ResultException.Merge(ResolvedException, LoopInstructions.ResolvedException.Item);

            foreach (IAssertion Item in node.InvariantList)
            {
                ResultException.Merge(ResolvedException, Item.ResolvedException.Item);
            }

            data = ResolvedException;

            return(Success);
        }
示例#2
0
        private static bool IsIndexerFeatureReady(IIndexerFeature feature, out ITypeName resolvedPathTypeName, out ICompiledType resolvedPathType)
        {
            bool Result = false;

            resolvedPathTypeName = null;
            resolvedPathType     = null;

            if (feature.ResolvedEntityTypeName.IsAssigned && feature.ResolvedEntityType.IsAssigned)
            {
                resolvedPathTypeName = feature.ResolvedEntityTypeName.Item;
                resolvedPathType     = feature.ResolvedEntityType.Item;
                Result = true;
            }

            return(Result);
        }
示例#3
0
        private static bool ResolveSelectedPrecursor(IPrecursorIndexExpression node, IFeatureInstance selectedPrecursor, IErrorList errorList, ref ResolvedExpression resolvedExpression)
        {
            IList <IArgument> ArgumentList = node.ArgumentList;

            List <IExpressionType> MergedArgumentList = new List <IExpressionType>();

            if (!Argument.Validate(ArgumentList, MergedArgumentList, out TypeArgumentStyles TypeArgumentStyle, errorList))
            {
                return(false);
            }

            IIndexerFeature OperatorFeature = selectedPrecursor.Feature as IIndexerFeature;

            Debug.Assert(OperatorFeature != null);
            IIndexerType OperatorType = OperatorFeature.ResolvedAgentType.Item as IIndexerType;

            Debug.Assert(OperatorType != null);

            IList <ISealableList <IParameter> > ParameterTableList = new List <ISealableList <IParameter> >();

            ParameterTableList.Add(OperatorType.ParameterTable);

            IList <ISealableList <IParameter> > ResultTableList = new List <ISealableList <IParameter> >();

            ResultTableList.Add(new SealableList <IParameter>());

            int SelectedIndex;

            if (!Argument.ArgumentsConformToParameters(ParameterTableList, MergedArgumentList, TypeArgumentStyle, errorList, node, out SelectedIndex))
            {
                return(false);
            }

            resolvedExpression.ResolvedResult = new ResultType(OperatorType.ResolvedEntityTypeName.Item, OperatorType.ResolvedEntityType.Item, string.Empty);

            resolvedExpression.ResolvedException    = new ResultException(OperatorType.GetExceptionIdentifierList);
            resolvedExpression.FeatureCall          = new FeatureCall(ParameterTableList[SelectedIndex], ResultTableList[SelectedIndex], ArgumentList, MergedArgumentList, TypeArgumentStyle);
            resolvedExpression.ResolvedFinalFeature = OperatorFeature;

            Argument.AddConstantArguments(ArgumentList, resolvedExpression.ConstantSourceList);

            return(true);
        }
示例#4
0
        private bool FindIndexer(IClassType instancingClassType, ISource source, IFeatureInstance indexerInstance, out ITypeName indexTypeName, out ICompiledType indexType)
        {
            bool IsConformantToNumericIndexer = false;

            indexTypeName = null;
            indexType     = null;

            IIndexerFeature AsIndexer = indexerInstance.Feature as IIndexerFeature;

            Debug.Assert(AsIndexer != null);

            if (AsIndexer.IndexParameterList.Count == 1)
            {
                if (Expression.IsLanguageTypeAvailable(LanguageClasses.Number.Guid, source, out ITypeName NumberTypeName, out ICompiledType NumberType))
                {
                    IEntityDeclaration IndexParameterDeclaration = AsIndexer.IndexParameterList[0];
                    ICompiledType      IndexParameterType        = IndexParameterDeclaration.ValidEntity.Item.ResolvedEffectiveType.Item;

                    if (IndexParameterType is IClassType AsClassIndexType)
                    {
                        if (AsClassIndexType == NumberType)
                        {
                            ITypeName     IndexResultTypeName = AsIndexer.ResolvedEntityTypeName.Item;
                            ICompiledType IndexResultType     = AsIndexer.ResolvedEntityType.Item;

                            IndexResultType.InstanciateType(instancingClassType, ref IndexResultTypeName, ref IndexResultType);

                            IsConformantToNumericIndexer = true;
                            indexTypeName = IndexResultTypeName;
                            indexType     = IndexResultType;
                        }
                    }
                }
            }

            return(IsConformantToNumericIndexer);
        }
        /// <summary>
        /// Checks that a keyword is available in the context of the source.
        /// </summary>
        /// <param name="keyword">The keyword to check.</param>
        /// <param name="source">The source node.</param>
        /// <param name="errorList">The list of errors found if not available.</param>
        /// <param name="resultTypeName">The resulting type name upon return if available.</param>
        /// <param name="resultType">The resulting type upon return if available.</param>
        public static bool IsKeywordAvailable(BaseNode.Keyword keyword, ISource source, IErrorList errorList, out ITypeName resultTypeName, out ICompiledType resultType)
        {
            resultTypeName = null;
            resultType     = null;
            bool Result    = false;
            bool IsHandled = false;

            IClass EmbeddingClass = source.EmbeddingClass;

            switch (keyword)
            {
            case BaseNode.Keyword.True:
            case BaseNode.Keyword.False:
            case BaseNode.Keyword.Retry:
                if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, source, out resultTypeName, out resultType))
                {
                    errorList.AddError(new ErrorBooleanTypeMissing(source));
                }
                else
                {
                    Result = true;
                }

                IsHandled = true;
                break;

            case BaseNode.Keyword.Current:
                Debug.Assert(EmbeddingClass.ResolvedClassTypeName.IsAssigned);
                Debug.Assert(EmbeddingClass.ResolvedClassType.IsAssigned);
                resultTypeName = EmbeddingClass.ResolvedClassTypeName.Item;
                resultType     = EmbeddingClass.ResolvedClassType.Item;
                Result         = true;
                IsHandled      = true;
                break;

            case BaseNode.Keyword.Value:
                Result    = IsWithinProperty(source, errorList, out resultTypeName, out resultType);
                IsHandled = true;
                break;

            case BaseNode.Keyword.Result:
                Result    = IsWithinGetter(source, errorList, out resultTypeName, out resultType);
                IsHandled = true;
                break;

            case BaseNode.Keyword.Exception:
                if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Exception.Guid, source, out resultTypeName, out resultType))
                {
                    errorList.AddError(new ErrorExceptionTypeMissing(source));
                }
                else
                {
                    Result = true;
                }

                IsHandled = true;
                break;

            case BaseNode.Keyword.Indexer:
                if (EmbeddingClass.ClassIndexer.IsAssigned)
                {
                    IIndexerFeature IndexerFeature = EmbeddingClass.ClassIndexer.Item;

                    Debug.Assert(IndexerFeature.ResolvedAgentTypeName.IsAssigned);
                    Debug.Assert(IndexerFeature.ResolvedAgentType.IsAssigned);

                    resultTypeName = IndexerFeature.ResolvedAgentTypeName.Item;
                    resultType     = IndexerFeature.ResolvedAgentType.Item;
                    Result         = true;
                }
                else
                {
                    errorList.AddError(new ErrorMissingIndexer(source));
                }
                IsHandled = true;
                break;
            }

            Debug.Assert(IsHandled);

            return(Result);
        }
示例#6
0
        /// <summary>
        /// Finds the matching nodes of a <see cref="IIndexQueryExpression"/>.
        /// </summary>
        /// <param name="node">The agent expression to check.</param>
        /// <param name="errorList">The list of errors found.</param>
        /// <param name="resolvedExpression">The result of the search.</param>
        public static bool ResolveCompilerReferences(IIndexQueryExpression node, IErrorList errorList, out ResolvedExpression resolvedExpression)
        {
            resolvedExpression = new ResolvedExpression();

            IExpression       IndexedExpression      = (IExpression)node.IndexedExpression;
            IList <IArgument> ArgumentList           = node.ArgumentList;
            IClass            EmbeddingClass         = node.EmbeddingClass;
            IResultType       ResolvedIndexerResult  = IndexedExpression.ResolvedResult.Item;
            IExpressionType   PreferredIndexerResult = ResolvedIndexerResult.Preferred;
            ICompiledType     IndexedExpressionType;

            if (PreferredIndexerResult == null)
            {
                errorList.AddError(new ErrorInvalidExpression(node));
                return(false);
            }
            else
            {
                IndexedExpressionType = PreferredIndexerResult.ValueType;
            }

            if (IndexedExpressionType is IClassType AsClassType)
            {
                IClass IndexedBaseClass = AsClassType.BaseClass;
                ISealableDictionary <IFeatureName, IFeatureInstance> IndexedFeatureTable = IndexedBaseClass.FeatureTable;

                if (!IndexedFeatureTable.ContainsKey(FeatureName.IndexerFeatureName))
                {
                    errorList.AddError(new ErrorMissingIndexer(node));
                    return(false);
                }

                IFeatureInstance IndexerInstance = IndexedFeatureTable[FeatureName.IndexerFeatureName];
                IIndexerFeature  Indexer         = (IndexerFeature)IndexerInstance.Feature;
                IIndexerType     AsIndexerType   = (IndexerType)Indexer.ResolvedAgentType.Item;

                List <IExpressionType> MergedArgumentList = new List <IExpressionType>();
                if (!Argument.Validate(ArgumentList, MergedArgumentList, out TypeArgumentStyles TypeArgumentStyle, errorList))
                {
                    return(false);
                }

                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>());

                int SelectedIndex;
                if (!Argument.ArgumentsConformToParameters(ParameterTableList, MergedArgumentList, TypeArgumentStyle, errorList, node, out SelectedIndex))
                {
                    return(false);
                }

                resolvedExpression.ResolvedFinalFeature = Indexer;
                resolvedExpression.ResolvedResult       = new ResultType(AsIndexerType.ResolvedEntityTypeName.Item, AsIndexerType.ResolvedEntityType.Item, string.Empty);
                resolvedExpression.ResolvedException    = new ResultException(AsIndexerType.GetExceptionIdentifierList);
                resolvedExpression.FeatureCall          = new FeatureCall(ParameterTableList[SelectedIndex], ResultTableList[SelectedIndex], ArgumentList, MergedArgumentList, TypeArgumentStyle);

                Argument.AddConstantArguments(ArgumentList, resolvedExpression.ConstantSourceList);
            }
            else
            {
                errorList.AddError(new ErrorInvalidExpression(node));
                return(false);
            }

#if COVERAGE
            Debug.Assert(!node.IsComplex);
#endif

            return(true);
        }
示例#7
0
        private static ISealableDictionary <string, IScopeAttributeFeature> CurrentIndexerScope(IIndexerFeature indexerFeature, ISource childSource)
        {
            ISealableDictionary <string, IScopeAttributeFeature> Result = null;
            bool IsHandled = false;

            if (indexerFeature.GetterBody.IsAssigned && indexerFeature.GetterBody.Item == childSource)
            {
                Result    = indexerFeature.FullGetScope;
                IsHandled = true;
            }
            else if (indexerFeature.SetterBody.IsAssigned && indexerFeature.SetterBody.Item == childSource)
            {
                Result    = indexerFeature.FullSetScope;
                IsHandled = true;
            }

            Debug.Assert(IsHandled);

            return(Result);
        }
        /// <summary>
        /// Finds the matching nodes of a <see cref="IKeywordEntityExpression"/>.
        /// </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>
        public static bool ResolveCompilerReferences(IKeywordEntityExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant, out ICompiledFeature resolvedFinalFeature)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (errorList == null)
            {
                throw new ArgumentNullException(nameof(errorList));
            }

            resolvedResult       = null;
            resolvedException    = null;
            constantSourceList   = new SealableList <IExpression>();
            expressionConstant   = NeutralLanguageConstant.NotConstant;
            resolvedFinalFeature = null;

            IClass EmbeddingClass = node.EmbeddingClass;

            BaseNode.Keyword Value = node.Value;

            if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Entity.Guid, node, out ITypeName ResultTypeName, out ICompiledType ResultType))
            {
                errorList.AddError(new ErrorEntityTypeMissing(node));
                return(false);
            }

            Guid EntityGuid = Guid.Empty;

            switch (node.Value)
            {
            case BaseNode.Keyword.Indexer:
                if (EmbeddingClass.ClassIndexer.IsAssigned)
                {
                    IIndexerFeature ClassIndexer = EmbeddingClass.ClassIndexer.Item;
                    resolvedFinalFeature = ClassIndexer;
                    EntityGuid           = ClassIndexer.EntityGuid;

                    expressionConstant = new EntityLanguageConstant(ClassIndexer);
                }
                else
                {
                    errorList.AddError(new ErrorMissingIndexer(node));
                    return(false);
                }
                break;

            default:
                errorList.AddError(new ErrorInvalidExpression(node));
                return(false);
            }

            Debug.Assert(EntityGuid != Guid.Empty);

            ITypeName     EntityTypeName = EmbeddingClass.ImportedLanguageTypeTable[EntityGuid].Item1;
            ICompiledType EntityType     = EmbeddingClass.ImportedLanguageTypeTable[EntityGuid].Item2;

            resolvedResult    = new ResultType(EntityTypeName, EntityType, string.Empty);
            resolvedException = new ResultException();

#if COVERAGE
            Debug.Assert(!node.IsComplex);
#endif

            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(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);
        }