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); } } } } }
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; } } } } }
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)); }
static IEnumerable <IMethod> GetAllMethods( ProjectDom projectDatabase, IType cls) { foreach (IType type in projectDatabase.GetInheritanceTree(cls)) { foreach (IMethod meth in type.Methods) { yield return(meth); } } }
static IEnumerable <IEvent> GetAllEvents( ProjectDom projectDatabase, IType cls) { foreach (IType type in projectDatabase.GetInheritanceTree(cls)) { foreach (IEvent ev in type.Events) { yield return(ev); } } }
static IEnumerable <IProperty> GetAllProperties( ProjectDom projectDatabase, IType cls) { foreach (IType type in projectDatabase.GetInheritanceTree(cls)) { foreach (IProperty prop in type.Properties) { yield return(prop); } } }
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); }
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); }
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)); }
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; }
/// <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); } } } } }
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; } }
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()); }
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; } } }
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; } } } } }
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); } }
//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); } } } }