/// <summary>
        ///
        /// </summary>
        /// <param name="cls">The class</param>
        /// <param name="classBehavior">True for class behavior, false for instance.</param>
        /// <param name="directProtocols">Directly defined by the class.</param>
        /// <param name="inheritedProtocols">Indirectly defined by the class, because the direct protocols inherit from those.</param>
        /// <param name="implementedProtocols">Protocols implemented by the class or the class' superclasses.</param>
        /// <returns></returns>
        private void GetClassProtocols(Definitions.Implementation.Class cls, bool classBehavior,
                                       out IEnumerable <string> directProtocols, out HashSet <string> inheritedProtocols, out HashSet <string> implementedProtocols)
        {
            directProtocols      = (classBehavior ? cls.ImplementedClassProtocols : cls.ImplementedInstanceProtocols);
            inheritedProtocols   = new HashSet <string>();
            implementedProtocols = new HashSet <string>();

            foreach (string protocolName in directProtocols)
            {
                var protocol = this.SmalltalkSystem.SystemDescription.Protocols.FirstOrDefault(p => p.Name == protocolName);
                if (protocol != null)
                {
                    foreach (var p in protocol.AllConformsTo())
                    {
                        inheritedProtocols.Add(p);
                    }
                }
            }

            foreach (var c in cls.WithAllSuperclasses())
            {
                foreach (var p in (classBehavior ? c.ImplementedClassProtocols : c.ImplementedInstanceProtocols))
                {
                    implementedProtocols.Add(p);
                }
            }
        }
 private bool HasDuplicateClassNativeName(Definitions.Implementation.Class cls, Definitions.Implementation.Method mth, string nativeName)
 {
     if (this.HasDuplicates(cls, mth, nativeName, c => c.ClassMethods))
     {
         return(true);
     }
     return(this.HasDuplicateInstanceNativeName(mth.Parent.Parent.Classes.FirstOrDefault(c => c.Name == "Class"), mth, nativeName));
 }
        private bool IsDynamicMetaObject(Definitions.Implementation.Class cls)
        {
            string name = cls.Annotations.GetFirst("ist.runtime.native-class");

            if (String.IsNullOrWhiteSpace(name))
            {
                return(false);
            }
            Type type = IronSmalltalk.Runtime.Internal.NativeTypeClassMap.GetType(name);

            if (type == null)
            {
                return(false);
            }
            return(type.GetInterfaces().Contains(typeof(System.Dynamic.IDynamicMetaObjectProvider)));
        }
 private bool HasDuplicates(Definitions.Implementation.Class cls, Definitions.Implementation.Method mth, string nativeName,
                            Func <Definitions.Implementation.Class, ISet <Definitions.Implementation.Method> > getMethods)
 {
     while (cls != null)
     {
         foreach (var m in getMethods(cls))
         {
             if (m.Selector != mth.Selector)
             {
                 string native = m.Annotations.GetFirst("ist.runtime.native-name");
                 if (native == nativeName)
                 {
                     if (this.NumberOfParameters(m.Selector) == this.NumberOfParameters(mth.Selector))
                     {
                         return(true);
                     }
                 }
             }
         }
         cls = cls.Parent.Classes.FirstOrDefault(c => c.Name == cls.SuperclassName);
     }
     return(false);
 }
 private bool HasDuplicateInstanceNativeName(Definitions.Implementation.Class cls, Definitions.Implementation.Method mth, string nativeName)
 {
     return(this.HasDuplicates(cls, mth, nativeName, c => c.InstanceMethods));
 }
        private List <string> BuildImplementsResult(Definitions.Implementation.Class cls, HashSet <string> missing, bool classBehavior)
        {
            List <string> result = new List <string>();

            IEnumerable <string> directProtocols;
            HashSet <string>     inheritedProtocols;
            HashSet <string>     implementedProtocols;

            this.GetClassProtocols(cls, classBehavior, out directProtocols, out inheritedProtocols, out implementedProtocols);

            // Class behavior also implements the instance behavior of the Class (and Object) class.
            HashSet <string> indirectImplementedProtocols = new HashSet <string>();

            if (classBehavior)
            {
                Definitions.Implementation.Class c = cls.Parent.Classes.FirstOrDefault(e => e.Name == "Class");
                if (c == null)
                {
                    c = cls.Parent.Classes.FirstOrDefault(e => e.Name == "Object");
                }
                if (c != null)
                {
                    IEnumerable <string> na1;
                    HashSet <string>     na2;
                    this.GetClassProtocols(c, false, out na1, out na2, out indirectImplementedProtocols);
                }
            }

            // Protocols that the class wishes to implement (direct protocols)
            foreach (string protocolName in directProtocols.OrderBy(pn => pn))
            {
                if (implementedProtocols.Contains(protocolName) || indirectImplementedProtocols.Contains(protocolName))
                {
                    result.Add(protocolName);
                }
                else
                {
                    result.Add("[" + protocolName + "]");
                }

                if (!implementedProtocols.Contains(protocolName) && !indirectImplementedProtocols.Contains(protocolName))
                {
                    missing.Add(protocolName);
                }
            }

            // Protocols that the class have to implement, because the direct protocols inherit from those
            foreach (string protocolName in inheritedProtocols.Where(pn => pn != "ANY").OrderBy(pn => pn))
            {
                if (implementedProtocols.Contains(protocolName) || indirectImplementedProtocols.Contains(protocolName))
                {
                    result.Add("(" + protocolName + ")");
                }
                else
                {
                    result.Add("[" + protocolName + "]");
                }

                if (!implementedProtocols.Contains(protocolName) && !indirectImplementedProtocols.Contains(protocolName))
                {
                    missing.Add(protocolName);
                }
            }

            return(result);
        }