public override IEnumerable <CompletionItem> GetProperties(string objectName, IEnumerable <string> path) { var prefix = PrefixWithColon; if (prefix != null) { if (!objectName.StartsWith(prefix)) { yield break; } objectName = objectName.Substring(prefix.Length); } var fullName = Namespace + "." + objectName; var type = Assembly.GetType(fullName, false); if (type != null) { foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (prop.SetMethod == null || !prop.SetMethod.IsPublic) { continue; } if (prop.GetCustomAttribute <ObsoleteAttribute>() != null) { continue; } var underlyingType = Nullable.GetUnderlyingType(prop.PropertyType); var suffix = underlyingType != null ? underlyingType.Name + "?" : prop.PropertyType.Name; // todo: get friendly names for generic types yield return(new CompletionItem { Name = prop.Name, Suffix = suffix, Description = XmlComments.GetSummary(prop), Type = CompletionType.Property }); } foreach (var evt in type.GetEvents(BindingFlags.Public | BindingFlags.Instance)) { yield return(new CompletionItem { Name = evt.Name, Description = XmlComments.GetSummary(evt), Type = CompletionType.Event }); } } }
public override IEnumerable <CompletionItem> GetClasses(IEnumerable <string> path, Func <Type, bool> filter) { var prefixWithColon = PrefixWithColon; string contentProperty; var nodeType = GetNodeType(path.LastOrDefault(), out contentProperty); var contentType = GetContentType(nodeType, contentProperty); var types = GetExportedTypes(); if (filter != null) { foreach (var result in types.Where(filter)) { // special case, don't allow windows as a child control if (contentType != null && typeof(Window).IsAssignableFrom(result)) { continue; } yield return(new CompletionItem { Name = prefixWithColon + result.Name, Description = XmlComments.GetSummary(result), Type = CompletionType.Class }); } } if (contentType != null && !contentType.IsAbstract && !types.Contains(contentType) && contentType.Assembly == Assembly) { yield return new CompletionItem { Name = prefixWithColon + contentType.Name, Description = XmlComments.GetSummary(contentType), Type = CompletionType.Class } } ; if (nodeType != null) { yield return(new CompletionItem { Name = prefixWithColon + nodeType.Name + ".", Description = "Add a property tag", Type = CompletionType.Property }); } } Type GetNodeType(string last, out string propertyName) { propertyName = null; var prefix = PrefixWithColon; if (!string.IsNullOrEmpty(prefix)) { if (!last.StartsWith(prefix)) { return(null); } last = last.Substring(prefix.Length); } else if (last.Contains(':')) { return(null); } if (string.IsNullOrEmpty(last)) { return(null); } var dotIndex = last.IndexOf('.'); if (dotIndex > 0) { propertyName = last.Substring(dotIndex + 1); last = last.Substring(0, dotIndex); } last = Namespace + "." + last; var types = GetExportedTypes(); return(types.FirstOrDefault(r => r.FullName == last)); } Type GetContentType(Type type, string propertyName) { if (type != null) { if (string.IsNullOrEmpty(propertyName)) { var contentProperty = type.GetCustomAttribute <ContentPropertyAttribute>(); if (contentProperty != null) { propertyName = contentProperty.Name; } } if (!string.IsNullOrEmpty(propertyName)) { var prop = type.GetProperty(propertyName); if (prop != null) { var propType = prop.PropertyType; if (typeof(IList).IsAssignableFrom(propType)) { var list = propType.GetInterfaces().FirstOrDefault(r => r.IsGenericType && r.GetGenericTypeDefinition() == typeof(IList <>)); if (list != null) { return(list.GenericTypeArguments[0]); } } return(prop.PropertyType); } } } return(null); }