Example #1
0
        /// <summary>
        /// Checks if a node source is ready.
        /// </summary>
        /// <param name="node">The node for which the value is checked.</param>
        /// <param name="data">Optional data returned to the caller.</param>
        public override bool IsReady(TSource node, out object data)
        {
            data = null;
            bool Result = false;

            ISealableDictionary <TKey, TValue> Value = GetSourceObject(node, out bool IsInterrupted);

            if (!IsInterrupted && Value.IsSealed)
            {
                data   = Value;
                Result = true;
            }

            return(Result);
        }
Example #2
0
        /// <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(IOverLoopInstruction node, object data)
        {
            ISealableDictionary <string, IScopeAttributeFeature> CheckedScope = (ISealableDictionary <string, IScopeAttributeFeature>)data;

            node.InnerLoopScope.Merge(CheckedScope);
            node.InnerLoopScope.Seal();

            node.LocalScope.Seal();

            ScopeHolder.RecursiveAdd(CheckedScope, node.InnerScopes);

            IList <IScopeHolder> EmbeddingScopeList = ScopeHolder.EmbeddingScope(node);

            EmbeddingScopeList.Add(node);
        }
Example #3
0
        /// <summary>
        /// Resolves reference from libraries to classes and other libraries.
        /// </summary>
        /// <param name="libraryTable">The table of known libraries.</param>
        /// <param name="resolvedLibraryList">The list of libraries that have been resolved so far.</param>
        /// <param name="importChanged">Indicates that the import specifier has changed.</param>
        /// <param name="errorList">List of errors found.</param>
        /// <returns>True if the method succeeded.</returns>
        public virtual bool Resolve(ISealableDictionary <string, ISealableDictionary <string, ILibrary> > libraryTable, IList <ILibrary> resolvedLibraryList, ref bool importChanged, IErrorList errorList)
        {
            List <IImport> ToRemove = new List <IImport>();
            bool           Success  = true;

            foreach (IImport ImportItem in ImportList)
            {
                // Check the import and obtain the matching library.
                if (!ImportItem.CheckImportConsistency(libraryTable, out ILibrary MatchingLibrary, errorList))
                {
                    Success = false;
                    continue;
                }

                // You can't import the same library twice.
                if (ImportedLibraryList.Contains(MatchingLibrary))
                {
                    Success = false;
                    errorList.AddError(new ErrorDuplicateImport((IIdentifier)ImportItem.LibraryIdentifier, MatchingLibrary.ValidLibraryName, MatchingLibrary.ValidSourceName));
                    continue;
                }

                // If the imported library hasn't been resolved yet, ignore it for now.
                if (!resolvedLibraryList.Contains(MatchingLibrary))
                {
                    continue;
                }

                // The imported library was resolved, merge this import with it.
                if (!MergeImports(ImportedClassTable, ImportItem, MatchingLibrary, errorList))
                {
                    Success = false;
                    continue;
                }

                ImportedLibraryList.Add(MatchingLibrary);
                ToRemove.Add(ImportItem);
                importChanged = true;
            }

            foreach (IImport ImportItem in ToRemove)
            {
                ImportList.Remove(ImportItem);
            }

            Debug.Assert(Success || !errorList.IsEmpty);
            return(Success);
        }
Example #4
0
        /// <summary>
        /// Validates an import and return the matching library.
        /// </summary>
        /// <param name="libraryTable">Table of valid library names and their sources, updated upon return.</param>
        /// <param name="matchingLibrary">The matching library upon return.</param>
        /// <param name="errorList">List of errors found.</param>
        /// <returns>True if library names are valid.</returns>
        public virtual bool CheckImportConsistency(ISealableDictionary <string, ISealableDictionary <string, ILibrary> > libraryTable, out ILibrary matchingLibrary, IErrorList errorList)
        {
            IErrorStringValidity StringError;
            string      ValidFromIdentifier;
            IIdentifier ImportLibraryIdentifier = (IIdentifier)LibraryIdentifier;
            ISealableDictionary <string, ILibrary> SourceNameTable;

            matchingLibrary = null;

            if (!StringValidation.IsValidIdentifier(ImportLibraryIdentifier, LibraryIdentifier.Text, out string ValidLibraryIdentifier, out StringError))
            {
                errorList.AddError(StringError);
                return(false);
            }

            // Match the library name and source name.
            if (!libraryTable.ContainsKey(ValidLibraryIdentifier))
            {
                errorList.AddError(new ErrorUnknownIdentifier(ImportLibraryIdentifier, ValidLibraryIdentifier));
                return(false);
            }

            SourceNameTable = libraryTable[ValidLibraryIdentifier];

            if (FromIdentifier.IsAssigned)
            {
                IIdentifier ImportFromIdentifier = (IIdentifier)FromIdentifier.Item;

                if (!StringValidation.IsValidIdentifier(ImportFromIdentifier, FromIdentifier.Item.Text, out ValidFromIdentifier, out StringError))
                {
                    errorList.AddError(StringError);
                    return(false);
                }
            }
            else
            {
                ValidFromIdentifier = string.Empty;
            }

            if (!SourceNameTable.ContainsKey(ValidFromIdentifier))
            {
                errorList.AddError(new ErrorUnknownIdentifier(ImportLibraryIdentifier, ValidLibraryIdentifier));
                return(false);
            }

            matchingLibrary = SourceNameTable[ValidFromIdentifier];
            return(true);
        }
        /// <summary>
        /// Finds the matching nodes of a <see cref="IOldExpression"/>.
        /// </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(IOldExpression node, IErrorList errorList, out ResolvedExpression resolvedExpression)
        {
            resolvedExpression = new ResolvedExpression();

            IClass              EmbeddingClass = node.EmbeddingClass;
            IQualifiedName      Query          = (IQualifiedName)node.Query;
            IList <IIdentifier> ValidPath      = Query.ValidPath.Item;
            IClassType          BaseType       = EmbeddingClass.ResolvedClassType.Item;

            if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName BooleanTypeName, out ICompiledType BooleanType))
            {
                errorList.AddError(new ErrorBooleanTypeMissing(node));
                return(false);
            }

            ISealableDictionary <string, IScopeAttributeFeature> LocalScope = Scope.CurrentScope(node);

            Debug.Assert(LocalScope != null);

            if (node.EmbeddingBody == null && node.EmbeddingAssertion == null)
            {
                errorList.AddError(new ErrorInvalidOldExpression(node));
                return(false);
            }

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

            if (FinalFeature == null)
            {
                errorList.AddError(new ErrorInvalidOldExpression(node));
                return(false);
            }

            ObjectType.FillResultPath(EmbeddingClass, BaseType, LocalScope, ValidPath, 0, Query.ValidResultTypePath.Item);

            resolvedExpression.ResolvedFinalFeature = FinalFeature;
            resolvedExpression.ResolvedResult       = new ResultType(FinalTypeName, FinalType, string.Empty);
            resolvedExpression.ResolvedException    = new ResultException();

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

            return(true);
        }
        /// <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(IQueryOverload node, object data)
        {
            IClass   EmbeddingClass   = node.EmbeddingClass;
            IFeature EmbeddingFeature = node.EmbeddingFeature;

            ISealableDictionary <string, IScopeAttributeFeature> CheckedScope = (ISealableDictionary <string, IScopeAttributeFeature>)data;

            node.LocalScope.Merge(CheckedScope);
            node.LocalScope.Seal();
            node.FullScope.Merge(node.LocalScope);

            ScopeHolder.RecursiveAdd(node.FullScope, node.InnerScopes);

            EmbeddingClass.BodyList.Add((IBody)node.QueryBody);
            EmbeddingClass.QueryOverloadList.Add(node);
        }
Example #7
0
        /// <summary>
        /// Finds all single class attributes in conflict with others already defined in embedding scopes.
        /// </summary>
        /// <param name="scope">The scope where the check is performed.</param>
        /// <param name="innerScopeList">The list of inner scopes.</param>
        /// <param name="assignedSingleClassList">The list of assigned single class attributes.</param>
        /// <param name="source">The location where to report errors.</param>
        /// <param name="errorList">The list of errors found.</param>
        public static bool HasConflictingSingleAttributes(ISealableDictionary <string, IScopeAttributeFeature> scope, IList <IScopeHolder> innerScopeList, IList <IClass> assignedSingleClassList, ISource source, IErrorList errorList)
        {
            bool IsAssigned = false;

            foreach (KeyValuePair <string, IScopeAttributeFeature> ScopeNameItem in scope)
            {
                IsAssigned |= ScopeNameItem.Value.IsGroupAssigned(assignedSingleClassList, source, errorList);
            }

            foreach (IScopeHolder Item in innerScopeList)
            {
                IsAssigned |= HasConflictingSingleAttributes(scope, Item.InnerScopes, assignedSingleClassList, source, errorList);
            }

            return(IsAssigned);
        }
Example #8
0
        /// <summary>
        /// Checks if a path to a target type is made of resolved elements.
        /// </summary>
        /// <param name="path">The path to the target.</param>
        /// <param name="localEntityList">The list of available local variables.</param>
        /// <param name="localFeatureTable">The local feature table at the begining of the path.</param>
        /// <param name="featureTable">The feature table at the begining of the path.</param>
        /// <param name="errorList">The list of errors found.</param>
        /// <param name="resolvedPathTypeName">The target type name upon return.</param>
        /// <param name="resolvedPathType">The target type upon return.</param>
        /// <returns>True if the path could be resolved to the target.</returns>
        public static bool IsPathReady(IList <IIdentifier> path, List <IEntityDeclaration> localEntityList, ISealableDictionary <IFeatureName, IFeatureInstance> localFeatureTable, ISealableDictionary <IFeatureName, IFeatureInstance> featureTable, IErrorList errorList, out ITypeName resolvedPathTypeName, out ICompiledType resolvedPathType)
        {
            resolvedPathTypeName = null;
            resolvedPathType     = null;

            ISealableDictionary <IFeatureName, IFeatureInstance> FeatureTable;

            // We start with a feature table. The full table if available, the local table otherwise.

            /*
             * if (featureTable.IsSealed)
             *  FeatureTable = featureTable;
             * else if (localFeatureTable.IsSealed)
             *  FeatureTable = localFeatureTable;
             * else
             *  return false;
             */

            if (localFeatureTable.IsSealed)
            {
                FeatureTable = localFeatureTable;
            }
            else
            {
                return(false);
            }

            Debug.Assert(path.Count > 0);

            bool IsInterrupted = false;
            bool IsReady       = true;
            int  i             = 0;

            // If an error is found, the error will be processed in CheckConsistency.
            for (; i + 1 < path.Count && !IsInterrupted && IsReady; i++)
            {
                IsReady &= IsPathItemReady(path[i], path[i + 1], ref localEntityList, ref FeatureTable, errorList, ref IsInterrupted);
            }

            // This loop executes once if IsReady is true, and doesn't otherwise.
            for (; i < path.Count && !IsInterrupted && IsReady; i++)
            {
                IsReady &= IsLastPathItemReady(path[i], localEntityList, FeatureTable, errorList, ref IsInterrupted, out resolvedPathTypeName, out resolvedPathType);
            }

            return(IsReady || IsInterrupted);
        }
Example #9
0
        /// <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(IInheritance node, IDictionary <ISourceTemplate, object> dataList, out object data)
        {
            bool Success = true;

            IClass      EmbeddingClass  = node.EmbeddingClass;
            IIdentifier ClassIdentifier = null;
            IClass      BaseClass       = null;

            if (node.ParentType is ISimpleType AsSimpleType)
            {
                ClassIdentifier = (IIdentifier)AsSimpleType.ClassIdentifier;
            }
            else if (node.ParentType is IGenericType AsGenericType)
            {
                ClassIdentifier = (IIdentifier)AsGenericType.ClassIdentifier;
            }

            if (ClassIdentifier != null)
            {
                Debug.Assert(ClassIdentifier.ValidText.IsAssigned);
                string ValidIdentifier = ClassIdentifier.ValidText.Item;

                ISealableDictionary <string, IImportedClass> ImportedClassTable = EmbeddingClass.ImportedClassTable;

                if (ValidIdentifier.ToUpperInvariant() == LanguageClasses.Any.Name.ToUpperInvariant())
                {
                    BaseClass = Class.ClassAny;
                }
                else if (ValidIdentifier.ToUpperInvariant() == LanguageClasses.AnyReference.Name.ToUpperInvariant())
                {
                    BaseClass = Class.ClassAnyReference;
                }
                else if (ValidIdentifier.ToUpperInvariant() == LanguageClasses.AnyValue.Name.ToUpperInvariant())
                {
                    BaseClass = Class.ClassAnyValue;
                }
                else if (ImportedClassTable.ContainsKey(ValidIdentifier))
                {
                    IImportedClass Imported = ImportedClassTable[ValidIdentifier];
                    BaseClass = Imported.Item;
                }
            }

            data = BaseClass;

            return(Success);
        }
        private bool HasConflictingEntry(IClass node, ISealableDictionary <IFeatureName, ISealableDictionary <string, IClass> > mergedExportTable)
        {
            bool Result = false;

            foreach (IInheritance Inheritance in node.InheritanceList)
            {
                Debug.Assert(Inheritance.ExportTable.IsAssigned);

                ISealableDictionary <IFeatureName, ISealableDictionary <string, IClass> > InheritedExportTable = Inheritance.ExportTable.Item;

                foreach (KeyValuePair <IFeatureName, ISealableDictionary <string, IClass> > InstanceEntry in InheritedExportTable)
                {
                    IFeatureName InstanceName = InstanceEntry.Key;
                    ISealableDictionary <string, IClass> InstanceItem = InstanceEntry.Value;
                    bool ConflictingEntry = false;

                    foreach (KeyValuePair <IFeatureName, ISealableDictionary <string, IClass> > Entry in mergedExportTable)
                    {
                        IFeatureName LocalName = Entry.Key;
                        ISealableDictionary <string, IClass> LocalItem = Entry.Value;

                        if (InstanceName.Name == LocalName.Name)
                        {
                            if (InstanceItem != LocalItem)
                            {
                                AddSourceError(new ErrorDuplicateName(Inheritance, LocalName.Name));
                                ConflictingEntry = true;
                                Result           = true;
                            }
                        }
                        else if (InstanceItem == LocalItem)
                        {
                            AddSourceError(new ErrorExportNameConflict(Inheritance, LocalName.Name, InstanceName.Name));
                            ConflictingEntry = true;
                            Result           = true;
                        }
                    }

                    if (!ConflictingEntry && !mergedExportTable.ContainsKey(InstanceName))
                    {
                        mergedExportTable.Add(InstanceName, InstanceItem);
                    }
                }
            }

            return(Result);
        }
Example #11
0
        /// <summary>
        /// Checks if a node source is ready.
        /// </summary>
        /// <param name="node">The node for which the value is checked.</param>
        /// <param name="data">Optional data returned to the caller.</param>
        public override bool IsReady(TSource node, out object data)
        {
            data = null;
            bool Result = false;

            OnceReference <IList <IIdentifier> > Value = GetSourceObject(node, out bool IsInterrupted);

            if (!IsInterrupted && Value.IsAssigned)
            {
                IList <IIdentifier> Path = Value.Item;
                foreach (IIdentifier Identifier in Path)
                {
                    Debug.Assert(Identifier.ValidText.IsAssigned);
                }

                List <IEntityDeclaration> LocalEntityList = new List <IEntityDeclaration>();

                if (node.EmbeddingOverload is ICommandOverload AsCommandOverload)
                {
                    LocalEntityList.AddRange(AsCommandOverload.ParameterList);
                }
                else if (node.EmbeddingOverload is IQueryOverload AsQueryOverload)
                {
                    LocalEntityList.AddRange(AsQueryOverload.ParameterList);
                    LocalEntityList.AddRange(AsQueryOverload.ResultList);
                }

                if (node.EmbeddingBody is IEffectiveBody AsEffectiveBody)
                {
                    LocalEntityList.AddRange(AsEffectiveBody.EntityDeclarationList);
                }

                IClass Class = node.EmbeddingClass;
                ISealableDictionary <IFeatureName, IFeatureInstance> LocalFeatureTable = Class.LocalFeatureTable;
                ISealableDictionary <IFeatureName, IFeatureInstance> FeatureTable      = Class.FeatureTable;

                IErrorList ErrorList = new ErrorList();
                if (IsPathReady(Path, LocalEntityList, LocalFeatureTable, FeatureTable, ErrorList, out ITypeName ResolvedPathTypeName, out ICompiledType ResolvedPathType))
                {
                    data   = new Tuple <IErrorList, ITypeName, ICompiledType>(ErrorList, ResolvedPathTypeName, ResolvedPathType);
                    Result = true;
                }
            }

            return(Result);
        }
        /// <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(IClass node, object data)
        {
            ISealableDictionary <IFeatureName, IFeatureInstance> MergedFeatureTable = (ISealableDictionary <IFeatureName, IFeatureInstance>)data;
            IClassType ThisClassType = node.ResolvedClassType.Item;

            ThisClassType.FeatureTable.Merge(MergedFeatureTable);
            ThisClassType.FeatureTable.Seal();

            node.FeatureTable.Merge(MergedFeatureTable);
            node.FeatureTable.Seal();

            foreach (ICompiledType Item in node.GenericInstanceList)
            {
                Item.FeatureTable.Merge(MergedFeatureTable);
                Item.FeatureTable.Seal();
            }
        }
        private bool CheckPrecursorBodiesHaveAncestor(ISealableDictionary <IFeatureName, InheritedInstanceInfo> byNameTable, IErrorList errorList)
        {
            foreach (KeyValuePair <IFeatureName, InheritedInstanceInfo> ImportedEntry in byNameTable)
            {
                IFeatureName          ImportedKey      = ImportedEntry.Key;
                InheritedInstanceInfo ImportedInstance = ImportedEntry.Value;
                if (ImportedInstance.EffectiveInstance.IsAssigned)
                {
                    InstanceNameInfo Item             = ImportedInstance.EffectiveInstance.Item;
                    ICompiledFeature EffectiveFeature = Item.Instance.Feature;

                    if (EffectiveFeature.HasPrecursorBody)
                    {
                        bool HasEffectiveAncestor = false;

                        foreach (InstanceNameInfo AncestorItem in ImportedInstance.PrecursorInstanceList)
                        {
                            if (AncestorItem == Item)
                            {
                                continue;
                            }

                            ICompiledFeature AncestorEffectiveFeature = AncestorItem.Instance.Feature;
                            if (AncestorEffectiveFeature.IsDeferredFeature)
                            {
                                continue;
                            }

                            HasEffectiveAncestor = true;
                        }

                        if (!HasEffectiveAncestor)
                        {
                            IFeature AsFeature = EffectiveFeature as IFeature;
                            Debug.Assert(AsFeature != null);

                            errorList.AddError(new ErrorMissingAncestor(AsFeature, Item.Name.Name));
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
Example #14
0
        /// <summary>
        /// Checks if a matching function and overload exists in a type table.
        /// </summary>
        /// <param name="typeTable">The table of existing types.</param>
        /// <param name="overload">The overload to check.</param>
        /// <param name="overloadList">The list of other overloads in the candidate function type.</param>
        public static bool IsQueryOverloadMatching(ISealableDictionary <ITypeName, ICompiledType> typeTable, IQueryOverloadType overload, IList <IQueryOverloadType> overloadList)
        {
            bool IsMatching = false;

            for (int i = 0; i < overloadList.Count && !IsMatching; i++)
            {
                IQueryOverloadType Item = overloadList[i];

                IsMatching  = true;
                IsMatching &= IsParametersMatching(overload, Item);
                IsMatching &= IsResultsMatching(overload, Item);
                IsMatching &= Assertion.IsAssertionListEqual(overload.RequireList, Item.RequireList);
                IsMatching &= Assertion.IsAssertionListEqual(overload.EnsureList, Item.EnsureList);
                IsMatching &= ExceptionHandler.IdenticalExceptionSignature(overload.ExceptionIdentifierList, Item.ExceptionIdentifierList);
            }

            return(IsMatching);
        }
Example #15
0
        /// <summary>
        /// Finds all names that in conflict with others already defined in embedding scopes.
        /// </summary>
        /// <param name="source">The scope where the check is performed.</param>
        /// <param name="innerScopeList">The list of inner scopes.</param>
        /// <param name="conflictList">The list of conflicting names.</param>
        public static void RecursiveCheck(ISealableDictionary <string, IScopeAttributeFeature> source, IList <IScopeHolder> innerScopeList, IList <string> conflictList)
        {
            foreach (IScopeHolder Item in innerScopeList)
            {
                foreach (KeyValuePair <string, IScopeAttributeFeature> ScopeNameItem in source)
                {
                    if (Item.FullScope.ContainsKey(ScopeNameItem.Key))
                    {
                        if (!conflictList.Contains(ScopeNameItem.Key))
                        {
                            conflictList.Add(ScopeNameItem.Key);
                        }
                    }
                }

                RecursiveCheck(source, Item.InnerScopes, conflictList);
            }
        }
        /// <summary>
        /// Finds the matching nodes of a <see cref="INewExpression"/>.
        /// </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 matching feature upon return.</param>
        public static bool ResolveCompilerReferences(INewExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant, out ICompiledFeature resolvedFinalFeature)
        {
            resolvedResult       = null;
            resolvedException    = null;
            constantSourceList   = new SealableList <IExpression>();
            expressionConstant   = NeutralLanguageConstant.NotConstant;
            resolvedFinalFeature = null;

            IClass              EmbeddingClass = node.EmbeddingClass;
            IQualifiedName      Object         = (IQualifiedName)node.Object;
            IList <IIdentifier> ValidPath      = Object.ValidPath.Item;
            IClassType          BaseType       = EmbeddingClass.ResolvedClassType.Item;

            if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName BooleanTypeName, out ICompiledType BooleanType))
            {
                errorList.AddError(new ErrorBooleanTypeMissing(node));
                return(false);
            }

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

            if (FinalFeature == null)
            {
                errorList.AddError(new ErrorConstantNewExpression(node));
                return(false);
            }

            ObjectType.FillResultPath(EmbeddingClass, BaseType, LocalScope, ValidPath, 0, Object.ValidResultTypePath.Item);

            resolvedResult       = new ResultType(BooleanTypeName, BooleanType, string.Empty);
            resolvedException    = new ResultException();
            resolvedFinalFeature = FinalFeature;

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

            return(true);
        }
Example #17
0
        /// <summary>
        /// Checks if a table of feature names contains a name, and if so returns the corresponding <see cref="IFeatureName"/> and associated value.
        /// </summary>
        /// <typeparam name="TValue">The type of the value associated to feature names in the table.</typeparam>
        /// <param name="table">The table.</param>
        /// <param name="name">The name to check.</param>
        /// <param name="key">The feature name found upon return.</param>
        /// <param name="value">The associated value.</param>
        public static bool TableContain <TValue>(ISealableDictionary <IFeatureName, TValue> table, string name, out IFeatureName key, out TValue value)
        {
            key   = null;
            value = default;
            bool Result = false;

            foreach (KeyValuePair <IFeatureName, TValue> Entry in table)
            {
                if (Entry.Key.Name == name)
                {
                    key    = Entry.Key;
                    value  = Entry.Value;
                    Result = true;
                    break;
                }
            }

            return(Result);
        }
        private bool ResolveIdentifierList(IList <IIdentifier> identifierList, out ISealableDictionary <string, IIdentifier> resultTable)
        {
            resultTable = new SealableDictionary <string, IIdentifier>();

            foreach (IIdentifier IdentifierItem in identifierList)
            {
                string ValidText = IdentifierItem.ValidText.Item;

                if (resultTable.ContainsKey(ValidText))
                {
                    AddSourceError(new ErrorIdentifierAlreadyListed(IdentifierItem, ValidText));
                    return(false);
                }

                resultTable.Add(ValidText, IdentifierItem);
            }

            return(true);
        }
        /// <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(IClass node, object data)
        {
            ISealableDictionary <IFeatureName, ITypedefType> MergedTypedefTable = (ISealableDictionary <IFeatureName, ITypedefType>)data;

            Debug.Assert(node.ResolvedClassType.IsAssigned);
            IClassType ThisClassType = node.ResolvedClassType.Item;

            ThisClassType.TypedefTable.Merge(MergedTypedefTable);
            ThisClassType.TypedefTable.Seal();

            node.TypedefTable.Merge(MergedTypedefTable);
            node.TypedefTable.Seal();

            foreach (IClassType Item in node.GenericInstanceList)
            {
                Item.TypedefTable.Merge(MergedTypedefTable);
                Item.TypedefTable.Seal();
            }
        }
        private void CheckAllPrecursorSelectedInNameTable(ISealableDictionary <IFeatureName, InheritedInstanceInfo> byNameTable, IList <ISealableDictionary <IFeatureName, IList <ICompiledFeature> > > precursorSetList)
        {
            foreach (KeyValuePair <IFeatureName, InheritedInstanceInfo> Entry in byNameTable)
            {
                IFeatureName          Key   = Entry.Key;
                InheritedInstanceInfo Value = Entry.Value;

                IList <ICompiledFeature> PrecursorList = new List <ICompiledFeature>();
                foreach (InstanceNameInfo PrecursorItem in Value.PrecursorInstanceList)
                {
                    FillPrecursorList(PrecursorList, PrecursorItem.Instance);
                }

                bool FoundInSet = false;
                foreach (ISealableDictionary <IFeatureName, IList <ICompiledFeature> > PrecursorSet in precursorSetList)
                {
                    foreach (KeyValuePair <IFeatureName, IList <ICompiledFeature> > SetMemberEntry in PrecursorSet)
                    {
                        IFeatureName             SetMemberKey           = SetMemberEntry.Key;
                        IList <ICompiledFeature> SetMemberPrecursorList = SetMemberEntry.Value;

                        if (PrecursorListIntersect(PrecursorList, SetMemberPrecursorList))
                        {
                            PrecursorSet.Add(Key, PrecursorList);
                            FoundInSet = true;
                            break;
                        }
                    }
                    if (FoundInSet)
                    {
                        break;
                    }
                }

                if (!FoundInSet)
                {
                    ISealableDictionary <IFeatureName, IList <ICompiledFeature> > NewSet = new SealableDictionary <IFeatureName, IList <ICompiledFeature> >();
                    NewSet.Add(Key, PrecursorList);
                    precursorSetList.Add(NewSet);
                }
            }
        }
        /// <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(IClass node, IDictionary <ISourceTemplate, object> dataList, out object data)
        {
            bool Success = true;

            data = null;

            ISealableDictionary <IFeatureName, IFeatureInstance> MergedFeatureTable = null;

            IList <AncestorFeatureInfo> FeatureTableList = new List <AncestorFeatureInfo>();

            ListLocalAndInheritedFeatures(node, FeatureTableList);

            ISealableDictionary <ICompiledFeature, IList <InstanceNameInfo> > ByFeatureTable; // ICompiledFeature -> List of InstanceNameInfo
            ISealableDictionary <IFeatureName, InheritedInstanceInfo>         ByNameTable;    // FeatureName -> InheritedInstanceInfo

            SortByFeatureAndByName(FeatureTableList, out ByFeatureTable, out ByNameTable);

            if (!CheckInheritanceConsistency(ByFeatureTable, ByNameTable, node.ResolvedClassType.Item, ErrorList))
            {
                Success = false;
            }
            else if (!CheckAllPrecursorSelected(ByNameTable, ErrorList))
            {
                Success = false;
            }
            else if (!CheckPrecursorBodiesHaveAncestor(ByNameTable, ErrorList))
            {
                Success = false;
            }
            else
            {
                MergeInheritedFeatures(node, ByNameTable, out MergedFeatureTable);
                ClassType.MergeConformingParentTypes(node, node.ResolvedClassType.Item);
            }

            if (Success)
            {
                data = MergedFeatureTable;
            }

            return(Success);
        }
Example #22
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);
        }
Example #23
0
        /// <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)
        {
            IList <ISealableDictionary <string, IScopeAttributeFeature> > CheckedScopeList = (IList <ISealableDictionary <string, IScopeAttributeFeature> >)data;

            Debug.Assert(CheckedScopeList.Count == node.AttachmentList.Count);

            node.LocalScope.Seal();

            for (int i = 0; i < node.AttachmentList.Count; i++)
            {
                IAttachment AttachmentItem = node.AttachmentList[i];
                ISealableDictionary <string, IScopeAttributeFeature> CheckedScope = CheckedScopeList[i];
                AttachmentItem.FullScope.Merge(CheckedScope);
                ScopeHolder.RecursiveAdd(CheckedScope, AttachmentItem.InnerScopes);
            }

            IList <IScopeHolder> EmbeddingScopeList = ScopeHolder.EmbeddingScope(node);

            EmbeddingScopeList.Add(node);
        }
        /// <summary>
        /// Creates an instance of a class type, or reuse an existing instance.
        /// </summary>
        /// <param name="instancingClassType">The class type to instanciate.</param>
        /// <param name="resolvedTypeName">The proposed type instance name.</param>
        /// <param name="resolvedType">The proposed type instance.</param>
        public void InstanciateType(ICompiledTypeWithFeature instancingClassType, ref ITypeName resolvedTypeName, ref ICompiledType resolvedType)
        {
            ISealableDictionary <ITypeName, ICompiledType> TypeTable = GetTypeTable();

            Debug.Assert(TypeTable.Count == 0);

            if (instancingClassType is IClassType AsClassType)
            {
                ISealableDictionary <string, ICompiledType> TypeArgumentTable = AsClassType.TypeArgumentTable;

                foreach (KeyValuePair <string, ICompiledType> TypeArgument in TypeArgumentTable)
                {
                    if (TypeArgument.Key == TypeFriendlyName)
                    {
                        resolvedType = TypeArgument.Value;
                        break;
                    }
                }
            }
        }
        /// <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(IClass node, object data)
        {
            ISealableDictionary <IDiscrete, string> AssignedDiscreteTable = node.AssignedDiscreteTable;

            Debug.Assert(AssignedDiscreteTable.Count == 0);

            foreach (IInheritance Inheritance in node.InheritanceList)
            {
                AssignedDiscreteTable.Merge(Inheritance.AssignedDiscreteTable);
            }

            foreach (IDiscrete Discrete in node.DiscreteList)
            {
                if (!Discrete.NumericValue.IsAssigned)
                {
                    AssignedDiscreteTable.Add(Discrete, Guid.NewGuid().ToString());
                }
            }

            AssignedDiscreteTable.Seal();
        }
        /// <summary>
        /// Gets the object a path is refering to.
        /// </summary>
        /// <param name="baseClass">The class where the path is used.</param>
        /// <param name="baseType">The type at the start of the path.</param>
        /// <param name="localScope">The local scope.</param>
        /// <param name="validPath">The path.</param>
        /// <param name="index">Index of the current identifier in the path.</param>
        /// <param name="errorList">The list of errors found.</param>
        /// <param name="finalFeature">The feature at the end of the path, if any, upon return.</param>
        /// <param name="finalDiscrete">The discrete at the end of the path, if any, upon return.</param>
        /// <param name="finalTypeName">The type name of the result.</param>
        /// <param name="finalType">The type of the result.</param>
        /// <param name="inheritBySideAttribute">Inherited from an effective body.</param>
        public static bool GetQualifiedPathFinalType(IClass baseClass, ICompiledType baseType, ISealableDictionary <string, IScopeAttributeFeature> localScope, IList <IIdentifier> validPath, int index, IErrorList errorList, out ICompiledFeature finalFeature, out IDiscrete finalDiscrete, out ITypeName finalTypeName, out ICompiledType finalType, out bool inheritBySideAttribute)
        {
            finalFeature           = null;
            finalDiscrete          = null;
            finalTypeName          = null;
            finalType              = null;
            inheritBySideAttribute = false;

            ISealableDictionary <IFeatureName, IFeatureInstance> FeatureTable = baseType.FeatureTable;

            IIdentifier ValidIdentifier = validPath[index];
            string      ValidText       = ValidIdentifier.ValidText.Item;

            if (index == 0 && localScope.ContainsKey(ValidText))
            {
                return(GetQualifiedPathFinalTypeFromLocal(baseClass, baseType, localScope, validPath, index, errorList, out finalFeature, out finalDiscrete, out finalTypeName, out finalType, out inheritBySideAttribute));
            }
            else if (FeatureName.TableContain(FeatureTable, ValidText, out IFeatureName Key, out IFeatureInstance Instance))
            {
                return(GetQualifiedPathFinalTypeAsFeature(baseClass, baseType, localScope, validPath, index, errorList, Instance, out finalFeature, out finalDiscrete, out finalTypeName, out finalType, out inheritBySideAttribute));
            }
        /// <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(IClass node, IDictionary <ISourceTemplate, object> dataList, out object data)
        {
            bool Success = true;

            data = null;

            IList <IIdentifier> ConversionList = node.ConversionList;
            ISealableDictionary <IFeatureName, IFeatureInstance> FeatureTable        = node.FeatureTable;
            ISealableDictionary <IFeatureName, ICreationFeature> ConversionFromTable = new SealableDictionary <IFeatureName, ICreationFeature>();
            ISealableDictionary <IFeatureName, IFunctionFeature> ConversionToTable   = new SealableDictionary <IFeatureName, IFunctionFeature>();

            foreach (IIdentifier Identifier in ConversionList)
            {
                Debug.Assert(Identifier.ValidText.IsAssigned);
                string ValidText = Identifier.ValidText.Item;

                if (!FeatureName.TableContain(FeatureTable, ValidText, out IFeatureName Key, out IFeatureInstance Instance))
                {
                    AddSourceError(new ErrorUnknownIdentifier(Identifier, ValidText));
                    Success = false;
                }
Example #28
0
        /// <summary>
        /// Checks if a matching class type exists in a type table.
        /// </summary>
        /// <param name="typeTable">The table of existing types.</param>
        /// <param name="baseClass">The class this is from.</param>
        /// <param name="typeArgumentTable">The generic arguments used when creating the class type.</param>
        /// <param name="resolvedTypeName">The type name upon return.</param>
        /// <param name="resolvedType">The type upon return.</param>
        public static bool TypeTableContaining(ISealableDictionary <ITypeName, ICompiledType> typeTable, IClass baseClass, ISealableDictionary <string, ICompiledType> typeArgumentTable, out ITypeName resolvedTypeName, out ICompiledType resolvedType)
        {
            resolvedTypeName = null;
            resolvedType     = null;
            bool Result = false;

            foreach (KeyValuePair <ITypeName, ICompiledType> Entry in typeTable)
            {
                if (Entry.Value is IClassType AsClassType)
                {
                    if (AsClassType.BaseClass == baseClass)
                    {
                        ISealableDictionary <string, ICompiledType> ResolvedTypeArgumentTable = AsClassType.TypeArgumentTable;
                        bool AllArgumentsEqual = true;

                        foreach (KeyValuePair <string, ICompiledType> TypeArgumentEntry in typeArgumentTable)
                        {
                            string        GenericName  = TypeArgumentEntry.Key;
                            ICompiledType TypeArgument = TypeArgumentEntry.Value;

                            Debug.Assert(ResolvedTypeArgumentTable.ContainsKey(GenericName));
                            ICompiledType ResolvedTypeArgument = ResolvedTypeArgumentTable[GenericName];

                            AllArgumentsEqual &= TypeArgument == ResolvedTypeArgument;
                        }

                        if (AllArgumentsEqual)
                        {
                            Debug.Assert(!Result);

                            resolvedTypeName = Entry.Key;
                            resolvedType     = AsClassType;
                            Result           = true;
                        }
                    }
                }
            }

            return(Result);
        }
Example #29
0
        /// <summary>
        /// Creates a class type with resolved arguments.
        /// </summary>
        /// <param name="baseClass">The class this is from.</param>
        /// <param name="typeArgumentTable">The generic arguments used when creating the class type.</param>
        /// <param name="instancingClassType">The class type to instanciate.</param>
        /// <param name="resolvedTypeName">The type name upon return.</param>
        /// <param name="resolvedType">The type upon return.</param>
        public static void BuildType(IClass baseClass, ISealableDictionary <string, ICompiledType> typeArgumentTable, ICompiledTypeWithFeature instancingClassType, out ITypeName resolvedTypeName, out ICompiledType resolvedType)
        {
            resolvedTypeName = null;
            resolvedType     = null;

            IClassType ResolvedClassType = Create(baseClass, typeArgumentTable, instancingClassType);

#if COVERAGE
            string TypeString = ResolvedClassType.ToString();
#endif

            resolvedTypeName = new TypeName(ResolvedClassType.TypeFriendlyName);
            resolvedType     = ResolvedClassType;

            if (baseClass.DiscreteTable.IsSealed)
            {
                ResolvedClassType.DiscreteTable.Merge(baseClass.DiscreteTable);
                ResolvedClassType.DiscreteTable.Seal();
            }

            if (baseClass.ExportTable.IsSealed)
            {
                ResolvedClassType.ExportTable.Merge(baseClass.ExportTable);
                ResolvedClassType.ExportTable.Seal();
            }

            if (baseClass.FeatureTable.IsSealed)
            {
                ResolvedClassType.FeatureTable.Merge(baseClass.FeatureTable);
                ResolvedClassType.FeatureTable.Seal();
            }

            if (baseClass.TypedefTable.IsSealed)
            {
                ResolvedClassType.TypedefTable.Merge(baseClass.TypedefTable);
                ResolvedClassType.TypedefTable.Seal();
            }

            baseClass.GenericInstanceList.Add(ResolvedClassType);
        }
Example #30
0
        /*
         * Two precursor index expressions cannot be compared because it happens only when comparing different features, and there can be only one indexer.
         * public static bool IsExpressionEqual(IPrecursorIndexExpression expression1, IPrecursorIndexExpression expression2)
         * {
         *  bool Result = true;
         *
         *  if (expression1.AncestorType.IsAssigned && expression2.AncestorType.IsAssigned)
         *  {
         *      IObjectType AncestorType1 = (IObjectType)expression1.AncestorType;
         *      IObjectType AncestorType2 = (IObjectType)expression2.AncestorType;
         *
         *      Debug.Assert(AncestorType1.ResolvedType.IsAssigned);
         *      Debug.Assert(AncestorType2.ResolvedType.IsAssigned);
         *
         *      Result &= AncestorType1.ResolvedType.Item == AncestorType2.ResolvedType.Item;
         *  }
         *
         *  Result &= expression1.AncestorType.IsAssigned == expression2.AncestorType.IsAssigned;
         *  Result &= Argument.IsArgumentListEqual(expression1.ArgumentList, expression2.ArgumentList);
         *
         *  return Result;
         * }
         */

        /// <summary>
        /// Finds the matching nodes of a <see cref="IPrecursorIndexExpression"/>.
        /// </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(IPrecursorIndexExpression node, IErrorList errorList, out ResolvedExpression resolvedExpression)
        {
            resolvedExpression = new ResolvedExpression();

            IOptionalReference <BaseNode.IObjectType> AncestorType = node.AncestorType;
            IList <IArgument> ArgumentList   = node.ArgumentList;
            IClass            EmbeddingClass = node.EmbeddingClass;

            ISealableDictionary <string, IImportedClass>         ClassTable   = EmbeddingClass.ImportedClassTable;
            ISealableDictionary <IFeatureName, IFeatureInstance> FeatureTable = EmbeddingClass.FeatureTable;
            IFeature InnerFeature = node.EmbeddingFeature;

            if (InnerFeature is IIndexerFeature AsIndexerFeature)
            {
                IFeatureInstance Instance = FeatureTable[FeatureName.IndexerFeatureName];

                if (!Instance.FindPrecursor(node.AncestorType, errorList, node, out IFeatureInstance SelectedPrecursor))
                {
                    return(false);
                }

                resolvedExpression.SelectedPrecursor = SelectedPrecursor;

                if (!ResolveSelectedPrecursor(node, SelectedPrecursor, errorList, ref resolvedExpression))
                {
                    return(false);
                }
            }
            else
            {
                errorList.AddError(new ErrorIndexPrecursorNotAllowedOutsideIndexer(node));
                return(false);
            }

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

            return(true);
        }