/// <summary> /// Adds extension methods to <paramref name="res"/>. /// </summary> public static void AddExtensions(LanguageProperties language, Action <IMethodOrProperty> methodFound, IClass callingClass, IReturnType resolvedType, bool searchInAllNamespaces = false) { if (language == null) { throw new ArgumentNullException("language"); } if (methodFound == null) { throw new ArgumentNullException("methodFound"); } if (resolvedType == null) { throw new ArgumentNullException("resolvedType"); } if (callingClass == null) { throw new ArgumentNullException("callingClass"); } // convert resolvedType into direct type to speed up the IsApplicable lookups resolvedType = resolvedType.GetDirectReturnType(); foreach (IMethodOrProperty mp in CtrlSpaceResolveHelper.FindAllExtensions(language, callingClass, searchInAllNamespaces)) { TryAddExtension(language, methodFound, mp, resolvedType); } }
public static List <IList <IMember> > LookupMember( IReturnType type, string name, IClass callingClass, LanguageProperties language, bool isInvocation, bool?isAccessThoughReferenceOfCurrentClass) { if (language == null) { throw new ArgumentNullException("language"); } if (isAccessThoughReferenceOfCurrentClass == null) { isAccessThoughReferenceOfCurrentClass = false; IClass underlyingClass = type.GetUnderlyingClass(); if (underlyingClass != null) { isAccessThoughReferenceOfCurrentClass = underlyingClass.IsTypeInInheritanceTree(callingClass); } } IEnumerable <IMember> members; if (language == LanguageProperties.VBNet && language.NameComparer.Equals(name, "New")) { members = GetAllMembers(type).OfType <IMethod>().Where(m => m.IsConstructor).Select(m => (IMember)m); } else { members = GetAllMembers(type).Where(m => language.NameComparer.Equals(m.Name, name)); } return(LookupMember(members, callingClass, (bool)isAccessThoughReferenceOfCurrentClass, isInvocation)); }
static void TryAddExtension(LanguageProperties language, Action <IMethodOrProperty> methodFound, IMethodOrProperty ext, IReturnType resolvedType) { // now add the extension method if it fits the type if (MemberLookupHelper.IsApplicable(resolvedType, ext.Parameters[0].ReturnType, ext as IMethod)) { IMethod method = ext as IMethod; if (method != null && method.TypeParameters.Count > 0) { IReturnType[] typeArguments = new IReturnType[method.TypeParameters.Count]; MemberLookupHelper.InferTypeArgument(method.Parameters[0].ReturnType, resolvedType, typeArguments); for (int i = 0; i < typeArguments.Length; i++) { if (typeArguments[i] != null) { ext = (IMethod)ext.CreateSpecializedMember(); ext.ReturnType = ConstructedReturnType.TranslateType(ext.ReturnType, typeArguments, true); for (int j = 0; j < ext.Parameters.Count; ++j) { ext.Parameters[j].ReturnType = ConstructedReturnType.TranslateType(ext.Parameters[j].ReturnType, typeArguments, true); } break; } } } methodFound(ext); } }
/// <summary> /// Gets the class dictionary that uses the name comparison rules of <paramref name="language"/>. /// </summary> protected Dictionary <string, IClass> GetClasses(LanguageProperties language) { for (int i = 0; i < classLists.Count; ++i) { if (classLists[i].Comparer == language.NameComparer) { return(classLists[i]); } } Dictionary <string, IClass> d; if (classLists.Count > 0) { Dictionary <string, IClass> oldList = classLists[0]; d = new Dictionary <string, IClass>(oldList.Count, language.NameComparer); foreach (KeyValuePair <string, IClass> pair in oldList) { // don't use d.Add(), the new name language might treat two names as equal // that were unequal in the old dictionary d[pair.Key] = pair.Value; } } else { d = new Dictionary <string, IClass>(language.NameComparer); } classLists.Add(d); return(d); }
/// <summary> /// Adds the contents of all namespaces in this project to the <paramref name="list"/>. /// </summary> /// <param name="lookInReferences">If true, contents of referenced projects will be added as well (not recursive - just 1 level deep).</param> public void AddAllContents(List <ICompletionEntry> list, LanguageProperties language, bool lookInReferences) { if (lookInReferences) { lock (referencedContents) { foreach (IProjectContent content in referencedContents) { content.AddAllContents(list, language, false); } } } lock (namespaces) { Dictionary <string, NamespaceStruct> dict = GetNamespaces(language); foreach (var namespaceStruct in dict.Values) { AddNamespaceStructContents(list, namespaceStruct, language, lookInReferences); } } }
void AddNamespaceContentsClass(List <ICompletionEntry> list, IClass c, LanguageProperties language, bool lookInReferences) { if (c.IsInternal && !lookInReferences) { // internal class and we are looking at it from another project content return; } if (language.ShowInNamespaceCompletion(c)) { list.Add(c); } if (language.ImportModules && c.ClassType == ClassType.Module) { foreach (IMember m in c.Methods) { if (m.IsAccessible(null, false)) { list.Add(m); } } foreach (IMember m in c.Events) { if (m.IsAccessible(null, false)) { list.Add(m); } } foreach (IMember m in c.Fields) { if (m.IsAccessible(null, false)) { list.Add(m); } } foreach (IMember m in c.Properties) { if (m.IsAccessible(null, false)) { list.Add(m); } } } }
/// <summary> /// Gets the namespace dictionary that uses the name comparison rules of <paramref name="language"/>. /// </summary> protected Dictionary <string, NamespaceStruct> GetNamespaces(LanguageProperties language) { for (int i = 0; i < namespaces.Count; ++i) { if (namespaces[i].Comparer == language.NameComparer) { return(namespaces[i]); } } Dictionary <string, NamespaceStruct> d; if (namespaces.Count > 0) { Dictionary <string, NamespaceStruct> oldList = namespaces[0]; d = new Dictionary <string, NamespaceStruct>(oldList.Count, language.NameComparer); foreach (KeyValuePair <string, NamespaceStruct> pair in oldList) { NamespaceStruct ns; if (d.TryGetValue(pair.Key, out ns)) { // we got a name conflict due to the new NameComparer. // This happens if a C# assembly contains the namespace "a" and "A", // and now we're trying to get a dictionary for use in VB. d[pair.Key] = ns.MergeWith(pair.Value); } else { d.Add(pair.Key, pair.Value); } } } else { d = new Dictionary <string, NamespaceStruct>(language.NameComparer); } namespaces.Add(d); return(d); }
/// <summary> /// Searches the member with the specified name. Returns the first member/overload found. /// </summary> public IMember SearchMember(string memberName, LanguageProperties language) { if (memberName == null || memberName.Length == 0) { return(null); } StringComparer cmp = language.NameComparer; foreach (IProperty p in Properties) { if (cmp.Equals(p.Name, memberName)) { return(p); } } foreach (IEvent e in Events) { if (cmp.Equals(e.Name, memberName)) { return(e); } } foreach (IField f in Fields) { if (cmp.Equals(f.Name, memberName)) { return(f); } } foreach (IMethod m in Methods) { if (cmp.Equals(m.Name, memberName)) { return(m); } } return(null); }
protected List <ICompletionEntry> GetCompletionData(LanguageProperties language, bool showStatic) { if (resolvedType == null) { return(null); } List <ICompletionEntry> res = new List <ICompletionEntry>(); foreach (IMember m in MemberLookupHelper.GetAccessibleMembers(resolvedType, callingClass, language)) { if (language.ShowMember(m, showStatic)) { res.Add(m); } } if (!showStatic && callingClass != null) { AddExtensions(language, res.Add, callingClass, resolvedType, this.showAllNamespacesContentsInCC); } return(res); }
protected IClass GetClassInternal(string typeName, int typeParameterCount, LanguageProperties language) { CheckNotDisposed(); #if DEBUG if (System.Text.RegularExpressions.Regex.IsMatch(typeName, "`[0-9]+$")) { Debug.Assert(false, "how did a Reflection type name get here?"); } #endif lock (namespaces) { IClass c; if (GetClasses(language).TryGetValue(typeName, out c)) { GenericClassContainer gcc = c as GenericClassContainer; if (gcc != null) { return(gcc.GetBest(typeParameterCount)); } return(c); } return(null); } }
public bool NamespaceExists(string name, LanguageProperties language, bool lookInReferences) { if (name == null) { return(false); } if (lookInReferences) { lock (referencedContents) { foreach (IProjectContent content in referencedContents) { if (content.NamespaceExists(name, language, false)) { return(true); } } } } lock (namespaces) { return(GetNamespaces(language).ContainsKey(name)); } }
public static IList <IMethodOrProperty> FindAllExtensions(LanguageProperties language, IClass callingClass, bool searchInAllNamespaces = false) { if (language == null) { throw new ArgumentNullException("language"); } if (callingClass == null) { throw new ArgumentNullException("callingClass"); } HashSet <IMethodOrProperty> res = new HashSet <IMethodOrProperty>(); bool supportsExtensionMethods = language.SupportsExtensionMethods; bool supportsExtensionProperties = language.SupportsExtensionProperties; if (supportsExtensionMethods || supportsExtensionProperties) { List <ICompletionEntry> list = new List <ICompletionEntry>(); IMethod dummyMethod = new DefaultMethod("dummy", callingClass.ProjectContent.SystemTypes.Void, ModifierEnum.Static, DomRegion.Empty, DomRegion.Empty, callingClass); CtrlSpaceResolveHelper.AddContentsFromCalling(list, callingClass, dummyMethod); if (searchInAllNamespaces) { // search extension methods in all referenced projects, no matter the using section CtrlSpaceResolveHelper.AddReferencedProjectsContents(list, callingClass.CompilationUnit, callingClass); } else { CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, callingClass.CompilationUnit, callingClass); } bool searchExtensionsInClasses = language.SearchExtensionsInClasses; foreach (object o in list) { IMethodOrProperty mp = o as IMethodOrProperty; if (mp != null && mp.IsExtensionMethod && (supportsExtensionMethods && o is IMethod || supportsExtensionProperties && o is IProperty)) { res.Add(mp); } else if (searchExtensionsInClasses && o is IClass) { IClass c = o as IClass; if (c.HasExtensionMethods) { if (supportsExtensionProperties) { foreach (IProperty p in c.Properties) { if (p.IsExtensionMethod) { res.Add(p); } } } if (supportsExtensionMethods) { foreach (IMethod m in c.Methods) { if (m.IsExtensionMethod) { res.Add(m); } } } } } } } return(res.ToList()); } // FindAllExtensions
public IClass GetClass(string typeName, int typeParameterCount, LanguageProperties language, GetClassOptions options) { IClass c = GetClassInternal(typeName, typeParameterCount, language); if (c != null && c.TypeParameters.Count == typeParameterCount) { return(c); } // Search in references: if ((options & GetClassOptions.LookInReferences) != 0) { lock (referencedContents) { foreach (IProjectContent content in referencedContents) { // Look for the class in the referenced content. // Don't do a inner-class search in the recursive call - one search // done by this GetClass call is sufficient. IClass contentClass = content.GetClass( typeName, typeParameterCount, language, options & ~(GetClassOptions.LookInReferences | GetClassOptions.LookForInnerClass)); if (contentClass != null) { if (contentClass.TypeParameters.Count == typeParameterCount && IsAccessibleClass(contentClass)) { return(contentClass); } else { c = contentClass; } } } } } if ((options & GetClassOptions.LookForInnerClass) != 0) { // not found -> maybe nested type -> trying to find class that contains this one. int lastIndex = typeName.LastIndexOf('.'); if (lastIndex > 0) { string outerName = typeName.Substring(0, lastIndex); IClass upperClass = GetClass(outerName, typeParameterCount, language, options); if (upperClass != null) { foreach (IClass upperBaseClass in upperClass.ClassInheritanceTree) { IList <IClass> innerClasses = upperBaseClass.InnerClasses; if (innerClasses != null) { string innerName = typeName.Substring(lastIndex + 1); foreach (IClass innerClass in innerClasses) { if (language.NameComparer.Equals(innerClass.Name, innerName)) { if (innerClass.TypeParameters.Count == typeParameterCount) { return(innerClass); } else { // store match c = innerClass; } } } } } } } } if ((options & GetClassOptions.ExactMatch) == GetClassOptions.ExactMatch) { return(null); } else { // no matching class found - we'll return a class with different type paramter count return(c); } }
/// <summary> /// Adds the contents of the specified <paramref name="nameSpace"/> to the <paramref name="list"/>. /// </summary> /// <param name="lookInReferences">If true, contents of referenced projects will be added as well (not recursive - just 1 level deep).</param> public void AddNamespaceContents(List <ICompletionEntry> list, string nameSpace, LanguageProperties language, bool lookInReferences) { if (nameSpace == null) { return; } if (lookInReferences) { lock (referencedContents) { foreach (IProjectContent content in referencedContents) { content.AddNamespaceContents(list, nameSpace, language, false); } } } lock (namespaces) { Dictionary <string, NamespaceStruct> dict = GetNamespaces(language); if (dict.ContainsKey(nameSpace)) { NamespaceStruct ns = dict[nameSpace]; AddNamespaceStructContents(list, ns, language, lookInReferences); } } }
/// <summary> /// Gets all accessible members, including indexers and constructors. /// </summary> public static List <IMember> GetAccessibleMembers(IReturnType rt, IClass callingClass, LanguageProperties language, bool isAccessThoughReferenceOfCurrentClass) { if (language == null) { throw new ArgumentNullException("language"); } List <IMember> result = new List <IMember>(); foreach (var g in GetAllMembers(rt).GroupBy(m => m.Name, language.NameComparer).OrderBy(g2 => g2.Key)) { foreach (var group in LookupMember(g, callingClass, isAccessThoughReferenceOfCurrentClass, false)) { result.AddRange(group); } } return(result); }
/// <summary> /// Gets all accessible members, including indexers and constructors. /// </summary> public static List <IMember> GetAccessibleMembers(IReturnType rt, IClass callingClass, LanguageProperties language) { bool isAccessThoughReferenceOfCurrentClass = false; IClass underlyingClass = rt.GetUnderlyingClass(); if (underlyingClass != null) { isAccessThoughReferenceOfCurrentClass = underlyingClass.IsTypeInInheritanceTree(callingClass); } return(GetAccessibleMembers(rt, callingClass, language, isAccessThoughReferenceOfCurrentClass)); }
void AddNamespaceStructContents(List <ICompletionEntry> list, NamespaceStruct ns, LanguageProperties language, bool lookInReferences) { int newCapacity = list.Count + ns.Classes.Count + ns.SubNamespaces.Count; if (list.Capacity < newCapacity) { list.Capacity = Math.Max(list.Count * 2, newCapacity); } foreach (IClass c in ns.Classes) { if (c is GenericClassContainer) { foreach (IClass realClass in ((GenericClassContainer)c).RealClasses) { AddNamespaceContentsClass(list, realClass, language, lookInReferences); } } else { AddNamespaceContentsClass(list, c, language, lookInReferences); } } foreach (string subns in ns.SubNamespaces) { NamespaceEntry subnsEntry = new NamespaceEntry(subns); if (!list.Contains(subnsEntry)) // PERF { list.Add(subnsEntry); } } }