public override void Complete(CompletionContext context, ICompletionItem item) { using (context.Editor.Document.OpenUndoGroup()) { base.Complete(context, item); XamlCompletionContext xamlContext = CompletionDataHelper.ResolveCompletionContext(context.Editor, context.CompletionChar); if (xamlContext.Description == XamlContextDescription.None && (context.StartOffset <= 0 || context.Editor.Document.GetCharAt(context.StartOffset - 1) != '<')) { context.Editor.Document.Insert(context.StartOffset, "<"); context.EndOffset++; } if (item is XamlCodeCompletionItem) { XamlCodeCompletionItem cItem = item as XamlCodeCompletionItem; if (cItem.Entity is IProperty || cItem.Entity is IEvent) { if (xamlContext.Description == XamlContextDescription.InTag) { context.Editor.Document.Insert(context.EndOffset, "=\"\""); context.CompletionCharHandled = context.CompletionChar == '='; context.Editor.Caret.Offset--; new XamlCodeCompletionBinding().CtrlSpace(context.Editor); } else if (xamlContext.Description == XamlContextDescription.InMarkupExtension && !string.IsNullOrEmpty(xamlContext.RawAttributeValue)) { string valuePart = xamlContext.RawAttributeValue.Substring(0, xamlContext.ValueStartOffset); AttributeValue value = MarkupExtensionParser.ParseValue(valuePart); if (value != null && !value.IsString) { var markup = Utils.GetMarkupExtensionAtPosition(value.ExtensionValue, context.Editor.Caret.Offset); if (markup.NamedArguments.Count > 0 || markup.PositionalArguments.Count > 0) { int oldOffset = context.Editor.Caret.Offset; context.Editor.Caret.Offset = context.StartOffset; string word = context.Editor.GetWordBeforeCaret().TrimEnd(); int spaces = CountWhiteSpacesAtEnd(context.Editor.GetWordBeforeCaret()); int typeNameStart = markup.ExtensionType.IndexOf(':') + 1; if (!(word == "." || word == "," || word == ":") && markup.ExtensionType.Substring(typeNameStart, markup.ExtensionType.Length - typeNameStart) != word) { context.Editor.Document.Replace(context.Editor.Caret.Offset - spaces, spaces, ", "); oldOffset += (2 - spaces); } context.Editor.Caret.Offset = oldOffset; } } if (cItem.Text.EndsWith("=", StringComparison.OrdinalIgnoreCase)) { new XamlCodeCompletionBinding().CtrlSpace(context.Editor); } } } } if (item is NewEventCompletionItem) { NewEventCompletionItem eventItem = item as NewEventCompletionItem; int discriminator; if (CreateEventHandlerCode(context, eventItem, out discriminator)) { if (discriminator > 0) { context.Editor.Document.Insert(context.EndOffset, discriminator.ToString()); } } } if (item is XmlnsCompletionItem) { context.Editor.Caret.Offset++; } if (item is XamlCompletionItem && xamlContext.Description == XamlContextDescription.InTag) { context.Editor.Document.Insert(context.EndOffset, "=\"\""); context.Editor.Caret.Offset--; new XamlCodeCompletionBinding().CtrlSpace(context.Editor); } switch (item.Text) { case "![CDATA[": context.Editor.Document.Insert(context.Editor.Caret.Offset, "]]>"); context.Editor.Caret.Offset -= 3; break; case "?": context.Editor.Document.Insert(context.Editor.Caret.Offset, "?>"); context.Editor.Caret.Offset -= 2; break; case "!--": context.Editor.Document.Insert(context.Editor.Caret.Offset, " -->"); context.Editor.Caret.Offset -= 4; break; } if (item.Text.StartsWith("/", StringComparison.OrdinalIgnoreCase)) { context.Editor.Document.Insert(context.EndOffset, ">"); context.CompletionCharHandled = context.CompletionChar == '>'; context.Editor.Caret.Offset++; } } }
public static IList<ICompletionItem> CreateElementList(XamlCompletionContext context, bool classesOnly, bool includeAbstract) { var items = GetClassesFromContext(context); var result = new List<ICompletionItem>(); var last = context.ParentElement; if (context.ParseInformation == null) return emptyList; XamlCompilationUnit cu = context.ParseInformation.CompilationUnit as XamlCompilationUnit; IReturnType rt = null; if (last != null && cu != null) { if (!last.Name.Contains(".") || last.Name.EndsWith(".", StringComparison.OrdinalIgnoreCase)) { rt = cu.CreateType(last.Namespace, last.LocalName.Trim('.')); string contentPropertyName = GetContentPropertyName(rt); if (!string.IsNullOrEmpty(contentPropertyName)) { string fullName = last.Name + "." + contentPropertyName; MemberResolveResult mrr = XamlResolver.Resolve(fullName, context) as MemberResolveResult; if (mrr != null) { rt = mrr.ResolvedType; } } } else { MemberResolveResult mrr = XamlResolver.Resolve(last.Name, context) as MemberResolveResult; if (mrr != null) { rt = mrr.ResolvedType; } } } bool isList = rt != null && rt.IsListReturnType(); bool parentAdded = false; foreach (var ns in items) { foreach (var c in ns.Value) { if (includeAbstract) { if (c.ClassType == ClassType.Class) { if (c.IsStatic || c.DerivesFrom("System.Attribute")) continue; } else if (c.ClassType == ClassType.Interface) { } else { continue; } } else { if (!(c.ClassType == ClassType.Class && c.IsAbstract == includeAbstract && !c.IsStatic && // TODO : use c.DefaultReturnType.GetConstructors(ctor => ctor.IsAccessible(context.ParseInformation.CompilationUnit.Classes.FirstOrDefault(), false)) after DOM rewrite !c.DerivesFrom("System.Attribute") && (c.AddDefaultConstructorIfRequired || c.Methods.Any(m => m.IsConstructor && m.IsAccessible(context.ParseInformation.CompilationUnit.Classes.FirstOrDefault(), false))))) continue; } if (last != null && isList) { var possibleTypes = rt.GetMethods() .Where(a => a.Parameters.Count == 1 && a.Name == "Add") .Select(method => method.Parameters.First().ReturnType.GetUnderlyingClass()).Where(p => p != null); if (!possibleTypes.Any(t => c.ClassInheritanceTreeClassesOnly.Any(c2 => c2.FullyQualifiedName == t.FullyQualifiedName))) continue; } XamlCodeCompletionItem item = new XamlCodeCompletionItem(c, ns.Key); parentAdded = parentAdded || (last != null && item.Text == last.Name); result.Add(new XamlCodeCompletionItem(c, ns.Key)); } } if (!parentAdded && last != null && !last.Name.Contains(".")) { IClass itemClass = cu.CreateType(last.Namespace, last.LocalName.Trim('.')).GetUnderlyingClass(); if (itemClass != null) result.Add(new XamlCodeCompletionItem(itemClass, last.Prefix)); } var xamlItems = XamlNamespaceAttributes.AsEnumerable(); if (EnableXaml2009) xamlItems = xamlBuiltInTypes.Concat(XamlNamespaceAttributes); foreach (string item in xamlItems) result.Add(new XamlCompletionItem(context.XamlNamespacePrefix, XamlNamespace, item)); return result; }