public void GetInheritanceTree()
        {
            IType type = mainProject.GetType("CompletionDbTest.CustomWidget1", false);

            List <string> types = new List <string> ();

            foreach (IType t in mainProject.GetInheritanceTree(type))
            {
                types.Add(t.FullName);
            }

            Assert.IsTrue(types.Contains("CompletionDbTest.CustomWidget1"));
            Assert.IsTrue(types.Contains("Library1.CBin"));
            Assert.IsTrue(types.Contains("Library1.ISimple"));
            Assert.IsTrue(types.Contains("Library2.CWidget"));
            Assert.IsTrue(types.Contains("Library2.IObject"));
            Assert.IsTrue(types.Contains("System.Object"));
            Assert.AreEqual(6, types.Count);

            type = mainProject.GetType("CompletionDbTest.CustomWidget2", false);

            types = new List <string> ();
            foreach (IType t in mainProject.GetInheritanceTree(type))
            {
                types.Add(t.FullName);
            }

            Assert.IsTrue(types.Contains("CompletionDbTest.CustomWidget2"));
            Assert.IsTrue(types.Contains("Library1.SomeContainer.CInnerWidget"));
            Assert.IsTrue(types.Contains("Library2.IObject"));
            Assert.IsTrue(types.Contains("Library2.CWidget"));
            Assert.IsTrue(types.Contains("System.Object"));
            Assert.AreEqual(5, types.Count);
        }
        void AddContentsFromClassAndMembers(ExpressionContext context, CSharpTextEditorCompletion.CompletionDataCollector col)
        {
            IMethod method = callingMember as IMethod;

            if (method != null && method.Parameters != null)
            {
                AddParameterList(col, method.Parameters);
            }
            IProperty property = callingMember as IProperty;

            if (property != null && property.Parameters != null)
            {
                AddParameterList(col, property.Parameters);
            }
            if (CallingType == null)
            {
                return;
            }

            AddContentsFromOuterClass(CallingType, context, col);
            IType callingType = CallingType is InstantiatedType ? ((InstantiatedType)CallingType).UninstantiatedType : CallingType;

            //bool isInStatic = CallingMember != null ? CallingMember.IsStatic : false;

            if (CallingMember == null || !CallingMember.IsStatic)
            {
                foreach (TypeParameter parameter in callingType.TypeParameters)
                {
                    col.Add(parameter.Name, "md-literal");
                }
            }

            if (context != ExpressionContext.TypeDeclaration && CallingMember != null)
            {
                bool includeProtected = DomType.IncludeProtected(dom, CallingType, CallingMember.DeclaringType);
                foreach (IType type in dom.GetInheritanceTree(CallingType))
                {
                    foreach (IMember member in type.Members)
                    {
                        if (!(member is IType) && CallingMember.IsStatic && !(member.IsStatic || member.IsConst))
                        {
                            continue;
                        }
                        if (member.IsAccessibleFrom(dom, CallingType, CallingMember, includeProtected))
                        {
                            if (context.FilterEntry(member))
                            {
                                continue;
                            }
                            col.Add(member);
                        }
                    }
                }
            }
        }
Пример #3
0
        internal static IEnumerable <INode> CollectMembers(ProjectDom dom, IMember member)
        {
            if (member is IMethod && ((IMethod)member).IsConstructor)
            {
                yield return(member);
            }
            else
            {
                bool isOverrideable = member.DeclaringType.ClassType == ClassType.Interface || member.IsOverride || member.IsVirtual || member.IsAbstract;
                bool isLastMember   = false;
                // for members we need to collect the whole 'class' of members (overloads & implementing types)
                HashSet <string> alreadyVisitedTypes = new HashSet <string> ();
                foreach (IType type in dom.GetInheritanceTree(member.DeclaringType))
                {
                    if (type.ClassType == ClassType.Interface || isOverrideable || type.DecoratedFullName == member.DeclaringType.DecoratedFullName)
                    {
                        // search in the class for the member
                        foreach (IMember interfaceMember in type.SearchMember(member.Name, true))
                        {
                            if (interfaceMember.MemberType == member.MemberType)
                            {
                                yield return(interfaceMember);
                            }
                        }

                        // now search in all subclasses of this class for the member
                        isLastMember = !member.IsOverride;
                        foreach (IType implementingType in dom.GetSubclasses(type))
                        {
                            string name = implementingType.DecoratedFullName;
                            if (alreadyVisitedTypes.Contains(name))
                            {
                                continue;
                            }
                            alreadyVisitedTypes.Add(name);
                            foreach (IMember typeMember in implementingType.SearchMember(member.Name, true))
                            {
                                if (typeMember.MemberType == member.MemberType)
                                {
                                    isLastMember = type.ClassType != ClassType.Interface && (typeMember.IsVirtual || typeMember.IsAbstract || !typeMember.IsOverride);
                                    yield return(typeMember);
                                }
                            }
                            if (!isOverrideable)
                            {
                                break;
                            }
                        }
                        if (isLastMember)
                        {
                            break;
                        }
                    }
                }
            }
        }
Пример #4
0
        public static bool IdentifierExistsInClass(ProjectDom parserContext, IType cls, string identifier)
        {
            foreach (IMember member in cls.Members)
            {
                if (member.Name == identifier)
                {
                    return(true);
                }
            }

            return(VisibleIdentifierExistsInBaseClasses(parserContext.GetInheritanceTree(cls), identifier));
        }
Пример #5
0
 static IEnumerable <IMethod> GetAllMethods(
     ProjectDom projectDatabase,
     IType cls)
 {
     foreach (IType type in projectDatabase.GetInheritanceTree(cls))
     {
         foreach (IMethod meth in type.Methods)
         {
             yield return(meth);
         }
     }
 }
Пример #6
0
 static IEnumerable <IEvent> GetAllEvents(
     ProjectDom projectDatabase,
     IType cls)
 {
     foreach (IType type in projectDatabase.GetInheritanceTree(cls))
     {
         foreach (IEvent ev in type.Events)
         {
             yield return(ev);
         }
     }
 }
Пример #7
0
 static IEnumerable <IProperty> GetAllProperties(
     ProjectDom projectDatabase,
     IType cls)
 {
     foreach (IType type in projectDatabase.GetInheritanceTree(cls))
     {
         foreach (IProperty prop in type.Properties)
         {
             yield return(prop);
         }
     }
 }
Пример #8
0
 public static bool IncludeProtected(ProjectDom dom, IType type, IType callingType)
 {
     if (type == null || callingType == null)
     {
         return(false);
     }
     foreach (IType t in dom.GetInheritanceTree(type))
     {
         if (t.FullName == callingType.FullName)
         {
             return(true);
         }
     }
     return(false);
 }
Пример #9
0
        public static IReturnType GetComponentType(ProjectDom dom, IReturnType returnType)
        {
            if (dom == null || returnType == null)
            {
                return(null);
            }
            if (returnType.FullName == DomReturnType.String.FullName && returnType.ArrayDimensions == 0)
            {
                return(DomReturnType.Char);
            }
            if (returnType.ArrayDimensions > 0)
            {
                return(new DomReturnType(returnType.FullName));
            }

            IType resolvedType = dom.GetType(returnType);

            if (resolvedType != null)
            {
                foreach (IType curType in dom.GetInheritanceTree(resolvedType))
                {
                    foreach (IReturnType baseType in curType.BaseTypes)
                    {
                        if (baseType.FullName == "System.Collections.Generic.IEnumerable" && baseType.GenericArguments.Count == 1)
                        {
                            return(baseType.GenericArguments [0]);
                        }
                    }

                    foreach (IProperty property in curType.Properties)
                    {
                        if (property.IsIndexer && !property.IsExplicitDeclaration)
                        {
                            return(property.ReturnType);
                        }
                    }
                }
            }

            if (returnType.GenericArguments.Count > 0)
            {
                return(returnType.GenericArguments [0]);
            }

            return(null);
        }
Пример #10
0
        public bool IsCompatible(IReturnType baseType, IReturnType type)
        {
            if (baseType.ToInvariantString() == type.ToInvariantString())
            {
                return(true);
            }
            ProjectDom dom = null;

            if (CallingType == null)
            {
                return(false);
            }
            dom = CallingType.SourceProjectDom;
            IType b = dom.SearchType(CallingType.CompilationUnit, CallingType, CallingType.Location, baseType);
            IType t = dom.SearchType(CallingType.CompilationUnit, CallingType, CallingType.Location, type);

            if (b == null || t == null)
            {
                return(false);
            }
            return(dom.GetInheritanceTree(t).Any(tBase => tBase.DecoratedFullName == b.DecoratedFullName));
        }
Пример #11
0
            public void Add(ProjectDom dom, IReturnType parameterType, IReturnType type)
            {
//				Console.WriteLine ("Add:" + parameterType +"\n\t->" + type);
                if (type == null || string.IsNullOrEmpty(type.FullName))
                {
                    return;
                }
                string name     = parameterType.Name;
                bool   contains = typeTable.ContainsKey(name);

                // when the type is already in the table use the type that is more general in the inheritance tree.
                if (contains && dom != null)
                {
                    var t1 = dom.GetType(typeTable[name]);
                    var t2 = dom.GetType(type);
                    if (t1 != null && !dom.GetInheritanceTree(t1).Any(t => t.DecoratedFullName == t2.DecoratedFullName))
                    {
                        return;
                    }
                }

                DomReturnType newType = new DomReturnType(type.FullName);

                newType.ArrayDimensions     = Math.Max(0, type.ArrayDimensions - parameterType.ArrayDimensions);
                newType.PointerNestingLevel = Math.Max(0, type.PointerNestingLevel - parameterType.PointerNestingLevel);
                newType.Type = type.Type;                  // May be anonymous type
                for (int i = 0; i < newType.ArrayDimensions; i++)
                {
                    newType.SetDimension(i, parameterType.GetDimension(i));
                }
                foreach (var generic in type.GenericArguments)
                {
                    newType.AddTypeParameter(generic);
                }
                typeTable[name] = newType;
            }
Пример #12
0
        /// <summary>
        /// Resolves the Objective-C types by mapping the known .NET type information.
        /// </summary>
        /// <param name='type'>
        /// An NSObjectTypeInfo with the .NET type information filled in.
        /// </param>
        public void ResolveCliToObjc(NSObjectTypeInfo type)
        {
            NSObjectTypeInfo resolved;

            if (type.BaseObjCType == null && type.BaseCliType != null)
            {
                if (TryResolveCliToObjc(type.BaseCliType, out resolved))
                {
                    if (resolved.IsModel)
                    {
                        type.BaseIsModel = true;
                    }
                    type.BaseObjCType = resolved.ObjCName;
                    //FIXME: handle type references better
                    if (resolved.IsUserType)
                    {
                        type.UserTypeReferences.Add(resolved.ObjCName);
                    }
                }
                else
                {
                    // managed classes may have implicitly registered base classes with a name not
                    // expressible in obj-c. In this case, the best we can do is walk down the
                    // hierarchy until we find a valid base class
                    foreach (var bt in dom.GetInheritanceTree(dom.GetType(type.BaseCliType)))
                    {
                        if (bt.ClassType != ClassType.Class)
                        {
                            continue;
                        }

                        if (TryResolveCliToObjc(bt.FullName, out resolved))
                        {
                            if (resolved.IsModel)
                            {
                                type.BaseIsModel = true;
                            }
                            type.BaseObjCType = resolved.ObjCName;
                            if (resolved.IsUserType)
                            {
                                type.UserTypeReferences.Add(resolved.ObjCName);
                            }
                            break;
                        }
                    }
                }
            }

            foreach (var outlet in type.Outlets)
            {
                if (outlet.ObjCType != null)
                {
                    continue;
                }

                if (TryResolveCliToObjc(outlet.CliType, out resolved))
                {
                    outlet.ObjCType = resolved.ObjCName;
                    if (resolved.IsUserType)
                    {
                        type.UserTypeReferences.Add(resolved.ObjCName);
                    }
                }
            }

            foreach (var action in type.Actions)
            {
                foreach (var param in action.Parameters)
                {
                    if (param.ObjCType != null)
                    {
                        continue;
                    }

                    if (TryResolveCliToObjc(param.CliType, out resolved))
                    {
                        param.ObjCType = resolved.ObjCName;
                        if (resolved.IsUserType)
                        {
                            type.UserTypeReferences.Add(resolved.ObjCName);
                        }
                    }
                }
            }
        }
Пример #13
0
        internal static void AddType(ProjectDom dom, List <object> result, IType type, IMember callingMember, bool showStatic, Func <IMember, bool> filter)
        {
//			System.Console.WriteLine("Add Type:" + type);
            if (type == null)
            {
                return;
            }

            if (showStatic && type.ClassType == ClassType.Enum)
            {
                foreach (IMember member in type.Fields)
                {
                    result.Add(member);
                }
                return;
            }
            List <IType> accessibleStaticTypes = null;

            if (callingMember != null && callingMember.DeclaringType != null)
            {
                accessibleStaticTypes = DomType.GetAccessibleExtensionTypes(dom, callingMember.DeclaringType.CompilationUnit);
            }

/* TODO: Typed extension methods
 *                      IList<IReturnType> genericParameters = null;
 *                      if (type is InstantiatedType)
 *                              genericParameters = ((InstantiatedType)type).GenericParameters;*/

            bool includeProtected = callingMember != null?DomType.IncludeProtected(dom, type, callingMember.DeclaringType) : false;

            if (accessibleStaticTypes != null)
            {
                foreach (IMethod extensionMethod in type.GetAllExtensionMethods(accessibleStaticTypes))
                {
                    result.Add(extensionMethod);
                }
            }
            foreach (IType curType in dom.GetInheritanceTree(type))
            {
                if (curType.ClassType == ClassType.Interface && type.ClassType != ClassType.Interface && !(type is InstantiatedParameterType))
                {
                    continue;
                }
                foreach (IMember member in curType.Members)
                {
                    if (callingMember != null && !member.IsAccessibleFrom(dom, type, callingMember, includeProtected))
                    {
                        continue;
                    }
// handled by member.IsAccessibleFrom
//					if (member.IsProtected && !includeProtected)
//						continue;
                    if (member is IMethod && (((IMethod)member).IsConstructor || ((IMethod)member).IsFinalizer))
                    {
                        continue;
                    }
                    if (!showStatic && member is IType)
                    {
                        continue;
                    }
                    if (filter != null && filter(member))
                    {
                        continue;
                    }
                    if (member is IType || !(showStatic ^ (member.IsStatic || member.IsConst)))
                    {
                        result.Add(member);
                    }
                }
                //	if (showStatic)
                //		break;
            }
        }
Пример #14
0
        protected string InternalCreateInterfaceImplementation(IType implementingType, IType interfaceType, bool explicitly, List <IMember> implementedMembers)
        {
            StringBuilder result = new StringBuilder();

            ProjectDom dom = implementingType.SourceProjectDom;

            List <KeyValuePair <IMember, bool> > toImplement = new List <KeyValuePair <IMember, bool> > ();
            bool alreadyImplemented;

            // Stub out non-implemented events defined by @iface
            foreach (IEvent ev in interfaceType.Events)
            {
                if (ev.IsSpecialName)
                {
                    continue;
                }
                bool needsExplicitly = explicitly;

                alreadyImplemented = dom.GetInheritanceTree(implementingType).Any(x => x.ClassType != ClassType.Interface && x.Events.Any(y => y.Name == ev.Name));

                if (!alreadyImplemented)
                {
                    toImplement.Add(new KeyValuePair <IMember, bool> (ev, needsExplicitly));
                }
            }

            // Stub out non-implemented methods defined by @iface
            foreach (IMethod method in interfaceType.Methods)
            {
                if (method.IsSpecialName)
                {
                    continue;
                }
                bool needsExplicitly = explicitly;
                alreadyImplemented = false;
                foreach (IType t in dom.GetInheritanceTree(implementingType))
                {
                    if (t.ClassType == ClassType.Interface)
                    {
                        continue;
                    }
                    foreach (IMethod cmet in t.Methods)
                    {
                        if (cmet.Name == method.Name && CompareParameters(cmet.Parameters, method.Parameters))
                        {
                            if (!needsExplicitly && !cmet.ReturnType.Equals(method.ReturnType))
                            {
                                needsExplicitly = true;
                            }
                            else
                            {
                                alreadyImplemented |= !needsExplicitly || (interfaceType.FullName == GetExplicitPrefix(cmet.ExplicitInterfaces));
                            }
                        }
                    }
                }
                if (!alreadyImplemented)
                {
                    toImplement.Add(new KeyValuePair <IMember, bool> (method, needsExplicitly));
                }
            }

            // Stub out non-implemented properties defined by @iface
            foreach (IProperty prop in interfaceType.Properties)
            {
                if (prop.IsSpecialName)
                {
                    continue;
                }
                bool needsExplicitly = explicitly;
                alreadyImplemented = false;
                foreach (IType t in dom.GetInheritanceTree(implementingType))
                {
                    if (t.ClassType == ClassType.Interface)
                    {
                        continue;
                    }
                    foreach (IProperty cprop in t.Properties)
                    {
                        if (cprop.Name == prop.Name)
                        {
                            if (!needsExplicitly && !cprop.ReturnType.Equals(prop.ReturnType))
                            {
                                needsExplicitly = true;
                            }
                            else
                            {
                                alreadyImplemented |= !needsExplicitly || (interfaceType.FullName == GetExplicitPrefix(cprop.ExplicitInterfaces));
                            }
                        }
                    }
                }
                if (!alreadyImplemented)
                {
                    toImplement.Add(new KeyValuePair <IMember, bool> (prop, needsExplicitly));
                }
            }
            bool first = true;

            foreach (var pair in toImplement)
            {
                if (!first)
                {
                    AppendLine(result);
                    AppendLine(result);
                }
                else
                {
                    first = false;
                }
                bool isExplicit = pair.Value;
                foreach (IMember member in implementedMembers.Where(m => m.Name == pair.Key.Name && m.MemberType == pair.Key.MemberType))
                {
                    if (member.MemberType == MemberType.Method)
                    {
                        isExplicit = member.ReturnType.ToInvariantString() != pair.Key.ReturnType.ToInvariantString() && CompareParameters(member.Parameters, pair.Key.Parameters);
                    }
                    else
                    {
                        isExplicit = true;
                    }
                }
                result.Append(CreateMemberImplementation(implementingType, pair.Key, isExplicit).Code);
                implementedMembers.Add(pair.Key);
            }

            return(result.ToString());
        }
Пример #15
0
        void UpdateTypeMembers(ProjectDom dom, NSObjectTypeInfo info, IType type)
        {
            info.Actions.Clear();
            info.Outlets.Clear();

            foreach (var prop in type.Properties)
            {
                foreach (var att in prop.Attributes)
                {
                    bool isIBOutlet = att.AttributeType.FullName == iboutletAttType.FullName;
                    if (!isIBOutlet)
                    {
                        if (att.AttributeType.FullName != connectAttType.FullName)
                        {
                            continue;
                        }
                    }
                    string name = null;
                    if (att.PositionalArguments.Count == 1)
                    {
                        name = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
                    }
                    if (string.IsNullOrEmpty(name))
                    {
                        name = prop.Name;
                    }

                    // HACK: Work around bug #1586 in the least obtrusive way possible. Strip out any outlet
                    // with the name 'view' on subclasses of MonoTouch.UIKit.UIViewController to avoid
                    // conflicts with the view property mapped there
                    if (name == "view")
                    {
                        if (dom.GetInheritanceTree(type).Any(p => p.FullName == "MonoTouch.UIKit.UIViewController"))
                        {
                            continue;
                        }
                    }

                    var ol = new IBOutlet(name, prop.Name, null, prop.ReturnType.FullName);
                    if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(prop.DeclaringType.CompilationUnit.FileName))
                    {
                        ol.IsDesigner = true;
                    }
                    info.Outlets.Add(ol);
                    break;
                }
            }

            foreach (var meth in type.Methods)
            {
                foreach (var att in meth.Attributes)
                {
                    bool isIBAction = att.AttributeType.FullName == ibactionAttType.FullName;
                    if (!isIBAction)
                    {
                        if (att.AttributeType.FullName != exportAttType.FullName)
                        {
                            continue;
                        }
                    }
                    bool isDesigner = MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(
                        meth.DeclaringType.CompilationUnit.FileName);
                    //only support Export from old designer files, user code must be IBAction
                    if (!isDesigner && !isIBAction)
                    {
                        continue;
                    }

                    string[] name = null;
                    if (att.PositionalArguments.Count == 1)
                    {
                        var n = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
                        if (!string.IsNullOrEmpty(n))
                        {
                            name = n.Split(colonChar);
                        }
                    }
                    var action = new IBAction(name != null? name [0] : meth.Name, meth.Name);
                    int i      = 1;
                    foreach (var param in meth.Parameters)
                    {
                        string label = name != null && i < name.Length? name[i] : null;
                        if (label != null && label.Length == 0)
                        {
                            label = null;
                        }
                        action.Parameters.Add(new IBActionParameter(label, param.Name, null, param.ReturnType.FullName));
                    }
                    if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(meth.DeclaringType.CompilationUnit.FileName))
                    {
                        action.IsDesigner = true;
                    }
                    info.Actions.Add(action);
                    break;
                }
            }
        }
Пример #16
0
        void ResolveTypes(ProjectDom dom, NSObjectTypeInfo type)
        {
            NSObjectTypeInfo resolved;

            if (type.BaseObjCType == null && type.BaseCliType != null)
            {
                if (cliTypes.TryGetValue(type.BaseCliType, out resolved))
                {
                    if (resolved.IsModel)
                    {
                        type.BaseIsModel = true;
                    }
                    type.BaseObjCType = resolved.ObjCName;
                    if (resolved.IsUserType)
                    {
                        type.UserTypeReferences.Add(resolved.ObjCName);
                    }
                }
                else
                {
                    //managed classes many have implicitly registered base classes with a name not
                    //expressible in obj-c. In this case, the best we can do is walk down the
                    //hierarchy until we find a valid base class
                    foreach (var bt in dom.GetInheritanceTree(dom.GetType(type.BaseCliType)))
                    {
                        if (cliTypes.TryGetValue(bt.FullName, out resolved))
                        {
                            if (resolved.IsModel)
                            {
                                type.BaseIsModel = true;
                            }
                            type.BaseObjCType = resolved.ObjCName;
                            if (resolved.IsUserType)
                            {
                                type.UserTypeReferences.Add(resolved.ObjCName);
                            }
                            break;
                        }
                    }
                    if (type.BaseObjCType == null)
                    {
                        Console.WriteLine("Could not resolve CLI type '{0}'", type.BaseCliType);
                    }
                }
            }

            if (type.BaseCliType == null && type.BaseObjCType != null)
            {
                if (objcTypes.TryGetValue(type.BaseObjCType, out resolved))
                {
                    type.BaseCliType = resolved.CliName;
                }
            }

            foreach (var outlet in type.Outlets)
            {
                if (outlet.ObjCType == null)
                {
                    if (cliTypes.TryGetValue(outlet.CliType, out resolved))
                    {
                        outlet.ObjCType = resolved.ObjCName;
                        if (resolved.IsUserType)
                        {
                            type.UserTypeReferences.Add(resolved.ObjCName);
                        }
                    }
                }
                if (outlet.CliType == null)
                {
                    if (objcTypes.TryGetValue(outlet.ObjCType, out resolved))
                    {
                        outlet.CliType = resolved.CliName;
                    }
                }
            }

            foreach (var action in type.Actions)
            {
                foreach (var param in action.Parameters)
                {
                    if (param.ObjCType == null)
                    {
                        if (cliTypes.TryGetValue(param.CliType, out resolved))
                        {
                            param.ObjCType = resolved.ObjCName;
                            if (resolved.IsUserType)
                            {
                                type.UserTypeReferences.Add(resolved.ObjCName);
                            }
                        }
                    }
                    if (param.CliType == null)
                    {
                        if (objcTypes.TryGetValue(param.ObjCType, out resolved))
                        {
                            param.CliType = resolved.CliName;
                        }
                    }
                }
            }
        }
Пример #17
0
        public IMethod Extends(ProjectDom dom, IType type)
        {
            if (dom == null || type == null || Parameters.Count == 0 || !IsExtension)
            {
                return(null);
            }
            string extensionTableKey = this.HelpUrl + "/" + type.FullName;

            if (Name.StartsWith("ForEachWithIndex"))
            {
                Console.WriteLine("table key:" + extensionTableKey);
            }
            lock (extensionTable) {
                if (extensionTable.ContainsKey(extensionTableKey))
                {
                    return(extensionTable[extensionTableKey]);
                }
                if (type.BaseType != null && type.BaseType.FullName == "System.Array" && Parameters[0].ReturnType.ArrayDimensions > 0)
                {
                    IReturnType elementType = null;
                    foreach (IReturnType returnType in type.BaseTypes)
                    {
                        if (returnType.FullName == "System.Collections.Generic.IList" && returnType.GenericArguments.Count > 0)
                        {
                            elementType = returnType.GenericArguments[0];
                            break;
                        }
                    }
                    if (elementType != null)
                    {
                        IMethod instMethod = DomMethod.CreateInstantiatedGenericMethod(this, new IReturnType[] {}, new IReturnType[] { elementType });
                        instMethod = new ExtensionMethod(type, instMethod, null, null);
                        extensionTable.Add(extensionTableKey, instMethod);
                        return(instMethod);
                    }
                }
                foreach (IType baseType in dom.GetInheritanceTree(type))
                {
                    IMethod instMethod       = DomMethod.CreateInstantiatedGenericMethod(this, new IReturnType[] {}, new IReturnType[] { new DomReturnType(baseType) });
                    string  baseTypeFullName = baseType is InstantiatedType ? ((InstantiatedType)baseType).UninstantiatedType.FullName : baseType.FullName;

                    // compare the generic arguments.
                    if (instMethod.Parameters[0].ReturnType.FullName == baseTypeFullName && Parameters[0].ReturnType.ArrayDimensions == 0 && Parameters[0].ReturnType.PointerNestingLevel == 0)
                    {
                        if (instMethod.Parameters[0].ReturnType.GenericArguments.Count > 0)
                        {
                            InstantiatedType instType = baseType as InstantiatedType;
                            if (instType == null || instType.GenericParameters.Count != instMethod.Parameters[0].ReturnType.GenericArguments.Count)
                            {
                                continue;
                            }
                            bool genericArgumentsAreEqual = true;
                            for (int i = 0; i < instMethod.Parameters[0].ReturnType.GenericArguments.Count; i++)
                            {
                                if (Name.StartsWith("ForEachWithIndex"))
                                {
                                    Console.WriteLine(instMethod.Parameters[0].ReturnType.GenericArguments[i].DecoratedFullName + " --- " + instType.GenericParameters[i].DecoratedFullName);
                                }
                                if (instMethod.Parameters[0].ReturnType.GenericArguments[i].DecoratedFullName != instType.GenericParameters[i].DecoratedFullName)
                                {
                                    genericArgumentsAreEqual = false;
                                    break;
                                }
                            }
                            if (!genericArgumentsAreEqual)
                            {
                                continue;
                            }
                        }

                        //ExtensionMethod result = new ExtensionMethod (baseType, this, null, null);
                        instMethod = new ExtensionMethod(type, instMethod, null, null);
                        extensionTable.Add(extensionTableKey, instMethod);
                        //Console.WriteLine ("ext. method:" + instMethod);
                        return(instMethod);
                    }
                }
//				Console.WriteLine ("null");
                extensionTable.Add(extensionTableKey, null);
                return(null);
            }
        }
Пример #18
0
        //TODO: check accessibility
        public static IEnumerable <IMethod> GetCompatibleMethodsInClass(ProjectDom ctx, IType cls, IMethod matchMeth)
        {
            IList <IType>[] pars = new IList <IType> [matchMeth.Parameters.Count];
            for (int i = 0; i < matchMeth.Parameters.Count; i++)
            {
                IType t = ctx.GetType(matchMeth.Parameters[i].ReturnType);
                if (t != null)
                {
                    pars[i] = new List <IType> (ctx.GetInheritanceTree(t));
                }
                else
                {
                    pars[i] = new IType[0];
                }
            }

            foreach (IType type in ctx.GetInheritanceTree(cls))
            {
                if (type.ClassType != ClassType.Class)
                {
                    continue;
                }

                foreach (IMethod method in type.Methods)
                {
                    if (method.IsPrivate || method.Parameters.Count != pars.Length || method.ReturnType.FullName != matchMeth.ReturnType.FullName

                        || method.IsInternal)
                    {
                        continue;
                    }

                    bool allCompatible = true;

                    //compare each parameter
                    for (int i = 0; i < pars.Length; i++)
                    {
                        bool parCompatible = false;
                        foreach (IType t in pars[i])
                        {
                            if (t.FullName == method.Parameters[i].ReturnType.FullName)
                            {
                                parCompatible = true;
                                break;
                            }
                        }

                        if (!parCompatible)
                        {
                            allCompatible = false;
                            break;
                        }
                    }

                    if (allCompatible)
                    {
                        yield return(method);
                    }
                }
            }
        }