private bool CompareEffectiveFlags(InheritedInstanceInfo importedInstance, IErrorList errorList, IClassType localClassType)
        {
            bool Result = true;

            importedInstance.IsKept         = importedInstance.EffectiveInstance.Item.Instance.IsKept;
            importedInstance.IsDiscontinued = importedInstance.EffectiveInstance.Item.Instance.IsDiscontinued;

            // If the effective instance is a redefine.
            if (importedInstance.EffectiveInstance.Item.Ancestor == localClassType && importedInstance.EffectiveInstance.Item.Instance.Feature.ResolvedAgentType.IsAssigned)
            {
                ICompiledType DescendantFeatureType = importedInstance.EffectiveInstance.Item.Instance.Feature.ResolvedAgentType.Item;

                IList <InstanceNameInfo> InstanceList = importedInstance.PrecursorInstanceList;
                foreach (InstanceNameInfo Item in InstanceList)
                {
                    if (Item == importedInstance.EffectiveInstance.Item)
                    {
                        continue;
                    }

                    ICompiledType AncestorFeatureType = Item.Instance.Feature.ResolvedAgentType.Item;

                    if (!ObjectType.TypeConformToBase(DescendantFeatureType, AncestorFeatureType, errorList, (ISource)importedInstance.EffectiveInstance.Item.Instance.Feature, isConversionAllowed: false))
                    {
                        errorList.AddError(new ErrorInheritanceConflict(Item.Location, Item.Name.Name));
                        Result = false;
                    }
                }
            }

            return(Result);
        }
        private bool IsSingleEffective(ISealableDictionary <IFeatureName, InheritedInstanceInfo> byNameTable, IErrorList errorList)
        {
            bool IsSingle = true;

            foreach (KeyValuePair <IFeatureName, InheritedInstanceInfo> ImportedEntry in byNameTable)
            {
                IFeatureName             ImportedKey      = ImportedEntry.Key;
                InheritedInstanceInfo    ImportedInstance = ImportedEntry.Value;
                IList <InstanceNameInfo> InstanceList     = ImportedInstance.PrecursorInstanceList;

                foreach (InstanceNameInfo Item in InstanceList)
                {
                    if (!Item.Instance.IsForgotten)
                    {
                        if (!ImportedInstance.EffectiveInstance.IsAssigned)
                        {
                            ImportedInstance.EffectiveInstance.Item = Item;
                        }
                        else
                        {
                            errorList.AddError(new ErrorMultipleEffectiveFeature(Item.Location, Item.Name.Name));
                            IsSingle = false;
                            break;
                        }
                    }
                }
            }

            return(IsSingle);
        }
        private bool CheckPrecursorSelected(ISealableDictionary <IFeatureName, InheritedInstanceInfo> byNameTable, ISealableDictionary <IFeatureName, IList <ICompiledFeature> > precursorSet, IErrorList errorList)
        {
            bool Success = true;
            bool IsKept  = false;

            foreach (KeyValuePair <IFeatureName, IList <ICompiledFeature> > SetMemberEntry in precursorSet)
            {
                IFeatureName          SetMemberKey          = SetMemberEntry.Key;
                InheritedInstanceInfo CorrespondingInstance = byNameTable[SetMemberKey];

                if (CorrespondingInstance.IsKept)
                {
                    if (IsKept)
                    {
                        foreach (InstanceNameInfo Item in CorrespondingInstance.PrecursorInstanceList)
                        {
                            if (Item.Instance.IsKept)
                            {
                                errorList.AddError(new ErrorInheritanceConflict(Item.Location, Item.Name.Name));
                                Success = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        IsKept = true;
                    }
                }
            }

            if (!IsKept && precursorSet.Count > 1)
            {
                foreach (KeyValuePair <IFeatureName, IList <ICompiledFeature> > SetMemberEntry in precursorSet)
                {
                    IFeatureName          SetMemberKey          = SetMemberEntry.Key;
                    InheritedInstanceInfo CorrespondingInstance = byNameTable[SetMemberKey];

                    foreach (InstanceNameInfo Item in CorrespondingInstance.PrecursorInstanceList)
                    {
                        errorList.AddError(new ErrorMissingSelectedPrecursor(Item.Location, Item.Name.Name));
                        Success = false;
                        break;
                    }

                    break;
                }

                Debug.Assert(!Success);
            }

            return(Success);
        }
        private void MergeInheritedFeatures(IClass item, ISealableDictionary <IFeatureName, InheritedInstanceInfo> byNameTable, out ISealableDictionary <IFeatureName, IFeatureInstance> mergedFeatureTable)
        {
            mergedFeatureTable = new SealableDictionary <IFeatureName, IFeatureInstance>();

            foreach (KeyValuePair <IFeatureName, InheritedInstanceInfo> ImportedEntry in byNameTable)
            {
                IFeatureName          ImportedKey      = ImportedEntry.Key;
                InheritedInstanceInfo ImportedInstance = ImportedEntry.Value;

                IFeatureInstance NewInstance = MergeCreateNewInstance(item, ImportedKey, ImportedInstance, out InstanceNameInfo SelectedInstanceInfo);

                StableReference <IPrecursorInstance> OriginalPrecursor = new StableReference <IPrecursorInstance>();
                IList <IPrecursorInstance>           PrecursorList     = new List <IPrecursorInstance>();
                foreach (InstanceNameInfo Item in ImportedInstance.PrecursorInstanceList)
                {
                    if (Item == SelectedInstanceInfo)
                    {
                        foreach (IPrecursorInstance PrecursorInstance in Item.Instance.PrecursorList)
                        {
                            PrecursorList.Add(PrecursorInstance);
                        }
                    }
                    else
                    {
                        IPrecursorInstance NewPrecursor = new PrecursorInstance(Item.Ancestor, Item.Instance);
                        PrecursorList.Add(NewPrecursor);
                    }

                    if (Item.Instance.OriginalPrecursor.IsAssigned)
                    {
                        OriginalPrecursor.Item = Item.Instance.OriginalPrecursor.Item;
                    }
                }

                if (OriginalPrecursor.IsAssigned)
                {
                    NewInstance.OriginalPrecursor.Item = OriginalPrecursor.Item;
                }
                else if (PrecursorList.Count > 0)
                {
                    NewInstance.OriginalPrecursor.Item = PrecursorList[0];
                }

                Debug.Assert(NewInstance.PrecursorList.Count == 0);
                foreach (IPrecursorInstance PrecursorInstance in PrecursorList)
                {
                    NewInstance.PrecursorList.Add(PrecursorInstance);
                }

                mergedFeatureTable.Add(ImportedKey, NewInstance);
            }
        }
        private void CheckIfFeatureNameListed(ISealableDictionary <IFeatureName, InheritedInstanceInfo> byNameTable, AncestorFeatureInfo featureInfo, IFeatureName featureName, IFeatureInstance featureInstance)
        {
            bool FeatureAlreadyListed = false;
            bool NameAlreadyListed    = false;

            foreach (KeyValuePair <IFeatureName, InheritedInstanceInfo> ImportedEntry in byNameTable)
            {
                IFeatureName             ImportedKey      = ImportedEntry.Key;
                InheritedInstanceInfo    ImportedInstance = ImportedEntry.Value;
                IList <InstanceNameInfo> InstanceList     = ImportedInstance.PrecursorInstanceList;

                if (featureName.Name == ImportedKey.Name)
                {
                    FeatureAlreadyListed = false;

                    Debug.Assert(featureInstance.Feature != null);

                    foreach (InstanceNameInfo Item in InstanceList)
                    {
                        Debug.Assert(Item.Instance.Feature != null);

                        if (featureInstance.Feature == Item.Instance.Feature)
                        {
                            FeatureAlreadyListed = true;
                            break;
                        }
                    }

                    if (!FeatureAlreadyListed)
                    {
                        InstanceNameInfo NewInfo = new InstanceNameInfo(featureInfo, featureInstance, featureName);
                        InstanceList.Add(NewInfo);
                    }

                    NameAlreadyListed = true;
                    break;
                }
            }
            if (!NameAlreadyListed)
            {
                IList <InstanceNameInfo> InitList = new List <InstanceNameInfo>();
                InstanceNameInfo         NewInfo  = new InstanceNameInfo(featureInfo, featureInstance, featureName);
                InitList.Add(NewInfo);

                InheritedInstanceInfo NewName = new InheritedInstanceInfo();
                NewName.PrecursorInstanceList = InitList;

                byNameTable.Add(featureName, NewName);
            }
        }
        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);
        }
        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);
                }
            }
        }
        private bool CompareNonEffectiveFlags(InheritedInstanceInfo importedInstance, IErrorList errorList)
        {
            bool Result = true;

            IList <InstanceNameInfo> InstanceList = importedInstance.PrecursorInstanceList;

            importedInstance.IsKept         = InstanceList[0].Instance.IsKept;
            importedInstance.IsDiscontinued = InstanceList[0].Instance.IsDiscontinued;

            if (InstanceList.Count > 1)
            {
                ICompiledType FeatureType = InstanceList[0].Instance.Feature.ResolvedAgentType.Item;

                for (int i = 1; i < InstanceList.Count && Result; i++)
                {
                    InstanceNameInfo ThisInstance = InstanceList[i];

                    Result &= importedInstance.IsKept == ThisInstance.Instance.IsKept;
                    Result &= importedInstance.IsDiscontinued == ThisInstance.Instance.IsDiscontinued;
                    Result &= ObjectType.TypesHaveIdenticalSignature(FeatureType, ThisInstance.Instance.Feature.ResolvedAgentType.Item);

                    if (!Result)
                    {
                        if (FeatureType is IIndexerType)
                        {
                            errorList.AddError(new ErrorIndexerInheritanceConflict(ThisInstance.Location));
                        }
                        else
                        {
                            errorList.AddError(new ErrorInheritanceConflict(ThisInstance.Location, ThisInstance.Name.Name));
                        }
                    }
                }
            }

            return(Result);
        }
        private bool CheckInheritanceConsistency(ISealableDictionary <ICompiledFeature, IList <InstanceNameInfo> > byFeatureTable, ISealableDictionary <IFeatureName, InheritedInstanceInfo> byNameTable, IClassType localClassType, IErrorList errorList)
        {
            if (!IsKeepDiscontinueConsistent(byFeatureTable, errorList))
            {
                return(false);
            }

            if (!IsSingleEffective(byNameTable, errorList))
            {
                return(false);
            }

            bool AllRedefineConformant = true;
            bool AllFlagsTheSame       = true;

            foreach (KeyValuePair <IFeatureName, InheritedInstanceInfo> ImportedEntry in byNameTable)
            {
                IFeatureName          ImportedKey      = ImportedEntry.Key;
                InheritedInstanceInfo ImportedInstance = ImportedEntry.Value;

                // If there is no effective instance for this name
                if (!ImportedInstance.EffectiveInstance.IsAssigned)
                {
                    AllFlagsTheSame &= CompareNonEffectiveFlags(ImportedInstance, errorList);
                }
                else
                {
                    AllRedefineConformant &= CompareEffectiveFlags(ImportedInstance, errorList, localClassType);
                }
            }
            if (!AllFlagsTheSame || !AllRedefineConformant)
            {
                return(false);
            }

            return(true);
        }
        private IFeatureInstance MergeCreateNewInstance(IClass item, IFeatureName importedKey, InheritedInstanceInfo importedInstance, out InstanceNameInfo selectedInstanceInfo)
        {
            IFeatureInstance NewInstance;

            if (importedInstance.EffectiveInstance.IsAssigned)
            {
                selectedInstanceInfo = importedInstance.EffectiveInstance.Item;
            }
            else
            {
                IList <InstanceNameInfo> InstancePrecursorList = importedInstance.PrecursorInstanceList;

                selectedInstanceInfo = null;
                foreach (InstanceNameInfo Item in InstancePrecursorList)
                {
                    if (Item.Instance.Owner == item)
                    {
                        selectedInstanceInfo = Item;
                        break;
                    }
                }

                if (selectedInstanceInfo == null)
                {
                    selectedInstanceInfo = InstancePrecursorList[0];
                }
            }

            NewInstance = new FeatureInstance(selectedInstanceInfo.Instance.Owner, selectedInstanceInfo.Instance.Feature, importedInstance.IsKept, importedInstance.IsDiscontinued);
            return(NewInstance);
        }