From c8af97298be99d777b97b4e862dd0e59fa18a08e Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 12 Mar 2012 18:13:12 +0100 Subject: [PATCH] WIP on XamlBinding --- .../XamlBinding/XamlBinding/Comparers.cs | 5 +- .../CompilationUnitCreatorVisitor.cs | 181 --- .../XamlBinding/CompletionDataHelper.cs | 1389 ----------------- .../XamlBinding/XamlBinding/Extensions.cs | 59 +- .../XamlBinding/MarkupExtensionInfo.cs | 2 +- .../Options/CodeCompletion.xaml.cs | 2 +- .../XamlBinding/XamlBinding/Utils.cs | 4 +- .../XamlBinding/XamlBinding/XamlBehavior.cs | 9 +- .../XamlBinding/XamlBinding.csproj | 70 +- .../XamlBinding/XamlClassReturnType.cs | 42 - .../XamlBinding/XamlCodeCompletionBinding.cs | 743 ++++----- .../XamlBinding/XamlBinding/XamlColorizer.cs | 394 ----- .../XamlBinding/XamlCompilationUnit.cs | 143 -- .../XamlBinding/XamlCompletionItem.cs | 309 ---- .../XamlBinding/XamlCompletionItemList.cs | 334 ++-- .../XamlBinding/XamlBinding/XamlContext.cs | 35 +- .../XamlBinding/XamlExpressionContext.cs | 9 +- .../XamlBinding/XamlExpressionFinder.cs | 75 - .../XamlBinding/XamlLanguageBinding.cs | 21 +- .../XamlOutlineContentHost.xaml.cs | 13 +- .../XamlBinding/XamlOutlineNode.cs | 1 + .../XamlBinding/XamlBinding/XamlParsedFile.cs | 97 ++ .../XamlBinding/XamlBinding/XamlParser.cs | 190 ++- .../XamlBinding/XamlBinding/XamlResolver.cs | 271 ---- .../XamlBinding/XamlSymbolSearch.cs | 32 + 25 files changed, 853 insertions(+), 3577 deletions(-) delete mode 100644 src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompilationUnitCreatorVisitor.cs delete mode 100644 src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs delete mode 100644 src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlClassReturnType.cs delete mode 100644 src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlColorizer.cs delete mode 100644 src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompilationUnit.cs delete mode 100644 src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItem.cs delete mode 100644 src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlExpressionFinder.cs create mode 100644 src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParsedFile.cs delete mode 100644 src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs create mode 100644 src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlSymbolSearch.cs diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Comparers.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Comparers.cs index 1a218ee5b1..daa53acd44 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Comparers.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Comparers.cs @@ -2,12 +2,11 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using ICSharpCode.SharpDevelop.Dom; using System.Collections.Generic; namespace ICSharpCode.XamlBinding { - sealed class ParameterComparer : IEqualityComparer { + /*sealed class ParameterComparer : IEqualityComparer { public bool Equals(IParameter x, IParameter y) { return x.Compare(y); @@ -45,5 +44,5 @@ namespace ICSharpCode.XamlBinding else return string.CompareOrdinal(x.Assembly, y.Assembly); } - } + }*/ } diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompilationUnitCreatorVisitor.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompilationUnitCreatorVisitor.cs deleted file mode 100644 index 3ed7c9d892..0000000000 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompilationUnitCreatorVisitor.cs +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; - -using ICSharpCode.AvalonEdit.Xml; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Project; - -namespace ICSharpCode.XamlBinding -{ - public sealed class CompilationUnitCreatorVisitor : AbstractAXmlVisitor - { - public XamlCompilationUnit CompilationUnit { get; private set; } - AXmlDocument document; - IClass generatedClass; - IProjectContent projectContent; - Stack nodeStack; - IAmbience currentAmbience; - - /// - /// string representation of the document, used to create DOM regions. - /// - string fileContent; - - string[] lexerTags; - - public CompilationUnitCreatorVisitor(IProjectContent projectContent, string fileContent, string fileName, string[] lexerTags) - { - this.CompilationUnit = new XamlCompilationUnit(projectContent); - - this.CompilationUnit.FileName = fileName; - this.fileContent = fileContent; - this.lexerTags = lexerTags; - this.projectContent = projectContent; - this.currentAmbience = projectContent.Language.GetAmbience(); - - this.nodeStack = new Stack(); - } - - public override void VisitDocument(AXmlDocument document) - { - this.CompilationUnit.ErrorsDuringCompile = document.SyntaxErrors.Any(); - this.document = document; - - base.VisitDocument(document); - } - - public override void VisitAttribute(AXmlAttribute attribute) - { - Debug.Assert(document != null); - - if (attribute.ParentElement != null) { - if (attribute.ParentElement.Parent == document && attribute.LocalName == "Class" && - attribute.Namespace == CompletionDataHelper.XamlNamespace) { - this.generatedClass = AddClass(attribute.Value, attribute.ParentElement); - } else if (generatedClass != null && attribute.LocalName == "Name") { - string name = attribute.Value; - - if (!string.IsNullOrEmpty(name)) { - IReturnType type = TypeFromXmlNode(CompilationUnit, attribute.ParentElement); - DomRegion position = CreateRegion(attribute.ParentElement.StartOffset, attribute.ParentElement.StartOffset + attribute.ParentElement.Name.Length); - - ModifierEnum fieldModifier = ModifierEnum.Internal; - - string modifierValue = (attribute.ParentElement.GetAttributeValue(CompletionDataHelper.XamlNamespace, "FieldModifier") ?? string.Empty).Trim(); - - string publicString = currentAmbience.ConvertAccessibility(ModifierEnum.Public).Trim(); - - if (projectContent.Language.NameComparer.Compare(modifierValue, publicString) == 0) - fieldModifier = ModifierEnum.Public; - - generatedClass.Fields.Add(new DefaultField(type, name, fieldModifier, position, generatedClass)); - } - } - } - - base.VisitAttribute(attribute); - } - - public override void VisitTag(AXmlTag tag) - { - if (tag.IsComment) { - StringBuilder sb = new StringBuilder(); - - foreach(AXmlText text in tag.Children.OfType()) { - sb.Append(text.Value); - } - - string value = sb.ToString(); - - foreach (string commentTag in lexerTags) { - if (value.Contains(commentTag)) { - CompilationUnit.TagComments.Add(new TagComment(value, CreateRegion(tag.StartOffset, tag.EndOffset))); - break; - } - } - } - - base.VisitTag(tag); - } - - public override void VisitElement(AXmlElement element) - { - AXmlTag tag = element.Children.FirstOrDefault() as AXmlTag; - - if (tag != null && tag.IsStartOrEmptyTag) { - NodeWrapper node = new NodeWrapper() { - ElementName = element.LocalName, - StartOffset = element.StartOffset, - EndOffset = element.EndOffset, - Name = element.GetAttributeValue("Name") ?? element.GetAttributeValue(CompletionDataHelper.XamlNamespace, "Name"), - Children = new List() - }; - - if (CompilationUnit.TreeRootNode == null) { - CompilationUnit.TreeRootNode = node; - nodeStack.Push(CompilationUnit.TreeRootNode); - } else { - if (nodeStack.Count > 0) - nodeStack.Peek().Children.Add(node); - if (!tag.IsEmptyTag) - nodeStack.Push(node); - } - } - - base.VisitElement(element); - - if (tag != null && tag.IsStartTag) - nodeStack.PopOrDefault(); - } - - IClass AddClass(string className, AXmlElement element) { - if (projectContent.Language == LanguageProperties.VBNet && projectContent.Project is IProject) - className = ((IProject)projectContent.Project).RootNamespace + "." + className; - - DefaultClass c = new DefaultClass(CompilationUnit, className); - string modifierValue = (element.GetAttributeValue(CompletionDataHelper.XamlNamespace, "ClassModifier") ?? string.Empty).Trim(); - - c.Modifiers = ModifierEnum.Partial; - - string internalString = currentAmbience.ConvertAccessibility(ModifierEnum.Internal).Trim(); - - if (projectContent.Language.NameComparer.Compare(modifierValue, internalString) == 0) - c.Modifiers |= ModifierEnum.Internal; - else - c.Modifiers |= ModifierEnum.Public; - - c.Region = CreateRegion(element.StartOffset, element.EndOffset); - var baseType = TypeFromXmlNode(CompilationUnit, element); - if (baseType != null) - c.BaseTypes.Add(baseType); - CompilationUnit.Classes.Add(c); - - DefaultMethod initializeComponent = new DefaultMethod( - "InitializeComponent", - projectContent.SystemTypes.Void, - ModifierEnum.Public | ModifierEnum.Synthetic, c.Region, DomRegion.Empty, - c); - c.Methods.Add(initializeComponent); - - return c; - } - - DomRegion CreateRegion(int startOffset, int endOffset) - { - ICSharpCode.NRefactory.Location loc = Utils.GetLocationInfoFromOffset(fileContent, startOffset); - ICSharpCode.NRefactory.Location loc2 = Utils.GetLocationInfoFromOffset(fileContent, endOffset); - return new DomRegion(loc.Line, loc.Column, loc2.Line, loc2.Column); - } - - static IReturnType TypeFromXmlNode(XamlCompilationUnit cu, AXmlElement element) - { - return cu.CreateType(element.Namespace, element.LocalName); - } - } -} diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs deleted file mode 100644 index 6aec28a8c5..0000000000 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs +++ /dev/null @@ -1,1389 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Linq; -using System.Windows.Media; - -using ICSharpCode.AvalonEdit.Xml; -using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Editor; -using ICSharpCode.SharpDevelop.Editor.CodeCompletion; -using ICSharpCode.SharpDevelop.Project; - -namespace ICSharpCode.XamlBinding -{ - public static class CompletionDataHelper - { - static readonly List standardElements = new List { - new SpecialCompletionItem("!--"), - new SpecialCompletionItem("![CDATA["), - new SpecialCompletionItem("?") - }; - - // [XAML 2009] - static readonly List xamlBuiltInTypes = new List { - "Object", "Boolean", "Char", "String", "Decimal", "Single", "Double", - "Int16", "Int32", "Int64", "TimeSpan", "Uri", "Byte", "Array", "List", "Dictionary", - // This is no built in type, but a markup extension - "Reference" - }; - - static readonly List standardAttributes = new List { - new SpecialCompletionItem("xmlns:"), - new XamlCompletionItem("xml", "", "space"), - new XamlCompletionItem("xml", "", "lang") - }; - - public static readonly ReadOnlyCollection XamlNamespaceAttributes = new List { - "Class", "ClassModifier", "FieldModifier", "Name", "Subclass", "TypeArguments", "Uid", "Key" - }.AsReadOnly(); - - public static readonly ReadOnlyCollection RootOnlyElements = new List { - "Class", "ClassModifier", "Subclass" - }.AsReadOnly(); - - public static readonly ReadOnlyCollection ChildOnlyElements = new List { - "FieldModifier" - }.AsReadOnly(); - - static readonly List emptyList = new List(); - - /// - /// value: http://schemas.microsoft.com/winfx/2006/xaml - /// - public const string XamlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml"; - - /// - /// values: http://schemas.microsoft.com/winfx/2006/xaml/presentation, - /// http://schemas.microsoft.com/netfx/2007/xaml/presentation - /// - public static readonly string[] WpfXamlNamespaces = new[] { - "http://schemas.microsoft.com/winfx/2006/xaml/presentation", - "http://schemas.microsoft.com/netfx/2007/xaml/presentation" - }; - - /// - /// value: http://schemas.openxmlformats.org/markup-compatibility/2006 - /// - public const string MarkupCompatibilityNamespace = "http://schemas.openxmlformats.org/markup-compatibility/2006"; - - public const bool EnableXaml2009 = true; - - public static XamlContext ResolveContext(string text, string fileName, int offset) - { - return ResolveContext(new StringTextBuffer(text), fileName, offset); - } - - public static XamlContext ResolveContext(ITextBuffer fileContent, string fileName, int offset) - { - //using (new DebugTimerObject("ResolveContext")) { - XamlParser parser = string.IsNullOrEmpty(fileName) ? new XamlParser() : ParserService.GetParser(fileName) as XamlParser; - ParseInformation info = string.IsNullOrEmpty(fileName) ? null : ParserService.GetParseInformation(fileName); - - using (parser.ParseAndLock(fileContent)) { - - AXmlDocument document = parser.LastDocument; - AXmlObject currentData = document.GetChildAtOffset(offset); - - string attribute = string.Empty, attributeValue = string.Empty; - bool inAttributeValue = false; - AttributeValue value = null; - bool isRoot = false; - bool wasAXmlElement = false; - int offsetFromValueStart = -1; - - List ancestors = new List(); - Dictionary xmlns = new Dictionary(); - List ignored = new List(); - string xamlNamespacePrefix = string.Empty; - - var item = currentData; - - while (item != document) { - if (item is AXmlElement) { - AXmlElement element = item as AXmlElement; - ancestors.Add(element); - foreach (var attr in element.Attributes) { - if (attr.IsNamespaceDeclaration) { - string prefix = (attr.Name == "xmlns") ? "" : attr.LocalName; - if (!xmlns.ContainsKey(prefix)) - xmlns.Add(prefix, attr.Value); - } - - if (attr.LocalName == "Ignorable" && attr.Namespace == MarkupCompatibilityNamespace) - ignored.AddRange(attr.Value.Split(' ', '\t')); - - if (string.IsNullOrEmpty(xamlNamespacePrefix) && attr.Value == XamlNamespace) - xamlNamespacePrefix = attr.LocalName; - } - - if (!wasAXmlElement && item.Parent is AXmlDocument) - isRoot = true; - - wasAXmlElement = true; - } - - item = item.Parent; - } - - XamlContextDescription description = XamlContextDescription.None; - - AXmlElement active = null; - AXmlElement parent = null; - - if (currentData.Parent is AXmlTag) { - AXmlTag tag = currentData.Parent as AXmlTag; - if (tag.IsStartOrEmptyTag) - description = XamlContextDescription.InTag; - else if (tag.IsComment) - description = XamlContextDescription.InComment; - else if (tag.IsCData) - description = XamlContextDescription.InCData; - active = tag.Parent as AXmlElement; - } - - if (currentData is AXmlAttribute) { - AXmlAttribute a = currentData as AXmlAttribute; - int valueStartOffset = a.StartOffset + (a.Name ?? "").Length + (a.EqualsSign ?? "").Length + 1; - attribute = a.Name; - attributeValue = a.Value; - value = MarkupExtensionParser.ParseValue(attributeValue); - - inAttributeValue = offset >= valueStartOffset && offset < a.EndOffset; - if (inAttributeValue) { - offsetFromValueStart = offset - valueStartOffset; - - description = XamlContextDescription.InAttributeValue; - - if (value != null && !value.IsString) - description = XamlContextDescription.InMarkupExtension; - if (attributeValue.StartsWith("{}", StringComparison.Ordinal) && attributeValue.Length > 2) - description = XamlContextDescription.InAttributeValue; - } else - description = XamlContextDescription.InTag; - } - - if (currentData is AXmlTag) { - AXmlTag tag = currentData as AXmlTag; - if (tag.IsStartOrEmptyTag || tag.IsEndTag) - description = XamlContextDescription.AtTag; - else if (tag.IsComment) - description = XamlContextDescription.InComment; - else if (tag.IsCData) - description = XamlContextDescription.InCData; - active = tag.Parent as AXmlElement; - } - - if (active != ancestors.FirstOrDefault()) - parent = ancestors.FirstOrDefault(); - else - parent = ancestors.Skip(1).FirstOrDefault(); - - if (active == null) - active = parent; - - var xAttribute = currentData as AXmlAttribute; - - var context = new XamlContext() { - Description = description, - ActiveElement = (active == null) ? null : active.ToWrapper(), - ParentElement = (parent == null) ? null : parent.ToWrapper(), - Ancestors = ancestors.Select(ancestor => ancestor.ToWrapper()).ToList(), - Attribute = (xAttribute != null) ? xAttribute.ToWrapper() : null, - InRoot = isRoot, - AttributeValue = value, - RawAttributeValue = attributeValue, - ValueStartOffset = offsetFromValueStart, - XmlnsDefinitions = xmlns, - ParseInformation = info, - IgnoredXmlns = ignored.AsReadOnly(), - XamlNamespacePrefix = xamlNamespacePrefix - }; - - return context; - } - //} - } - - public static XamlCompletionContext ResolveCompletionContext(ITextEditor editor, char typedValue) - { - var binding = editor.GetService(typeof(XamlLanguageBinding)) as XamlLanguageBinding; - - if (binding == null) - throw new InvalidOperationException("Can only use ResolveCompletionContext with a XamlLanguageBinding."); - - var context = new XamlCompletionContext(ResolveContext(editor.Document.CreateSnapshot(), editor.FileName, editor.Caret.Offset)) { - PressedKey = typedValue, - Editor = editor - }; - - return context; - } - - public static XamlCompletionContext ResolveCompletionContext(ITextEditor editor, char typedValue, int offset) - { - var binding = editor.GetService(typeof(XamlLanguageBinding)) as XamlLanguageBinding; - - if (binding == null) - throw new InvalidOperationException("Can only use ResolveCompletionContext with a XamlLanguageBinding."); - - var context = new XamlCompletionContext(ResolveContext(editor.Document.CreateSnapshot(), editor.FileName, offset)) { - PressedKey = typedValue, - Editor = editor - }; - - return context; - } - - static List CreateAttributeList(XamlCompletionContext context, bool includeEvents) - { - ElementWrapper lastElement = context.ActiveElement; - if (context.ParseInformation == null) - return emptyList; - XamlCompilationUnit cu = context.ParseInformation.CompilationUnit as XamlCompilationUnit; - if (cu == null) - return emptyList; - IReturnType rt = cu.CreateType(lastElement.Namespace, lastElement.LocalName.Trim('.')); - - var list = new List(); - - string xamlPrefix = context.XamlNamespacePrefix; - string xKey = string.IsNullOrEmpty(xamlPrefix) ? "" : xamlPrefix + ":"; - - if (xamlBuiltInTypes.Concat(XamlNamespaceAttributes).Select(s => xKey + s).Contains(lastElement.Name)) - return emptyList; - - if (lastElement.LocalName.EndsWith(".", StringComparison.OrdinalIgnoreCase) || context.PressedKey == '.') { - if (rt == null) - return list; - - string key = string.IsNullOrEmpty(lastElement.Prefix) ? "" : lastElement.Prefix + ":"; - - if (context.ParentElement != null && context.ParentElement.LocalName.StartsWith(lastElement.LocalName.TrimEnd('.'), StringComparison.OrdinalIgnoreCase)) { - AddAttributes(rt, list, includeEvents); - AddAttachedProperties(rt.GetUnderlyingClass(), list, key, lastElement.Name.Trim('.')); - } else - AddAttachedProperties(rt.GetUnderlyingClass(), list, key, lastElement.Name.Trim('.')); - } else { - if (rt == null) { - list.Add(new XamlCompletionItem(xamlPrefix, XamlNamespace, "Uid")); - } else { - AddAttributes(rt, list, includeEvents); - list.AddRange(GetListOfAttached(context, string.Empty, string.Empty, includeEvents, true)); - foreach (string item in XamlNamespaceAttributes.Where(item => AllowedInElement(context.InRoot, item))) - list.Add(new XamlCompletionItem(xamlPrefix, XamlNamespace, item)); - } - } - - return list; - } - - static void AddAttributes(IReturnType rt, IList list, bool includeEvents) - { - if (rt == null) - return; - - foreach (IProperty p in rt.GetProperties()) { - if (p.IsPublic && (p.IsPubliclySetable() || p.ReturnType.IsCollectionReturnType())) - list.Add(new XamlCodeCompletionItem(p)); - } - - if (includeEvents) { - foreach (IEvent e in rt.GetEvents()) { - if (e.IsPublic) { - list.Add(new XamlCodeCompletionItem(e)); - } - } - } - } - - static bool AllowedInElement(bool inRoot, string item) - { - return inRoot ? !ChildOnlyElements.Contains(item) : !RootOnlyElements.Contains(item); - } - - public static IEnumerable CreateListForXmlnsCompletion(IProjectContent projectContent) - { - List list = new List(); - - foreach (IProjectContent content in projectContent.ReferencedContents) { - foreach (IAttribute att in content.GetAssemblyAttributes()) { - if (att.PositionalArguments.Count == 2 - && att.AttributeType.FullyQualifiedName == "System.Windows.Markup.XmlnsDefinitionAttribute") { - list.Add(new XmlnsCompletionItem(att.PositionalArguments[0] as string, true)); - } - } - - foreach (string @namespace in content.NamespaceNames) { - if (!string.IsNullOrEmpty(@namespace)) - list.Add(new XmlnsCompletionItem(@namespace, content.AssemblyName)); - } - } - - foreach (string @namespace in projectContent.NamespaceNames) { - if (!string.IsNullOrEmpty(@namespace)) - list.Add(new XmlnsCompletionItem(@namespace, false)); - } - - list.Add(new XmlnsCompletionItem(MarkupCompatibilityNamespace, true)); - - return list - .Distinct(new XmlnsEqualityComparer()) - .OrderBy(item => item, new XmlnsComparer()); - } - - static string GetContentPropertyName(IReturnType type) - { - if (type == null) - return string.Empty; - - IClass c = type.GetUnderlyingClass(); - - if (c == null) - return string.Empty; - - IAttribute contentProperty = c.Attributes - .FirstOrDefault(attribute => attribute.AttributeType.FullyQualifiedName == "System.Windows.Markup.ContentPropertyAttribute"); - if (contentProperty != null) { - return contentProperty.PositionalArguments.FirstOrDefault() as string - ?? (contentProperty.NamedArguments.ContainsKey("Name") ? contentProperty.NamedArguments["Name"] as string : string.Empty); - } - - return string.Empty; - } - - public static IList CreateElementList(XamlCompletionContext context, bool classesOnly, bool includeAbstract) - { - var items = GetClassesFromContext(context); - var result = new List(); - 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; - } - - public static IEnumerable GetAllTypes(XamlCompletionContext context) - { - var items = GetClassesFromContext(context); - - foreach (var ns in items) { - foreach (var c in ns.Value) { - if (c.ClassType == ClassType.Class && !c.DerivesFrom("System.Attribute")) - yield return new XamlCodeCompletionItem(c, ns.Key); - } - } - } - - public static IEnumerable CreateListOfMarkupExtensions(XamlCompletionContext context) - { - var list = CreateElementList(context, true, false); - - var neededItems = list.OfType() - .Where(i => (i.Entity as IClass).DerivesFrom("System.Windows.Markup.MarkupExtension")); - foreach (XamlCodeCompletionItem it in neededItems) { - string text = it.Text; - if (it.Text.EndsWith("Extension", StringComparison.Ordinal)) - text = text.Remove(it.Text.Length - "Extension".Length); - it.Text = text; - } - - return neededItems.Cast().Add(new XamlCompletionItem(context.XamlNamespacePrefix, XamlNamespace, "Reference")); - } - - public static XamlCompletionItemList CreateListForContext(XamlCompletionContext context) - { - XamlCompletionItemList list = new XamlCompletionItemList(context); - - ParseInformation info = context.ParseInformation; - ITextEditor editor = context.Editor; - - switch (context.Description) { - case XamlContextDescription.None: - if (context.Forced) { - list.Items.AddRange(standardElements); - list.Items.AddRange(CreateElementList(context, false, false)); - AddClosingTagCompletion(context, list); - } - break; - case XamlContextDescription.AtTag: - if ((editor.Caret.Offset > 0 && editor.Document.GetCharAt(editor.Caret.Offset - 1) == '.') || context.PressedKey == '.') { - list.Items.AddRange(CreateAttributeList(context, false)); - } else { - list.Items.AddRange(standardElements); - list.Items.AddRange(CreateElementList(context, false, false)); - AddClosingTagCompletion(context, list); - } - break; - case XamlContextDescription.InTag: - DebugTimer.Start(); - - string word = context.Editor.GetWordBeforeCaretExtended(); - - if (context.PressedKey == '.' || word.Contains(".")) { - string ns = ""; - int pos = word.IndexOf(':'); - if (pos > -1) - ns = word.Substring(0, pos); - - string element = word.Substring(pos + 1, word.Length - pos - 1); - string className = word; - int propertyStart = element.IndexOf('.'); - if (propertyStart != -1) { - element = element.Substring(0, propertyStart).TrimEnd('.'); - className = className.Substring(0, propertyStart + pos + 1).TrimEnd('.'); - } - TypeResolveResult trr = XamlResolver.Resolve(className, context) as TypeResolveResult; - IClass typeClass = (trr != null && trr.ResolvedType != null) ? trr.ResolvedType.GetUnderlyingClass() : null; - - if (typeClass != null && typeClass.HasAttached(true, true)) - list.Items.AddRange(GetListOfAttached(context, element, ns, true, true)); - } else { - QualifiedNameWithLocation last = context.ActiveElement.ToQualifiedName(); - TypeResolveResult trr = XamlResolver.Resolve(last.Name, context) as TypeResolveResult; - IClass typeClass = (trr != null && trr.ResolvedType != null) ? trr.ResolvedType.GetUnderlyingClass() : null; - list.Items.AddRange(CreateAttributeList(context, true)); - list.Items.AddRange(standardAttributes); - } - - DebugTimer.Stop("CreateListForContext - InTag"); - break; - case XamlContextDescription.InAttributeValue: - new XamlCodeCompletionBinding().CtrlSpace(editor); - break; - } - - list.SortItems(); - - return list; - } - - static void AddClosingTagCompletion(XamlCompletionContext context, XamlCompletionItemList list) - { - if (context.ParentElement != null && !context.InRoot) { - ResolveResult rr = XamlResolver.Resolve(context.ParentElement.Name, context); - TypeResolveResult trr = rr as TypeResolveResult; - MemberResolveResult mrr = rr as MemberResolveResult; - - if (trr != null) { - if (trr.ResolvedClass == null) - return; - list.Items.Add(new XamlCodeCompletionItem("/" + context.ParentElement.Name, trr.ResolvedClass)); - } else if (mrr != null) { - if (mrr.ResolvedMember == null) - return; - list.Items.Add(new XamlCodeCompletionItem("/" + context.ParentElement.Name, mrr.ResolvedMember)); - } - } - } - - public static IEnumerable CreateMarkupExtensionInsight(XamlCompletionContext context) - { - var markup = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset); - var type = ResolveType(markup.ExtensionType, context) ?? ResolveType(markup.ExtensionType + "Extension", context); - - if (type != null) { - var ctors = type.GetMethods() - .Where(m => m.IsPublic && m.IsConstructor && m.Parameters.Count >= markup.PositionalArguments.Count) - .OrderBy(m => m.Parameters.Count); - - foreach (var ctor in ctors) - yield return new MarkupExtensionInsightItem(ctor); - } - } - - public static ICompletionItemList CreateMarkupExtensionCompletion(XamlCompletionContext context) - { - var list = new XamlCompletionItemList(context); - string visibleValue = context.RawAttributeValue.Substring(0, Utils.MinMax(context.ValueStartOffset, 0, context.RawAttributeValue.Length)); - if (context.PressedKey == '=') - visibleValue += "="; -// context.RawAttributeValue = visibleValue; -// context.AttributeValue = MarkupExtensionParser.ParseValue(visibleValue); - var markup = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset); - var type = ResolveType(markup.ExtensionType, context) ?? ResolveType(markup.ExtensionType + "Extension", context); - - if (type == null) { - list.Items.AddRange(CreateListOfMarkupExtensions(context)); - list.PreselectionLength = markup.ExtensionType.Length; - } else { - if (markup.NamedArguments.Count == 0) { - if (DoPositionalArgsCompletion(list, context, markup, type)) - DoNamedArgsCompletion(list, context, type, markup); - } else - DoNamedArgsCompletion(list, context, type, markup); - } - - list.SortItems(); - - return list; - } - - static void DoNamedArgsCompletion(XamlCompletionItemList list, XamlCompletionContext context, IReturnType type, MarkupExtensionInfo markup) - { - if (markup.NamedArguments.Count > 0 && !context.Editor.GetWordBeforeCaret().StartsWith(",", StringComparison.OrdinalIgnoreCase)) { - int lastStart = markup.NamedArguments.Max(i => i.Value.StartOffset); - var item = markup.NamedArguments.First(p => p.Value.StartOffset == lastStart); - - if (context.RawAttributeValue.EndsWith("=", StringComparison.OrdinalIgnoreCase) || - (item.Value.IsString && item.Value.StringValue.EndsWith(context.Editor.GetWordBeforeCaretExtended(), StringComparison.Ordinal))) { - MemberResolveResult mrr = XamlResolver.ResolveMember(item.Key, context) as MemberResolveResult; - if (mrr != null && mrr.ResolvedMember != null && mrr.ResolvedMember.ReturnType != null) { - IReturnType memberType = mrr.ResolvedMember.ReturnType; - list.Items.AddRange(MemberCompletion(context, memberType, string.Empty)); - } - return; - } - } - - list.Items.AddRange(type.GetProperties().Where(p => p.CanSet && p.IsPublic).Select(p => new XamlCodeCompletionItem(p.Name + "=", p))); - } - - /// returns true if elements from named args completion should be added afterwards. - static bool DoPositionalArgsCompletion(XamlCompletionItemList list, XamlCompletionContext context, MarkupExtensionInfo markup, IReturnType type) - { - switch (type.FullyQualifiedName) { - case "System.Windows.Markup.ArrayExtension": - case "System.Windows.Markup.NullExtension": - // x:Null/x:Array does not need completion, ignore it - break; - case "System.Windows.Markup.StaticExtension": - if (context.AttributeValue.ExtensionValue.PositionalArguments.Count <= 1) - return DoStaticExtensionCompletion(list, context); - break; - case "System.Windows.Markup.TypeExtension": - if (context.AttributeValue.ExtensionValue.PositionalArguments.Count <= 1) { - list.Items.AddRange(GetClassesFromContext(context).FlattenToList()); - AttributeValue selItem = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset) - .PositionalArguments.LastOrDefault(); - string word = context.Editor.GetWordBeforeCaret().TrimEnd(); - if (selItem != null && selItem.IsString && word == selItem.StringValue) { - list.PreselectionLength = selItem.StringValue.Length; - } - } - break; - default: - var ctors = type.GetMethods() - .Where(m => m.IsPublic && m.IsConstructor && m.Parameters.Count >= markup.PositionalArguments.Count + 1); - if (context.Forced) - return true; - if (ctors.Any() || markup.PositionalArguments.Count == 0) - return false; - break; - } - - return true; - } - - static IEnumerable FlattenToList(this IDictionary> data) - { - foreach (var item in data) { - foreach (IClass c in item.Value) { - yield return new XamlCodeCompletionItem(c, item.Key); - } - } - } - - public static IEnumerable MemberInsight(MemberResolveResult result) - { - switch (result.ResolvedType.FullyQualifiedName) { - case "System.Windows.Thickness": - yield return new MemberInsightItem(result.ResolvedMember, "uniformLength"); - yield return new MemberInsightItem(result.ResolvedMember, "left, top"); - yield return new MemberInsightItem(result.ResolvedMember, "left, top, right, bottom"); - break; - case "System.Windows.Size": - yield return new MemberInsightItem(result.ResolvedMember, "width, height"); - break; - case "System.Windows.Point": - yield return new MemberInsightItem(result.ResolvedMember, "x, y"); - break; - case "System.Windows.Rect": - yield return new MemberInsightItem(result.ResolvedMember, "x, y, width, height"); - break; - } - } - - public static string LookForTargetTypeValue(XamlCompletionContext context, out bool isExplicit, params string[] elementName) { - var ancestors = context.Ancestors; - - isExplicit = false; - - for (int i = 0; i < ancestors.Count; i++) { - if (ancestors[i].LocalName == "Style" && WpfXamlNamespaces.Contains(ancestors[i].Namespace)) { - isExplicit = true; - return ancestors[i].GetAttributeValue("TargetType") ?? string.Empty; - } - - if (ancestors[i].Name.EndsWithAny(elementName.Select(s => "." + s + "s"), StringComparison.Ordinal) - && !ancestors[i].Name.StartsWith("Style.", StringComparison.Ordinal)) { - return ancestors[i].Name.Remove(ancestors[i].Name.IndexOf('.')); - } - } - - return null; - } - - public static string GetTypeNameFromTypeExtension(MarkupExtensionInfo info, XamlCompletionContext context) - { - IReturnType type = CompletionDataHelper.ResolveType(info.ExtensionType, context) - ?? CompletionDataHelper.ResolveType(info.ExtensionType + "Extension", context); - - if (type == null || type.FullyQualifiedName != "System.Windows.Markup.TypeExtension") - return string.Empty; - - var item = info.PositionalArguments.FirstOrDefault(); - if (item != null && item.IsString) { - return item.StringValue; - } else { - if (info.NamedArguments.TryGetValue("typename", out item)) { - if (item.IsString) - return item.StringValue; - } - } - - return string.Empty; - } - - public static bool EndsWithAny(this string thisValue, IEnumerable items, StringComparison comparison) - { - foreach (string item in items) { - if (thisValue.EndsWith(item, comparison)) - return true; - } - - return false; - } - - public static bool EndsWithAny(this string thisValue, params char[] items) - { - foreach (char item in items) { - if (thisValue.EndsWith(item.ToString())) - return true; - } - - return false; - } - - static IReturnType GetType(XamlCompletionContext context, out bool isExplicit) - { - AttributeValue value = MarkupExtensionParser.ParseValue(LookForTargetTypeValue(context, out isExplicit, "Trigger", "Setter") ?? string.Empty); - - IReturnType typeName = null; - string typeNameString = null; - - if (!value.IsString) { - typeNameString = GetTypeNameFromTypeExtension(value.ExtensionValue, context); - typeName = CompletionDataHelper.ResolveType(typeNameString, context); - } else { - typeNameString = value.StringValue; - typeName = CompletionDataHelper.ResolveType(value.StringValue, context); - } - - return typeName; - } - - public static IEnumerable MemberCompletion(XamlCompletionContext context, IReturnType type, string textPrefix) - { - if (type == null || type.GetUnderlyingClass() == null) - yield break; - - var c = type.GetUnderlyingClass(); - - if (type is ConstructedReturnType && type.TypeArgumentCount > 0 && c.FullyQualifiedName == "System.Nullable") { - ConstructedReturnType rt = type as ConstructedReturnType; - string nullExtensionName = "Null"; - if (!string.IsNullOrEmpty(context.XamlNamespacePrefix)) - nullExtensionName = context.XamlNamespacePrefix + ":" + nullExtensionName; - yield return new SpecialCompletionItem("{" + nullExtensionName + "}"); - c = rt.TypeArguments.First().GetUnderlyingClass(); - if (c == null) - yield break; - } - - bool isExplicit, showFull = false; - IReturnType typeName; - - string valueBeforeCaret = (context.ValueStartOffset > 0) ? - context.RawAttributeValue.Substring(0, context.ValueStartOffset) : ""; - - switch (c.ClassType) { - case ClassType.Class: - switch (c.FullyQualifiedName) { - case "System.String": - // return nothing - break; - case "System.Type": - foreach (var item in CreateElementList(context, true, true)) - yield return item; - break; - case "System.Windows.PropertyPath": - foreach (var item in CreatePropertyPathCompletion(context)) - yield return item; - break; - case "System.Windows.DependencyProperty": - typeName = GetType(context, out isExplicit); - - bool isReadOnly = context.ActiveElement.Name.EndsWith("Trigger"); - - if (!isExplicit && valueBeforeCaret.Contains(".")) - showFull = true; - - if (typeName != null) { - foreach (var item in typeName.GetDependencyProperties(true, !isExplicit, !isReadOnly, showFull)) - yield return item; - } - break; - case "System.Windows.RoutedEvent": - typeName = GetType(context, out isExplicit); - - if (!isExplicit && valueBeforeCaret.Contains(".")) - showFull = true; - - if (typeName != null) { - foreach (var item in typeName.GetRoutedEvents(true, !isExplicit, showFull)) - yield return item; - } - break; - case "System.Windows.Media.FontFamily": - foreach (var font in Fonts.SystemFontFamilies) - yield return new SpecialValueCompletionItem(font.FamilyNames.First().Value); - break; - default: - if (context.Description == XamlContextDescription.InMarkupExtension) { - foreach (IField f in c.Fields) - yield return new XamlCodeCompletionItem(textPrefix + f.Name, f); - foreach (IProperty p in c.Properties.Where(pr => pr.IsPublic && pr.IsStatic && pr.CanGet)) - yield return new XamlCodeCompletionItem(textPrefix + p.Name, p); - } - break; - } - break; - case ClassType.Enum: - foreach (IField f in c.Fields) - yield return new XamlCodeCompletionItem(textPrefix + f.Name, f); - foreach (IProperty p in c.Properties.Where(pr => pr.IsPublic && pr.IsStatic && pr.CanGet)) - yield return new XamlCodeCompletionItem(textPrefix + p.Name, p); - break; - case ClassType.Struct: - switch (c.FullyQualifiedName) { - case "System.Boolean": - yield return new SpecialValueCompletionItem("True"); - yield return new SpecialValueCompletionItem("False"); - break; - case "System.Windows.GridLength": - yield return new SpecialValueCompletionItem("Auto"); - yield return new SpecialValueCompletionItem("*"); - break; - } - break; - case ClassType.Delegate: - foreach (var item in CreateEventCompletion(context, c)) - yield return item; - break; - } - - var classes = c.ProjectContent.Classes.Where( - cla => (cla.FullyQualifiedName == c.FullyQualifiedName + "s" || - cla.FullyQualifiedName == c.FullyQualifiedName + "es")); - foreach (var coll in classes) { - foreach (var item in coll.Properties) - yield return new SpecialValueCompletionItem(item.Name); - foreach (var item in coll.Fields.Where(f => f.IsPublic && f.IsStatic && f.ReturnType.FullyQualifiedName == c.FullyQualifiedName)) - yield return new SpecialValueCompletionItem(item.Name); - } - } - - static IList CreatePropertyPathCompletion(XamlCompletionContext context) - { - bool isExplicit; - IReturnType typeName = GetType(context, out isExplicit); - IList list = new List(); - - string value = context.ValueStartOffset > -1 ? context.RawAttributeValue.Substring(0, Math.Min(context.ValueStartOffset + 1, context.RawAttributeValue.Length)) : ""; - - if (value.EndsWithAny(']', ')')) - return list; - - var segments = PropertyPathParser.Parse(value).ToList(); - - int completionStart; - bool isAtDot = false; - - IReturnType propertyPathType = ResolvePropertyPath(segments, context, typeName, out completionStart); - if (completionStart < segments.Count) { - PropertyPathSegment seg = segments[completionStart]; - switch (seg.Kind) { - case SegmentKind.ControlChar: - if (seg.Content == ".") { - AddAttributes(propertyPathType, list, false); - isAtDot = true; - } - break; - case SegmentKind.AttachedProperty: - AddAttributes(seg.Resolve(context, propertyPathType), list, false); - isAtDot = seg.Content.Contains("."); - break; - case SegmentKind.PropertyOrType: - AddAttributes(propertyPathType, list, false); - isAtDot = true; - break; - } - } else if (typeName != null) { - AddAttributes(typeName, list, false); - } - - if (!isAtDot) { - foreach (var item in GetAllTypes(context)) - list.Add(item); - } - - return list; - } - - static IReturnType ResolvePropertyPath(IList segments, XamlCompletionContext context, IReturnType parentType, out int lastIndex) - { - IReturnType type = parentType; - - for (lastIndex = 0; lastIndex < segments.Count - 1; lastIndex++) { - PropertyPathSegment segment = segments[lastIndex]; - switch (segment.Kind) { - case SegmentKind.AttachedProperty: - // do we need to take account of previous results? - type = segment.Resolve(context, null); - break; - case SegmentKind.ControlChar: - if (segment.Content == "[" || segment.Content == "(" || segment.Content == "/") - return null; - return type; - case SegmentKind.PropertyOrType: - type = segment.Resolve(context, type); - break; - case SegmentKind.Indexer: - if (type != null) { - IProperty prop = type.GetProperties().FirstOrDefault(p => p.IsIndexer); - if (prop != null) { - type = prop.ReturnType; - } - } - break; - case SegmentKind.SourceTraversal: - // ignore - return null; - } - } - - return type; - } - - static IReturnType Resolve(this PropertyPathSegment segment, XamlCompletionContext context, IReturnType previousType) - { - if (segment.Kind == SegmentKind.SourceTraversal) - return previousType; - if (segment.Kind == SegmentKind.ControlChar) - return previousType; - - string content = segment.Content; - - if (segment.Kind == SegmentKind.AttachedProperty && content.StartsWith("(")) { - content = content.TrimStart('('); - if (content.Contains(".")) - content = content.Remove(content.IndexOf('.')); - } - - XamlContextDescription tmp = context.Description; - context.Description = XamlContextDescription.InTag; - - ResolveResult rr = XamlResolver.Resolve(content, context); - IReturnType type = null; - - if (rr is TypeResolveResult) - type = (rr as TypeResolveResult).ResolvedType; - - if (previousType != null) { - IMember member = previousType.GetMemberByName(content); - if (member != null) - type = member.ReturnType; - } else { - if (rr is MemberResolveResult) { - MemberResolveResult mrr = rr as MemberResolveResult; - if (mrr.ResolvedMember != null) - type = mrr.ResolvedMember.ReturnType; - } - if (rr is TypeResolveResult) - type = (rr as TypeResolveResult).ResolvedType; - } - - context.Description = tmp; - return type; - } - - static IMember GetMemberByName(this IReturnType type, string name) - { - if (type == null) - throw new ArgumentNullException("type"); - - foreach (IMember member in type.GetFields()) { - if (member.Name == name) - return member; - } - - foreach (IMember member in type.GetProperties()) { - if (member.Name == name) - return member; - } - - return null; - } - - static IEnumerable CreateEventCompletion(XamlCompletionContext context, IClass c) - { - IMethod invoker = c.Methods.Where(method => method.Name == "Invoke").FirstOrDefault(); - if (invoker != null && context.ActiveElement != null) { - var item = context.ActiveElement; - var evt = ResolveAttribute(context.Attribute.ToQualifiedName(), context) as IEvent; - if (evt == null) - return Enumerable.Empty(); - - int offset = XmlEditor.XmlParser.GetActiveElementStartIndex(context.Editor.Document.Text, context.Editor.Caret.Offset); - - if (offset == -1) - return Enumerable.Empty(); - - var loc = context.Editor.Document.OffsetToPosition(offset); - - string name = context.ActiveElement.GetAttributeValue("Name"); - if (string.IsNullOrEmpty(name)) - name = context.ActiveElement.GetAttributeValue(XamlNamespace, "Name"); - - IList list = new List(); - list.Add(new NewEventCompletionItem(evt, (string.IsNullOrEmpty(name) ? item.Name : name))); - - return CompletionDataHelper.AddMatchingEventHandlers(context, invoker).Concat(list); - } - - return Enumerable.Empty(); - } - - static IMember ResolveAttribute(QualifiedNameWithLocation attribute, XamlCompletionContext context) - { - if (attribute == null) - return null; - - return ResolveAttribute(attribute.FullXmlName, context); - } - - static IMember ResolveAttribute(string attribute, XamlCompletionContext context) - { - MemberResolveResult mrr = XamlResolver.Resolve(attribute, context) as MemberResolveResult; - - if (mrr == null) - return null; - - return mrr.ResolvedMember; - } - - static bool DoStaticExtensionCompletion(XamlCompletionItemList list, XamlCompletionContext context) - { - AttributeValue selItem = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset) - .PositionalArguments.LastOrDefault(); - if (context.PressedKey == '.') { - if (selItem != null && selItem.IsString) { - var rr = XamlResolver.Resolve(selItem.StringValue, context) as TypeResolveResult; - if (rr != null) - list.Items.AddRange(MemberCompletion(context, rr.ResolvedType, string.Empty)); - return false; - } - } else { - if (selItem != null && selItem.IsString) { - int index = selItem.StringValue.IndexOf('.'); - string s = (index > -1) ? selItem.StringValue.Substring(0, index) : selItem.StringValue; - var rr = XamlResolver.Resolve(s, context) as TypeResolveResult; - if (rr != null) { - list.Items.AddRange(MemberCompletion(context, rr.ResolvedType, (index == -1) ? "." : string.Empty)); - - list.PreselectionLength = (index > -1) ? selItem.StringValue.Length - index - 1 : 0; - - return false; - } else - DoStaticTypeCompletion(selItem, list, context); - } else { - DoStaticTypeCompletion(selItem, list, context); - } - } - - return true; - } - - static void DoStaticTypeCompletion(AttributeValue selItem, XamlCompletionItemList list, XamlCompletionContext context) - { - var items = GetClassesFromContext(context); - foreach (var ns in items) { - list.Items.AddRange(ns.Value.Where(c => c.Fields.Any(f => f.IsStatic) || c.Properties.Any(p => p.IsStatic)) - .Select(c => new XamlCodeCompletionItem(c, ns.Key))); - } - if (selItem != null && selItem.IsString) { - list.PreselectionLength = selItem.StringValue.Length; - } - } - - public static IReturnType ResolveType(string typeName, XamlContext context) - { - if (context.ParseInformation == null) - return null; - - XamlCompilationUnit cu = context.ParseInformation.CompilationUnit as XamlCompilationUnit; - if (cu == null) - return null; - string prefix = ""; - int len = typeName.IndexOf(':'); - string name = typeName; - if (len > 0) { - prefix = typeName.Substring(0, len); - name = typeName.Substring(len + 1, name.Length - len - 1); - } - string namespaceName = ""; - if (context.XmlnsDefinitions.TryGetValue(prefix, out namespaceName)) { - IReturnType rt = cu.CreateType(namespaceName, name); - if (rt != null && rt.GetUnderlyingClass() != null) - return rt; - } - return null; - } - - public static IEnumerable AddMatchingEventHandlers(XamlCompletionContext context, IMethod delegateInvoker) - { - if (context.ParseInformation == null) - yield break; - - var unit = context.ParseInformation.CompilationUnit; - var loc = context.Editor.Caret.Position; - IClass c = unit.GetInnermostClass(loc.Line, loc.Column); - if (c == null) - yield break; - CompoundClass compound = c.GetCompoundClass() as CompoundClass; - if (compound != null) { - foreach (IClass part in compound.Parts) { - foreach (IMethod m in part.Methods) { - if (m.Parameters.Count != delegateInvoker.Parameters.Count) - continue; - - if ((m.ReturnType != null && delegateInvoker.ReturnType != null) && m.ReturnType.DotNetName != delegateInvoker.ReturnType.DotNetName) - continue; - - bool equal = m.Parameters.SequenceEqual(delegateInvoker.Parameters, new ParameterComparer()); - if (equal) { - yield return new XamlCodeCompletionItem(m); - } - } - } - } - } - - public static bool Compare(this IParameter p1, IParameter p2) - { - return (p1.ReturnType.DotNetName == p2.ReturnType.DotNetName) && - (p1.IsOut == p2.IsOut) && (p1.IsParams == p2.IsParams) && (p1.IsRef == p2.IsRef); - } - - static IDictionary> GetClassesFromContext(XamlCompletionContext context) - { - var result = new Dictionary>(); - - if (context.ParseInformation == null) - return result; - - IProjectContent pc = context.ProjectContent; - - foreach (var ns in context.XmlnsDefinitions) { - result.Add(ns.Key, XamlCompilationUnit.GetNamespaceMembers(pc, ns.Value)); - } - - return result; - } - - public static bool IsPubliclySetable(this IProperty thisValue) - { - return thisValue.CanSet && - (thisValue.SetterModifiers == ModifierEnum.None || - (thisValue.SetterModifiers & ModifierEnum.Public) == ModifierEnum.Public); - } - - public static IEnumerable GetDependencyProperties(this IReturnType type, bool excludeSuffix, bool addType, bool requiresSetable, bool showFull) - { - foreach (var field in type.GetFields()) { - if (field.ReturnType.FullyQualifiedName != "System.Windows.DependencyProperty") - continue; - if (field.Name.Length <= "Property".Length || !field.Name.EndsWith("Property", StringComparison.Ordinal)) - continue; - string fieldName = field.Name.Remove(field.Name.Length - "Property".Length); - IProperty property = type.GetProperties().FirstOrDefault(p => p.Name == fieldName); - if (property == null) - continue; - if (requiresSetable && !property.IsPubliclySetable()) - continue; - - if (!excludeSuffix) - fieldName = field.Name; - - if (showFull) { - addType = false; - - fieldName = field.DeclaringType.Name + "." + fieldName; - } - - yield return new XamlLazyValueCompletionItem(field, fieldName, addType); - } - } - - public static IEnumerable GetRoutedEvents(this IReturnType type, bool excludeSuffix, bool addType, bool showFull) - { - foreach (var field in type.GetFields()) { - if (field.ReturnType.FullyQualifiedName != "System.Windows.RoutedEvent") - continue; - if (field.Name.Length <= "Event".Length || !field.Name.EndsWith("Event", StringComparison.Ordinal)) - continue; - string fieldName = field.Name.Remove(field.Name.Length - "Event".Length); - if (!type.GetEvents().Any(p => p.Name == fieldName)) - continue; - - if (!excludeSuffix) - fieldName = field.Name; - - if (showFull) { - addType = false; - - fieldName = field.DeclaringType.Name + "." + fieldName; - } - - yield return new XamlLazyValueCompletionItem(field, fieldName, addType); - } - } - - internal static List GetListOfAttached(XamlCompletionContext context, string prefixClassName, string prefixNamespace, bool events, bool properties) - { - List result = new List(); - - if (context.ParseInformation == null) - return result; - - IProjectContent pc = context.ProjectContent; - - if (!string.IsNullOrEmpty(prefixClassName)) { - var ns = context.XmlnsDefinitions[prefixNamespace]; - IClass c = XamlCompilationUnit.GetNamespaceMembers(pc, ns).FirstOrDefault(item => item.Name == prefixClassName); - if (c != null && c.ClassType == ClassType.Class) { - if (!c.ClassInheritanceTree.Any(b => b.FullyQualifiedName == "System.Attribute")) { - prefixNamespace = string.IsNullOrEmpty(prefixNamespace) ? prefixNamespace : prefixNamespace + ":"; - if (properties) - AddAttachedProperties(c, result, prefixNamespace, prefixNamespace + prefixClassName); - if (events) - AddAttachedEvents(c, result, prefixNamespace, prefixNamespace + prefixClassName); - } - } - } else { - foreach (var ns in context.XmlnsDefinitions) { - string key = string.IsNullOrEmpty(ns.Key) ? "" : ns.Key + ":"; - - foreach (IClass c in XamlCompilationUnit.GetNamespaceMembers(pc, ns.Value)) { - if (c.ClassType != ClassType.Class) - continue; - if (c.HasAttached(properties, events)) - result.Add(new XamlCodeCompletionItem(c, ns.Key)); - } - } - } - - return result; - } - - public static void AddAttachedProperties(IClass c, List result, string key, string prefix) - { - if (c == null) - return; - - var attachedProperties = c.Fields.Where(f => f.IsAttached(true, false)); - - int prefixLength = (prefix.Length > 0) ? prefix.Length + 1 : 0; - - result.AddRange( - attachedProperties.Select( - item => { - string property = item.Name.Remove(item.Name.Length - "Property".Length); - string name = key + c.Name + "." + item.Name.Remove(item.Name.Length - "Property".Length); - return new XamlCodeCompletionItem(name.Remove(0, prefixLength), new DefaultProperty(c, property) { ReturnType = GetAttachedPropertyType(item, c) }); - } - ) - ); - } - - static void AddAttachedEvents(IClass c, List result, string key, string prefix) - { - var attachedEvents = c.Fields.Where(f => f.IsAttached(false, true)); - - int prefixLength = (prefix.Length > 0) ? prefix.Length + 1 : 0; - - result.AddRange( - attachedEvents.Select( - item => { - string @event = item.Name.Remove(item.Name.Length - "Event".Length); - string name = key + c.Name + "." + item.Name.Remove(item.Name.Length - "Event".Length); - return new XamlCodeCompletionItem(name.Remove(0, prefixLength), new DefaultEvent(c, @event) { ReturnType = GetAttachedEventDelegateType(item, c) }); - } - ) - ); - } - - static IReturnType GetAttachedEventDelegateType(IField field, IClass c) - { - if (c == null || field == null) - return null; - - string eventName = field.Name.Remove(field.Name.Length - "Event".Length); - - IMethod method = c.Methods - .Where(m => - m.IsPublic && - m.IsStatic && - m.Parameters.Count == 2 && - (m.Name == "Add" + eventName + "Handler" || - m.Name == "Remove" + eventName + "Handler")) - .FirstOrDefault(); - - if (method == null) - return null; - - return method.Parameters[1].ReturnType; - } - - static IReturnType GetAttachedPropertyType(IField field, IClass c) - { - if (c == null || field == null) - return null; - - string propertyName = field.Name.Remove(field.Name.Length - "Property".Length); - - IMethod method = c.Methods - .Where(m => - m.IsPublic && - m.IsStatic && - m.Name == "Get" + propertyName) - .FirstOrDefault(); - - if (method == null) - return null; - - return method.ReturnType; - } - - static string GetEventNameFromMethod(IMethod m) - { - string mName = m.Name; - if (mName.StartsWith("Add", StringComparison.Ordinal)) - mName = mName.Remove(0, 3); - else if (mName.StartsWith("Remove", StringComparison.Ordinal)) - mName = mName.Remove(0, 6); - if (mName.EndsWith("Handler", StringComparison.Ordinal)) - mName = mName.Remove(mName.Length - "Handler".Length); - - return mName; - } - - static string GetEventNameFromField(IField f) - { - string fName = f.Name; - if (fName.EndsWith("Event", StringComparison.Ordinal)) - fName = fName.Remove(fName.Length - "Event".Length); - - return fName; - } - - static bool IsMethodFromEvent(IField f, IMethod m) - { - return GetEventNameFromField(f) == GetEventNameFromMethod(m); - } - } -} diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs index c6c143bc2d..ce0e830715 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs @@ -12,10 +12,11 @@ using System.Xml; using System.Xml.Linq; using ICSharpCode.AvalonEdit.Document; -using ICSharpCode.AvalonEdit.Xml; using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.Editor; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.Xml; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor.CodeCompletion; using ICSharpCode.XmlEditor; @@ -161,8 +162,9 @@ namespace ICSharpCode.XamlBinding public static string GetWordBeforeCaretExtended(this ITextEditor editor) { IDocumentLine line = editor.Document.GetLine(editor.Caret.Line); - int index = Math.Min(editor.Caret.Column - 1, line.Text.Length); - string text = line.Text.Substring(0, index); + string lineText = editor.Document.GetText(line); + int index = Math.Min(editor.Caret.Column - 1, lineText.Length); + string text = lineText.Substring(0, index); int startIndex = text.LastIndexOfAny(' ', '\t', '"', '=', '<', '\'', '>', '{', '}'); if (startIndex > -1) return text.Substring(startIndex + 1); @@ -236,12 +238,12 @@ namespace ICSharpCode.XamlBinding return thisValue.LinePosition; } - public static Location GetLocation(this IXmlLineInfo thisValue) + public static TextLocation GetLocation(this IXmlLineInfo thisValue) { - return new Location(thisValue.GetLinePosition(), thisValue.GetLineNumber()); + return new TextLocation(thisValue.GetLinePosition(), thisValue.GetLineNumber()); } - public static bool IsInRange(this IXmlLineInfo item, Location begin, Location end) + public static bool IsInRange(this IXmlLineInfo item, TextLocation begin, TextLocation end) { return IsInRange(item, begin.Line, begin.Column, end.Line, end.Column); } @@ -261,41 +263,21 @@ namespace ICSharpCode.XamlBinding return false; } - public static bool IsCollectionType(this IClass thisValue) + public static bool IsCollectionType(this IType thisValue) { if (thisValue == null) throw new ArgumentNullException("thisValue"); - return thisValue.ClassInheritanceTree.Any(cla => cla.FullyQualifiedName == "System.Collections.ICollection"); + return thisValue.GetAllBaseTypeDefinitions().Any(t => t.FullName == "System.Collections.ICollection"); } - public static bool IsCollectionReturnType(this IReturnType type) - { - if (type == null) - throw new ArgumentNullException("type"); - if (type.GetUnderlyingClass() != null) - return type.GetUnderlyingClass().IsCollectionType(); - - return false; - } - - public static bool IsListType(this IClass thisValue) + public static bool IsListType(this IType thisValue) { if (thisValue == null) throw new ArgumentNullException("thisValue"); - return thisValue.ClassInheritanceTree.Any(cla => cla.FullyQualifiedName == "System.Collections.IList"); + return thisValue.GetAllBaseTypeDefinitions().Any(t => t.FullName == "System.Collections.IList"); } - public static bool IsListReturnType(this IReturnType type) - { - if (type == null) - throw new ArgumentNullException("type"); - if (type.GetUnderlyingClass() != null) - return type.GetUnderlyingClass().IsListType(); - - return false; - } - - public static bool HasAttached(this IClass thisValue, bool lookForProperties, bool lookForEvents) + public static bool HasAttached(this ITypeDefinition thisValue, bool lookForProperties, bool lookForEvents) { if (!lookForProperties && !lookForEvents) return false; @@ -310,12 +292,12 @@ namespace ICSharpCode.XamlBinding public static bool IsAttached(this IField field, bool lookForProperties, bool lookForEvents) { - if (!field.IsPublic || !field.IsStatic || !field.IsReadonly || field.ReturnType == null) + if (!field.IsPublic || !field.IsStatic || !field.IsReadOnly || field.ReturnType == null) return false; bool foundMethod = false; - if (lookForProperties && field.ReturnType.FullyQualifiedName == "System.Windows.DependencyProperty") { + if (lookForProperties && field.ReturnType.FullName == "System.Windows.DependencyProperty") { if (field.Name.Length <= "Property".Length) return false; if (!field.Name.EndsWith("Property", StringComparison.Ordinal)) @@ -323,7 +305,7 @@ namespace ICSharpCode.XamlBinding string fieldName = field.Name.Remove(field.Name.Length - "Property".Length); - foreach (IMethod method in field.DeclaringType.Methods) { + foreach (IMethod method in field.DeclaringTypeDefinition.Methods) { if (!method.IsPublic || !method.IsStatic || method.Name.Length <= 3) continue; if (!method.Name.StartsWith("Get") && !method.Name.StartsWith("Set")) @@ -334,7 +316,7 @@ namespace ICSharpCode.XamlBinding } } - if (lookForEvents && !foundMethod && field.ReturnType.FullyQualifiedName == "System.Windows.RoutedEvent") { + if (lookForEvents && !foundMethod && field.ReturnType.FullName == "System.Windows.RoutedEvent") { if (field.Name.Length <= "Event".Length) return false; if (!field.Name.EndsWith("Event", StringComparison.Ordinal)) @@ -347,9 +329,10 @@ namespace ICSharpCode.XamlBinding } /// Works only if fullyQualifiedClassName is the name of a class! - public static bool DerivesFrom(this IClass myClass, string fullyQualifiedClassName) + public static bool DerivesFrom(this ITypeDefinition myClass, string fullyQualifiedClassName) { - return myClass.ClassInheritanceTreeClassesOnly.Any(c => c.FullyQualifiedName == fullyQualifiedClassName); +// return myClass.ClassInheritanceTreeClassesOnly.Any(c => c.FullyQualifiedName == fullyQualifiedClassName); + return false; } public static T PopOrDefault(this Stack stack) diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/MarkupExtensionInfo.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/MarkupExtensionInfo.cs index 86ecf6ce28..1f0ee134e5 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/MarkupExtensionInfo.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/MarkupExtensionInfo.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Linq; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.XmlEditor; using System.Text; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/CodeCompletion.xaml.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/CodeCompletion.xaml.cs index 1052405c37..9ed1a2cac6 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/CodeCompletion.xaml.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/CodeCompletion.xaml.cs @@ -28,7 +28,7 @@ namespace ICSharpCode.XamlBinding.Options public override bool SaveOptions() { if (base.SaveOptions()) { - XamlColorizer.RefreshAll(); +// XamlColorizer.RefreshAll(); return true; } diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs index 56d58f05cb..7ed1637669 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs @@ -69,12 +69,12 @@ namespace ICSharpCode.XamlBinding return offset + col; } - public static Location GetLocationInfoFromOffset(string text, int offset) + public static TextLocation GetLocationInfoFromOffset(string text, int offset) { string[] lines = text.Substring(0, MinMax(offset, 0, text.Length)).Split('\n'); string line = lines.LastOrDefault() ?? string.Empty; - return new Location(line.Length + 1, lines.Length); + return new TextLocation(line.Length + 1, lines.Length); } /// diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBehavior.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBehavior.cs index 1b260f1257..168dd01882 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBehavior.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBehavior.cs @@ -7,11 +7,11 @@ using System.IO; using System.Linq; using ICSharpCode.AvalonEdit.Document; -using ICSharpCode.AvalonEdit.Xml; using ICSharpCode.Core; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.SharpDevelop.Refactoring; namespace ICSharpCode.XamlBinding { @@ -24,6 +24,11 @@ namespace ICSharpCode.XamlBinding return base.GetDefaultItemType(fileName); } + + public override ISymbolSearch PrepareSymbolSearch(IEntity entity) + { + return new XamlSymbolSearch(entity); + } } public class SilverlightBehavior : ProjectBehavior diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj index 5df30af413..f11520dbdd 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj @@ -64,17 +64,17 @@ + + Always Properties\GlobalAssemblyInfo.cs - - @@ -87,41 +87,6 @@ Code - - - - - - - - - - - EditGridColumnsAndRowsDialog.xaml - Code - - - ExtractPropertiesAsStyleDialog.xaml - Code - - - FieldEditor.xaml - Code - - - GridLengthEditor.xaml - Code - - - SelectSourceClassDialog.xaml - Code - - - SourceClassFormEditor.xaml - Code - - - @@ -131,17 +96,11 @@ - - - - - - @@ -151,7 +110,16 @@ - + + {DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6} + ICSharpCode.NRefactory.Xml + False + + + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} + ICSharpCode.NRefactory + False + {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} NRefactory @@ -177,11 +145,6 @@ ICSharpCode.Core.Presentation False - - {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} - ICSharpCode.SharpDevelop.Dom - False - {8035765F-D51F-4A0C-A746-2FD100E19419} ICSharpCode.SharpDevelop.Widgets @@ -204,19 +167,10 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlClassReturnType.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlClassReturnType.cs deleted file mode 100644 index e0daf64963..0000000000 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlClassReturnType.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using ICSharpCode.SharpDevelop.Dom; - -namespace ICSharpCode.XamlBinding -{ - /// - /// IReturnType that gets created by XamlCompilationUnit.CreateType and will - /// run XamlCompilationUnit.FindType on demand. - /// - public class XamlClassReturnType : ProxyReturnType - { - XamlCompilationUnit compilationUnit; - string xmlNamespace; - string className; - - public XamlClassReturnType(XamlCompilationUnit compilationUnit, string xmlNamespace, string className) - { - if (compilationUnit == null) - throw new ArgumentNullException("compilationUnit"); - - this.compilationUnit = compilationUnit; - this.xmlNamespace = xmlNamespace; - this.className = className ?? ""; - } - - public override IReturnType BaseType - { - get - { - return compilationUnit.FindType(xmlNamespace, className); - } - } - - public override string Name - { - get { return className; } - } - } -} diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCodeCompletionBinding.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCodeCompletionBinding.cs index 2a884b04b2..6dbc05051b 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCodeCompletionBinding.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCodeCompletionBinding.cs @@ -4,7 +4,7 @@ using ICSharpCode.XmlEditor; using System; using System.Linq; -using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor.CodeCompletion; @@ -16,384 +16,389 @@ namespace ICSharpCode.XamlBinding public CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch) { - XamlCompletionContext context = CompletionDataHelper.ResolveCompletionContext(editor, ch); - XamlCompletionItemList list; - - if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData) - return CodeCompletionKeyPressResult.None; - - switch (ch) { - case '<': - context.Description = (context.Description == XamlContextDescription.None) ? XamlContextDescription.AtTag : context.Description; - list = CompletionDataHelper.CreateListForContext(context); - editor.ShowCompletionWindow(list); - return CodeCompletionKeyPressResult.Completed; - case '>': - return CodeCompletionKeyPressResult.None; - case '\'': - case '"': - if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) { - // count all " or ' chars before the next > char - int search = editor.Caret.Offset + 1; - int endMarkerCount = 1; - char curCh = editor.Document.GetCharAt(search); - while (search < editor.Document.TextLength - 1 && curCh != '>') { - if (curCh == ch) - endMarkerCount++; - search++; - curCh = editor.Document.GetCharAt(search); - } - // if the count is odd we need to add an additional " or ' char - if (endMarkerCount % 2 != 0) { - editor.Document.Insert(editor.Caret.Offset, ch.ToString()); - editor.Caret.Offset--; - this.CtrlSpace(editor); - return CodeCompletionKeyPressResult.Completed; - } - } - break; - case '{': // starting point for Markup Extension Completion - if (context.Attribute != null - && XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset) - && !(context.RawAttributeValue.StartsWith("{}", StringComparison.OrdinalIgnoreCase) && context.RawAttributeValue.Length != 2)) { - - if (editor.SelectionLength != 0) - editor.Document.Remove(editor.SelectionStart, editor.SelectionLength); - - editor.Document.Insert(editor.Caret.Offset, "{}"); - editor.Caret.Offset--; - - this.CtrlSpace(editor); - return CodeCompletionKeyPressResult.EatKey; - } - break; - case '.': - switch (context.Description) { - case XamlContextDescription.AtTag: - case XamlContextDescription.InTag: - if (context.ActiveElement != null && !XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) { - list = CompletionDataHelper.CreateListForContext(context); - editor.ShowCompletionWindow(list); - return CodeCompletionKeyPressResult.Completed; - } - break; - case XamlContextDescription.InMarkupExtension: - if (DoMarkupExtensionCompletion(context)) - return CodeCompletionKeyPressResult.Completed; - break; - case XamlContextDescription.InAttributeValue: - if (editor.SelectionLength != 0) - editor.Document.Remove(editor.SelectionStart, editor.SelectionLength); - - editor.Document.Insert(editor.Caret.Offset, "."); - - this.CtrlSpace(editor); - return CodeCompletionKeyPressResult.EatKey; - } - break; - case '(': - case '[': - if (context.Description == XamlContextDescription.InAttributeValue) { - if (editor.SelectionLength != 0) - editor.Document.Remove(editor.SelectionStart, editor.SelectionLength); - - if (ch == '(') - editor.Document.Insert(editor.Caret.Offset, "()"); - if (ch == '[') - editor.Document.Insert(editor.Caret.Offset, "[]"); - editor.Caret.Offset--; - - this.CtrlSpace(editor); - return CodeCompletionKeyPressResult.EatKey; - } - break; - case ':': - if (context.ActiveElement != null && XmlParser.GetQualifiedAttributeNameAtIndex(editor.Document.Text, editor.Caret.Offset) == null) { - if (context.Attribute != null && !context.Attribute.Name.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase)) { - list = CompletionDataHelper.CreateListForContext(context); - list.PreselectionLength = editor.GetWordBeforeCaretExtended().Length; - editor.ShowCompletionWindow(list); - return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion; - } - } - break; - case '/': // ignore '/' when trying to type '/>' - return CodeCompletionKeyPressResult.None; - case '=': - if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) { - int searchOffset = editor.Caret.Offset; - - if (editor.SelectionLength != 0) - editor.Document.Remove(editor.SelectionStart, editor.SelectionLength); - - while (searchOffset < editor.Document.TextLength - 1) { - searchOffset++; - if (!char.IsWhiteSpace(editor.Document.GetCharAt(searchOffset))) - break; - } - - if (searchOffset >= editor.Document.TextLength || editor.Document.GetCharAt(searchOffset) != '"') { - editor.Document.Insert(editor.Caret.Offset, "=\"\""); - editor.Caret.Offset--; - } else { - editor.Document.Insert(editor.Caret.Offset, "="); - editor.Caret.Offset++; - } - - this.CtrlSpace(editor); - return CodeCompletionKeyPressResult.EatKey; - } else { - DoMarkupExtensionCompletion(context); - return CodeCompletionKeyPressResult.Completed; - } - default: - if (context.Description != XamlContextDescription.None && !char.IsWhiteSpace(ch)) { - string starter = editor.GetWordBeforeCaretExtended(); - if (!string.IsNullOrEmpty(starter)) - return CodeCompletionKeyPressResult.None; - trackForced = false; - - string attributeName = (context.Attribute != null) ? context.Attribute.Name : string.Empty; - - if (!attributeName.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase)) { - return this.CtrlSpace(editor) - ? CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion - : CodeCompletionKeyPressResult.None; - } - trackForced = true; - return CodeCompletionKeyPressResult.None; - } - break; - } - +// XamlCompletionContext context = CompletionDataHelper.ResolveCompletionContext(editor, ch); +// XamlCompletionItemList list; +// +// if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData) +// return CodeCompletionKeyPressResult.None; +// +// switch (ch) { +// case '<': +// context.Description = (context.Description == XamlContextDescription.None) ? XamlContextDescription.AtTag : context.Description; +// list = CompletionDataHelper.CreateListForContext(context); +// editor.ShowCompletionWindow(list); +// return CodeCompletionKeyPressResult.Completed; +// case '>': +// return CodeCompletionKeyPressResult.None; +// case '\'': +// case '"': +// if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) { +// // count all " or ' chars before the next > char +// int search = editor.Caret.Offset + 1; +// int endMarkerCount = 1; +// char curCh = editor.Document.GetCharAt(search); +// while (search < editor.Document.TextLength - 1 && curCh != '>') { +// if (curCh == ch) +// endMarkerCount++; +// search++; +// curCh = editor.Document.GetCharAt(search); +// } +// // if the count is odd we need to add an additional " or ' char +// if (endMarkerCount % 2 != 0) { +// editor.Document.Insert(editor.Caret.Offset, ch.ToString()); +// editor.Caret.Offset--; +// this.CtrlSpace(editor); +// return CodeCompletionKeyPressResult.Completed; +// } +// } +// break; +// case '{': // starting point for Markup Extension Completion +// if (context.Attribute != null +// && XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset) +// && !(context.RawAttributeValue.StartsWith("{}", StringComparison.OrdinalIgnoreCase) && context.RawAttributeValue.Length != 2)) { +// +// if (editor.SelectionLength != 0) +// editor.Document.Remove(editor.SelectionStart, editor.SelectionLength); +// +// editor.Document.Insert(editor.Caret.Offset, "{}"); +// editor.Caret.Offset--; +// +// this.CtrlSpace(editor); +// return CodeCompletionKeyPressResult.EatKey; +// } +// break; +// case '.': +// switch (context.Description) { +// case XamlContextDescription.AtTag: +// case XamlContextDescription.InTag: +// if (context.ActiveElement != null && !XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) { +// list = CompletionDataHelper.CreateListForContext(context); +// editor.ShowCompletionWindow(list); +// return CodeCompletionKeyPressResult.Completed; +// } +// break; +// case XamlContextDescription.InMarkupExtension: +//// if (DoMarkupExtensionCompletion(context)) +//// return CodeCompletionKeyPressResult.Completed; +// break; +// case XamlContextDescription.InAttributeValue: +// if (editor.SelectionLength != 0) +// editor.Document.Remove(editor.SelectionStart, editor.SelectionLength); +// +// editor.Document.Insert(editor.Caret.Offset, "."); +// +// this.CtrlSpace(editor); +// return CodeCompletionKeyPressResult.EatKey; +// } +// break; +// case '(': +// case '[': +// if (context.Description == XamlContextDescription.InAttributeValue) { +// if (editor.SelectionLength != 0) +// editor.Document.Remove(editor.SelectionStart, editor.SelectionLength); +// +// if (ch == '(') +// editor.Document.Insert(editor.Caret.Offset, "()"); +// if (ch == '[') +// editor.Document.Insert(editor.Caret.Offset, "[]"); +// editor.Caret.Offset--; +// +// this.CtrlSpace(editor); +// return CodeCompletionKeyPressResult.EatKey; +// } +// break; +// case ':': +// if (context.ActiveElement != null && XmlParser.GetQualifiedAttributeNameAtIndex(editor.Document.Text, editor.Caret.Offset) == null) { +// if (context.Attribute != null && !context.Attribute.Name.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase)) { +// list = CompletionDataHelper.CreateListForContext(context); +// list.PreselectionLength = editor.GetWordBeforeCaretExtended().Length; +// editor.ShowCompletionWindow(list); +// return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion; +// } +// } +// break; +// case '/': // ignore '/' when trying to type '/>' +// return CodeCompletionKeyPressResult.None; +// case '=': +// if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) { +// int searchOffset = editor.Caret.Offset; +// +// if (editor.SelectionLength != 0) +// editor.Document.Remove(editor.SelectionStart, editor.SelectionLength); +// +// while (searchOffset < editor.Document.TextLength - 1) { +// searchOffset++; +// if (!char.IsWhiteSpace(editor.Document.GetCharAt(searchOffset))) +// break; +// } +// +// if (searchOffset >= editor.Document.TextLength || editor.Document.GetCharAt(searchOffset) != '"') { +// editor.Document.Insert(editor.Caret.Offset, "=\"\""); +// editor.Caret.Offset--; +// } else { +// editor.Document.Insert(editor.Caret.Offset, "="); +// editor.Caret.Offset++; +// } +// +// this.CtrlSpace(editor); +// return CodeCompletionKeyPressResult.EatKey; +// } else { +//// DoMarkupExtensionCompletion(context); +// return CodeCompletionKeyPressResult.Completed; +// } +// default: +// if (context.Description != XamlContextDescription.None && !char.IsWhiteSpace(ch)) { +// string starter = editor.GetWordBeforeCaretExtended(); +// if (!string.IsNullOrEmpty(starter)) +// return CodeCompletionKeyPressResult.None; +// trackForced = false; +// +// string attributeName = (context.Attribute != null) ? context.Attribute.Name : string.Empty; +// +// if (!attributeName.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase)) { +// return this.CtrlSpace(editor) +// ? CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion +// : CodeCompletionKeyPressResult.None; +// } +// trackForced = true; +// return CodeCompletionKeyPressResult.None; +// } +// break; +// } +// return CodeCompletionKeyPressResult.None; } public bool CtrlSpace(ITextEditor editor) { - XamlCompletionContext context = CompletionDataHelper.ResolveCompletionContext(editor, ' '); - context.Forced = trackForced; - - if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData) - return false; - - if (context.ActiveElement != null) { - if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset) && context.Description != XamlContextDescription.InAttributeValue) { - XamlCompletionItemList list = CompletionDataHelper.CreateListForContext(context); - string starter = editor.GetWordBeforeCaretExtended().TrimStart('/'); - if (context.Description != XamlContextDescription.None && !string.IsNullOrEmpty(starter)) { - if (starter.Contains(".")) - list.PreselectionLength = starter.Length - starter.IndexOf('.') - 1; - else - list.PreselectionLength = starter.Length; - } - editor.ShowCompletionWindow(list); - return true; - } else { - // DO NOT USE CompletionDataHelper.CreateListForContext here!!! results in endless recursion!!!! - if (context.Attribute != null) { - if (!DoMarkupExtensionCompletion(context)) { - var completionList = new XamlCompletionItemList(context); - completionList.PreselectionLength = editor.GetWordBeforeCaretExtended().Length; - - if ((context.ActiveElement.Name == "Setter" || context.ActiveElement.Name == "EventSetter") && - (context.Attribute.Name == "Property" || context.Attribute.Name == "Value")) - DoSetterAndEventSetterCompletion(context, completionList); - else if ((context.ActiveElement.Name.EndsWith("Trigger") || context.ActiveElement.Name == "Condition") && context.Attribute.Name == "Value") - DoTriggerCompletion(context, completionList); - else { - if (context.Attribute.Name == "xml:space") { - completionList.Items.AddRange(new[] { new SpecialCompletionItem("preserve"), - new SpecialCompletionItem("default") }); - } - - var mrr = XamlResolver.Resolve(context.Attribute.Name, context) as MemberResolveResult; - if (mrr != null && mrr.ResolvedType != null) { - completionList.Items.AddRange(CompletionDataHelper.MemberCompletion(context, mrr.ResolvedType, string.Empty)); - editor.ShowInsightWindow(CompletionDataHelper.MemberInsight(mrr)); - if (mrr.ResolvedType.FullyQualifiedName == "System.Windows.PropertyPath") { - string start = editor.GetWordBeforeCaretExtended(); - int index = start.LastIndexOfAny(PropertyPathTokenizer.ControlChars); - if (index + 1 < start.Length) - start = start.Substring(index + 1); - else - start = ""; - completionList.PreselectionLength = start.Length; - } else if (mrr.ResolvedType.FullyQualifiedName == "System.Windows.Media.FontFamily") { - string text = context.ValueStartOffset > -1 ? context.RawAttributeValue.Substring(0, Math.Min(context.ValueStartOffset, context.RawAttributeValue.Length)) : ""; - int lastComma = text.LastIndexOf(','); - completionList.PreselectionLength = lastComma == -1 ? context.ValueStartOffset : context.ValueStartOffset - lastComma - 1; - } - } - } - - completionList.SortItems(); - - if (context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) || - context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase)) - completionList.Items.AddRange(CompletionDataHelper.CreateListForXmlnsCompletion(context.ProjectContent)); - - ICompletionListWindow window = editor.ShowCompletionWindow(completionList); - - if ((context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) || - context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase)) && window != null) - window.Width = 400; - - return completionList.Items.Any(); - } - return true; - } - } - } +// XamlCompletionContext context = CompletionDataHelper.ResolveCompletionContext(editor, ' '); +// context.Forced = trackForced; +// +// if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData) +// return false; +// +// if (context.ActiveElement != null) { +// if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset) && context.Description != XamlContextDescription.InAttributeValue) { +// XamlCompletionItemList list = CompletionDataHelper.CreateListForContext(context); +// string starter = editor.GetWordBeforeCaretExtended().TrimStart('/'); +// if (context.Description != XamlContextDescription.None && !string.IsNullOrEmpty(starter)) { +// if (starter.Contains(".")) +// list.PreselectionLength = starter.Length - starter.IndexOf('.') - 1; +// else +// list.PreselectionLength = starter.Length; +// } +// editor.ShowCompletionWindow(list); +// return true; +// } else { +// // DO NOT USE CompletionDataHelper.CreateListForContext here!!! results in endless recursion!!!! +// if (context.Attribute != null) { +// if (!DoMarkupExtensionCompletion(context)) { +// var completionList = new XamlCompletionItemList(context); +// completionList.PreselectionLength = editor.GetWordBeforeCaretExtended().Length; +// +// if ((context.ActiveElement.Name == "Setter" || context.ActiveElement.Name == "EventSetter") && +// (context.Attribute.Name == "Property" || context.Attribute.Name == "Value")) +// DoSetterAndEventSetterCompletion(context, completionList); +// else if ((context.ActiveElement.Name.EndsWith("Trigger") || context.ActiveElement.Name == "Condition") && context.Attribute.Name == "Value") +// DoTriggerCompletion(context, completionList); +// else { +// if (context.Attribute.Name == "xml:space") { +// completionList.Items.AddRange(new[] { new SpecialCompletionItem("preserve"), +// new SpecialCompletionItem("default") }); +// } +// +// var mrr = XamlResolver.Resolve(context.Attribute.Name, context) as MemberResolveResult; +// if (mrr != null && mrr.ResolvedType != null) { +// completionList.Items.AddRange(CompletionDataHelper.MemberCompletion(context, mrr.ResolvedType, string.Empty)); +// editor.ShowInsightWindow(CompletionDataHelper.MemberInsight(mrr)); +// if (mrr.ResolvedType.FullyQualifiedName == "System.Windows.PropertyPath") { +// string start = editor.GetWordBeforeCaretExtended(); +// int index = start.LastIndexOfAny(PropertyPathTokenizer.ControlChars); +// if (index + 1 < start.Length) +// start = start.Substring(index + 1); +// else +// start = ""; +// completionList.PreselectionLength = start.Length; +// } else if (mrr.ResolvedType.FullyQualifiedName == "System.Windows.Media.FontFamily") { +// string text = context.ValueStartOffset > -1 ? context.RawAttributeValue.Substring(0, Math.Min(context.ValueStartOffset, context.RawAttributeValue.Length)) : ""; +// int lastComma = text.LastIndexOf(','); +// completionList.PreselectionLength = lastComma == -1 ? context.ValueStartOffset : context.ValueStartOffset - lastComma - 1; +// } +// } +// } +// +// completionList.SortItems(); +// +// if (context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) || +// context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase)) +// completionList.Items.AddRange(CompletionDataHelper.CreateListForXmlnsCompletion(context.ProjectContent)); +// +// ICompletionListWindow window = editor.ShowCompletionWindow(completionList); +// +// if ((context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) || +// context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase)) && window != null) +// window.Width = 400; +// +// return completionList.Items.Any(); +// } +// return true; +// } +// } +// } return false; } - static void DoTriggerCompletion(XamlCompletionContext context, XamlCompletionItemList completionList) { - bool isExplicit; - AttributeValue value = MarkupExtensionParser.ParseValue(CompletionDataHelper.LookForTargetTypeValue(context, out isExplicit, "Trigger") ?? string.Empty); - - IReturnType typeName = null; - string typeNameString = null; - - if (!value.IsString) { - typeNameString = CompletionDataHelper.GetTypeNameFromTypeExtension(value.ExtensionValue, context); - typeName = CompletionDataHelper.ResolveType(typeNameString, context); - } else { - typeNameString = value.StringValue; - typeName = CompletionDataHelper.ResolveType(value.StringValue, context); - } - - if (typeName != null) { - switch (context.Attribute.Name) { - case "Value": - AttributeValue propType = MarkupExtensionParser.ParseValue(context.ActiveElement.GetAttributeValue("Property") ?? ""); - if (!propType.IsString) - break; - - string name = propType.StringValue; - - if (!name.Contains(".")) - name = typeNameString + "." + name; - - context.Description = XamlContextDescription.AtTag; - - var member = XamlResolver.Resolve(name, context) as MemberResolveResult; - - if (member == null || member.ResolvedMember == null) - break; - - completionList.Items.AddRange( - CompletionDataHelper.MemberCompletion(context, member.ResolvedMember.ReturnType, string.Empty) - ); - break; - } - } - } +// static void DoTriggerCompletion(XamlCompletionContext context, XamlCompletionItemList completionList) { +// bool isExplicit; +// AttributeValue value = MarkupExtensionParser.ParseValue(CompletionDataHelper.LookForTargetTypeValue(context, out isExplicit, "Trigger") ?? string.Empty); +// +// IType typeName = null; +// string typeNameString = null; +// +// if (!value.IsString) { +// typeNameString = CompletionDataHelper.GetTypeNameFromTypeExtension(value.ExtensionValue, context); +// typeName = CompletionDataHelper.ResolveType(typeNameString, context); +// } else { +// typeNameString = value.StringValue; +// typeName = CompletionDataHelper.ResolveType(value.StringValue, context); +// } +// +// if (typeName != null) { +// switch (context.Attribute.Name) { +// case "Value": +// AttributeValue propType = MarkupExtensionParser.ParseValue(context.ActiveElement.GetAttributeValue("Property") ?? ""); +// if (!propType.IsString) +// break; +// +// string name = propType.StringValue; +// +// if (!name.Contains(".")) +// name = typeNameString + "." + name; +// +// context.Description = XamlContextDescription.AtTag; +// +// var member = XamlResolver.Resolve(name, context) as MemberResolveResult; +// +// if (member == null || member.ResolvedMember == null) +// break; +// +// completionList.Items.AddRange( +// CompletionDataHelper.MemberCompletion(context, member.ResolvedMember.ReturnType, string.Empty) +// ); +// break; +// } +// } +// } +// +// static void DoSetterAndEventSetterCompletion(XamlCompletionContext context, XamlCompletionItemList completionList) { +// bool isExplicit; +// string element = context.ParentElement.Name.EndsWith("Trigger") ? "Trigger" : context.ParentElement.Name; +// AttributeValue value = MarkupExtensionParser.ParseValue(CompletionDataHelper.LookForTargetTypeValue(context, out isExplicit, element) ?? string.Empty); +// +// IType typeName = null; +// string typeNameString = null; +// +// if (!value.IsString) { +// typeNameString = CompletionDataHelper.GetTypeNameFromTypeExtension(value.ExtensionValue, context); +// typeName = CompletionDataHelper.ResolveType(typeNameString, context); +// } else { +// typeNameString = value.StringValue; +// typeName = CompletionDataHelper.ResolveType(value.StringValue, context); +// } +// +// if (typeName != null) { +// switch (context.Attribute.Name) { +// case "Value": +// AttributeValue propType = MarkupExtensionParser.ParseValue(context.ActiveElement.GetAttributeValue("Property") ?? ""); +// +// if (!propType.IsString) +// break; +// +// context.Description = XamlContextDescription.AtTag; +// +// string name = propType.StringValue; +// +// if (!name.Contains(".")) +// name = typeNameString + "." + name; +// +// var member = XamlResolver.Resolve(name, context) as MemberResolveResult; +// +// if (member == null || member.ResolvedMember == null) +// break; +// +// completionList.Items.AddRange( +// CompletionDataHelper.MemberCompletion(context, member.ResolvedMember.ReturnType, string.Empty) +// ); +// break; +// case "Property": +// completionList.Items.AddRange( +// typeName.GetProperties() +// .Where(p => p.IsPublic && p.CanSet) +// .Select(prop => new XamlCodeCompletionItem(prop)) +// ); +// break; +// case "Event": +// completionList.Items.AddRange( +// typeName.GetEvents() +// .Where(e => e.IsPublic) +// .Select(evt => new XamlCodeCompletionItem(evt)) +// ); +// break; +// case "Handler": +// var loc3 = context.Editor.Document.OffsetToPosition(XmlParser.GetActiveElementStartIndex(context.Editor.Document.Text, context.Editor.Caret.Offset)); +// AttributeValue evtType = MarkupExtensionParser.ParseValue(context.ActiveElement.GetAttributeValue("Event") ?? ""); +// if (!evtType.IsString) +// break; +// +// string evtName = evtType.StringValue; +// +// if (!evtName.Contains(".")) +// evtName = typeNameString + "." + evtName; +// +// var evtMember = XamlResolver.Resolve(evtName, context) as MemberResolveResult; +// +// if (evtMember == null || evtMember.ResolvedMember == null || !(evtMember.ResolvedMember is IEvent) || evtMember.ResolvedMember.ReturnType == null) +// break; +// +// IClass c = (evtMember.ResolvedMember as IEvent).ReturnType.GetUnderlyingClass(); +// +// if (c == null) +// break; +// +// IMethod invoker = c.Methods.FirstOrDefault(m => m.Name == "Invoke"); +// +// if (invoker == null) +// break; +// +// completionList.Items.AddRange( +// CompletionDataHelper.AddMatchingEventHandlers(context, invoker).Add(new NewEventCompletionItem(evtMember.ResolvedMember as IEvent, typeName.Name)) +// ); +// break; +// } +// } +// } +// +// static bool DoMarkupExtensionCompletion(XamlCompletionContext context) +// { +// if (context.Description == XamlContextDescription.InMarkupExtension && context.AttributeValue != null && !context.AttributeValue.IsString) { +// if (!XamlBindingOptions.UseExtensionCompletion) +// return false; +// XamlCompletionItemList completionList = CompletionDataHelper.CreateMarkupExtensionCompletion(context) as XamlCompletionItemList; +// string word = context.Editor.GetWordBeforeCaretExtended(); +// if (context.PressedKey != '.' && context.PressedKey != '=' && !word.EndsWith(".") && completionList.PreselectionLength == 0) +// completionList.PreselectionLength = word.Length; +// var insightList = CompletionDataHelper.CreateMarkupExtensionInsight(context); +// context.Editor.ShowInsightWindow(insightList); +// context.Editor.ShowCompletionWindow(completionList); +// return completionList.Items.Any() || insightList.Any(); +// } +// +// return false; +// } - static void DoSetterAndEventSetterCompletion(XamlCompletionContext context, XamlCompletionItemList completionList) { - bool isExplicit; - string element = context.ParentElement.Name.EndsWith("Trigger") ? "Trigger" : context.ParentElement.Name; - AttributeValue value = MarkupExtensionParser.ParseValue(CompletionDataHelper.LookForTargetTypeValue(context, out isExplicit, element) ?? string.Empty); - - IReturnType typeName = null; - string typeNameString = null; - - if (!value.IsString) { - typeNameString = CompletionDataHelper.GetTypeNameFromTypeExtension(value.ExtensionValue, context); - typeName = CompletionDataHelper.ResolveType(typeNameString, context); - } else { - typeNameString = value.StringValue; - typeName = CompletionDataHelper.ResolveType(value.StringValue, context); - } - - if (typeName != null) { - switch (context.Attribute.Name) { - case "Value": - AttributeValue propType = MarkupExtensionParser.ParseValue(context.ActiveElement.GetAttributeValue("Property") ?? ""); - - if (!propType.IsString) - break; - - context.Description = XamlContextDescription.AtTag; - - string name = propType.StringValue; - - if (!name.Contains(".")) - name = typeNameString + "." + name; - - var member = XamlResolver.Resolve(name, context) as MemberResolveResult; - - if (member == null || member.ResolvedMember == null) - break; - - completionList.Items.AddRange( - CompletionDataHelper.MemberCompletion(context, member.ResolvedMember.ReturnType, string.Empty) - ); - break; - case "Property": - completionList.Items.AddRange( - typeName.GetProperties() - .Where(p => p.IsPublic && p.CanSet) - .Select(prop => new XamlCodeCompletionItem(prop)) - ); - break; - case "Event": - completionList.Items.AddRange( - typeName.GetEvents() - .Where(e => e.IsPublic) - .Select(evt => new XamlCodeCompletionItem(evt)) - ); - break; - case "Handler": - var loc3 = context.Editor.Document.OffsetToPosition(XmlParser.GetActiveElementStartIndex(context.Editor.Document.Text, context.Editor.Caret.Offset)); - AttributeValue evtType = MarkupExtensionParser.ParseValue(context.ActiveElement.GetAttributeValue("Event") ?? ""); - if (!evtType.IsString) - break; - - string evtName = evtType.StringValue; - - if (!evtName.Contains(".")) - evtName = typeNameString + "." + evtName; - - var evtMember = XamlResolver.Resolve(evtName, context) as MemberResolveResult; - - if (evtMember == null || evtMember.ResolvedMember == null || !(evtMember.ResolvedMember is IEvent) || evtMember.ResolvedMember.ReturnType == null) - break; - - IClass c = (evtMember.ResolvedMember as IEvent).ReturnType.GetUnderlyingClass(); - - if (c == null) - break; - - IMethod invoker = c.Methods.FirstOrDefault(m => m.Name == "Invoke"); - - if (invoker == null) - break; - - completionList.Items.AddRange( - CompletionDataHelper.AddMatchingEventHandlers(context, invoker).Add(new NewEventCompletionItem(evtMember.ResolvedMember as IEvent, typeName.Name)) - ); - break; - } - } - } - - static bool DoMarkupExtensionCompletion(XamlCompletionContext context) + public bool HandleKeyPressed(ITextEditor editor, char ch) { - if (context.Description == XamlContextDescription.InMarkupExtension && context.AttributeValue != null && !context.AttributeValue.IsString) { - if (!XamlBindingOptions.UseExtensionCompletion) - return false; - XamlCompletionItemList completionList = CompletionDataHelper.CreateMarkupExtensionCompletion(context) as XamlCompletionItemList; - string word = context.Editor.GetWordBeforeCaretExtended(); - if (context.PressedKey != '.' && context.PressedKey != '=' && !word.EndsWith(".") && completionList.PreselectionLength == 0) - completionList.PreselectionLength = word.Length; - var insightList = CompletionDataHelper.CreateMarkupExtensionInsight(context); - context.Editor.ShowInsightWindow(insightList); - context.Editor.ShowCompletionWindow(completionList); - return completionList.Items.Any() || insightList.Any(); - } - - return false; + throw new NotImplementedException(); } } } diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlColorizer.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlColorizer.cs deleted file mode 100644 index ce91c387b3..0000000000 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlColorizer.cs +++ /dev/null @@ -1,394 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using ICSharpCode.Core; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Windows.Threading; -using ICSharpCode.AvalonEdit.Document; -using ICSharpCode.AvalonEdit.Rendering; -using ICSharpCode.AvalonEdit.Xml; -using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Editor; -using ICSharpCode.SharpDevelop.Gui; -using ICSharpCode.XmlEditor; - -namespace ICSharpCode.XamlBinding -{ - using Task = System.Threading.Tasks.Task; - using Tasks = System.Threading.Tasks; - - public class XamlColorizer : DocumentColorizingTransformer, ILineTracker, IDisposable - { - public struct Highlight { - public IMember Member { get; set; } - public HighlightingInfo Info { get; set; } - } - - public sealed class HighlightTask { - // input - readonly string fileName; - readonly string lineText; - readonly int offset; - - TextView textView; - ITextBuffer snapshot; - - public HighlightTask(ITextEditor editor, DocumentLine currentLine, TextView textView) - { - this.fileName = editor.FileName; - this.textView = textView; - this.snapshot = editor.Document.CreateSnapshot(); - this.lineText = textView.Document.GetText(currentLine); - this.offset = currentLine.Offset; - this.task = new Task(Process); - } - - public HighlightTask(ITextEditor editor, DocumentLine currentLine, TextView textView, IList oldHighlightData) - : this(editor, currentLine, textView) - { - this.results = oldHighlightData; - } - - IList results; - - // output - public Highlight[] GetResults() - { - lock (this) { - if (results == null) - return null; - return results.ToArray(); - } - } - - readonly Task task; - - public void Start() - { - task.Start(); - } - - public bool CompletedSuccessfully { - get { - return task.IsCompleted && task.Status == Tasks.TaskStatus.RanToCompletion; - } - } - - public bool Invalid { get; set; } - - void Process() - { - try { - List results = new List(); - - foreach (HighlightingInfo info in GetInfo()) { - IMember member = null; - - // Commented out because task doesn't come with cancellation support in .NET 4.0 Beta 2 - // (use CancellationToken instead) - // I didn't have to remove any call to task.Cancel(), so apparently this was dead code. - //if (task.IsCancellationRequested) { - // task.AcknowledgeCancellation(); - // return; - //} - // TODO: implement cancellation support - - if (!info.Token.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase)) { - MemberResolveResult rr = XamlResolver.Resolve(info.Token, info.Context) as MemberResolveResult; - member = (rr != null) ? rr.ResolvedMember : null; - } - - results.Add(new Highlight() { Member = member, Info = info }); - } - - lock (this) - this.results = results; - - WorkbenchSingleton.SafeThreadAsyncCall(InvokeRedraw); - } catch (Exception e) { - WorkbenchSingleton.SafeThreadAsyncCall(() => MessageService.ShowException(e)); - } - } - - void InvokeRedraw() - { - task.Wait(); - textView.Redraw(this.offset, this.lineText.Length, DispatcherPriority.Background); - } - - IEnumerable GetInfo() - { - int index = -1; - XamlContext context = null; - - do { - if (index + 1 >= lineText.Length) - break; - - index = lineText.IndexOfAny(index + 1, '=', '.'); - if (index > -1) { - context = CompletionDataHelper.ResolveContext(snapshot, fileName, offset + index); - - if (context.ActiveElement == null || context.InAttributeValueOrMarkupExtension || context.InCommentOrCData) - continue; - - string propertyName; - string token; - int startIndex; - - switch (context.Description) { - case XamlContextDescription.AtTag: - token = context.ActiveElement.Name; - int propertyNameIndex = token.IndexOf('.'); - - if (propertyNameIndex == -1) - continue; - - propertyName = token.Substring(propertyNameIndex + 1); - startIndex = lineText.IndexOf(propertyName, index, StringComparison.Ordinal); - break; - case XamlContextDescription.InTag: - if (lineText[index] == '.' || context.Attribute == null) - continue; - - token = propertyName = context.Attribute.Name; - startIndex = lineText.LastIndexOf(propertyName, index, StringComparison.Ordinal); - break; - default: - continue; - } - - if (startIndex > -1) { - yield return new HighlightingInfo(token, startIndex, startIndex + propertyName.Length, offset, context); - } - } - } while (index > -1); - } - } - - Dictionary highlightCache = new Dictionary(); - - public ITextEditor Editor { get; set; } - - public AvalonEdit.Rendering.TextView TextView { get; set; } - - public XamlColorizer(ITextEditor editor, TextView textView) - { - this.Editor = editor; - this.TextView = textView; - - this.weakLineTracker = WeakLineTracker.Register(this.Editor.Document.GetService(typeof(TextDocument)) as TextDocument, this); - - ParserService.LoadSolutionProjectsThreadEnded += ParserServiceLoadSolutionProjectsThreadEnded; - - colorizers.Add(this); - } - - static IList colorizers = new List(); - - public static void RefreshAll() - { - foreach (XamlColorizer colorizer in colorizers) { - colorizer.RebuildDocument(); - colorizer.TextView.Redraw(); - } - } - - void ParserServiceLoadSolutionProjectsThreadEnded(object sender, EventArgs e) - { - WorkbenchSingleton.SafeThreadAsyncCall( - () => { - highlightCache.Clear(); - TextView.Redraw(); - } - ); - } - - WeakLineTracker weakLineTracker; - bool disposed; - - public void Dispose() - { - if (!disposed) { - ParserService.LoadSolutionProjectsThreadEnded -= ParserServiceLoadSolutionProjectsThreadEnded; - weakLineTracker.Deregister(); - colorizers.Remove(this); - } - disposed = true; - } - - protected override void ColorizeLine(DocumentLine line) - { - if (!highlightCache.ContainsKey(line)) { - HighlightTask task = new HighlightTask(this.Editor, line, this.TextView); - task.Start(); - highlightCache.Add(line, task); - } else { - HighlightTask task = highlightCache[line]; - var results = task.GetResults(); - if (results != null) { - foreach (var result in results) { - ColorizeMember(result.Info, line, result.Member); - } - } - } - ColorizeInvalidated(); - } - - void ColorizeMember(HighlightingInfo info, DocumentLine line, IMember member) - { - try { - Action handler = null; - - if (info.Token.StartsWith(info.Context.XamlNamespacePrefix + ":", StringComparison.Ordinal)) - handler = HighlightProperty; - else if (info.Context.IgnoredXmlns.Any(item => info.Token.StartsWith(item + ":", StringComparison.Ordinal))) - handler = HighlightIgnored; - else if (member != null) { - if (member is IEvent) - handler = HighlightEvent; - else - handler = HighlightProperty; - } else { - if (info.Token.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase) || info.Token.StartsWith(Utils.GetNamespacePrefix(CompletionDataHelper.MarkupCompatibilityNamespace, info.Context) + ":", StringComparison.OrdinalIgnoreCase)) - handler = HighlightNamespaceDeclaration; - else if (info.Token.StartsWith("xml:", StringComparison.OrdinalIgnoreCase)) - handler = HighlightProperty; - else - Core.LoggingService.Debug(info.Token + " not highlighted; line " + line.LineNumber); - } - if (handler != null) - ChangeLinePart(line.Offset + info.StartOffset, line.Offset + info.EndOffset, handler); - } catch (ArgumentOutOfRangeException) {} - } - - void ColorizeInvalidated() - { - foreach (var item in highlightCache.ToArray()) { - if (item.Key.IsDeleted) { - highlightCache.Remove(item.Key); - continue; - } - if (item.Value.Invalid) { - var newTask = new HighlightTask(this.Editor, item.Key, this.TextView, item.Value.GetResults()); - newTask.Start(); - highlightCache[item.Key] = newTask; - } - } - } - - void InvalidateLines(DocumentLine line) - { - DocumentLine current = line; - while (current != null) { - HighlightTask task; - if (highlightCache.TryGetValue(current, out task)) - task.Invalid = true; - - current = current.NextLine; - } - } - - #region highlight helpers - void HighlightProperty(VisualLineElement element) - { - element.TextRunProperties.SetForegroundBrush(XamlBindingOptions.PropertyForegroundColor.ToBrush()); - element.TextRunProperties.SetBackgroundBrush(XamlBindingOptions.PropertyBackgroundColor.ToBrush()); - } - - void HighlightEvent(VisualLineElement element) - { - element.TextRunProperties.SetForegroundBrush(XamlBindingOptions.EventForegroundColor.ToBrush()); - element.TextRunProperties.SetBackgroundBrush(XamlBindingOptions.EventBackgroundColor.ToBrush()); - } - - void HighlightNamespaceDeclaration(VisualLineElement element) - { - element.TextRunProperties.SetForegroundBrush(XamlBindingOptions.NamespaceDeclarationForegroundColor.ToBrush()); - element.TextRunProperties.SetBackgroundBrush(XamlBindingOptions.NamespaceDeclarationBackgroundColor.ToBrush()); - } - - void HighlightIgnored(VisualLineElement element) - { - element.TextRunProperties.SetForegroundBrush(XamlBindingOptions.IgnoredForegroundColor.ToBrush()); - element.TextRunProperties.SetBackgroundBrush(XamlBindingOptions.IgnoredBackgroundColor.ToBrush()); - } - #endregion - - #region ILineTracker implementation - public void BeforeRemoveLine(DocumentLine line) - { - InvalidateLines(line.NextLine); - } - - public void SetLineLength(DocumentLine line, int newTotalLength) - { - InvalidateLines(line); - } - - public void LineInserted(DocumentLine insertionPos, DocumentLine newLine) - { - InvalidateLines(newLine); - } - - public void RebuildDocument() - { - highlightCache.Clear(); - } - #endregion - - public struct HighlightingInfo - { - string token; - int startOffset; - int endOffset; - int lineOffset; - XamlContext context; - - public HighlightingInfo(string token, int startOffset, int endOffset, int lineOffset, XamlContext context) - { - if (token == null) - throw new ArgumentNullException("token"); - if (startOffset < 0) - throw new ArgumentOutOfRangeException("startOffset", startOffset, "Value must be greater 0"); - if (endOffset < 0) - throw new ArgumentOutOfRangeException("endOffset", endOffset, "Value must be greater 0"); - if (lineOffset < 0) - throw new ArgumentOutOfRangeException("lineOffset", lineOffset, "Value must be greater 0"); - if (context == null) - throw new ArgumentNullException("context"); - - this.token = token; - this.startOffset = startOffset; - this.endOffset = endOffset; - this.lineOffset = lineOffset; - this.context = context; - } - - public string Token { - get { return token; } - } - - public int StartOffset { - get { return startOffset; } - } - - public int EndOffset { - get { return endOffset; } - } - - public int LineOffset { - get { return lineOffset; } - } - - public XamlContext Context { - get { return context; } - } - } - } -} diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompilationUnit.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompilationUnit.cs deleted file mode 100644 index 7ac7da7d53..0000000000 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompilationUnit.cs +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Linq; -using ICSharpCode.SharpDevelop.Dom; -using System.Collections; -using System.Collections.Generic; - -namespace ICSharpCode.XamlBinding -{ - /// - /// Description of XamlCompilationUnit. - /// - public class XamlCompilationUnit : DefaultCompilationUnit - { - public XamlCompilationUnit(IProjectContent projectContent) - : base(projectContent) - { - } - - public NodeWrapper TreeRootNode { get; set; } - - /// - /// Creates a IReturnType looking for a class referenced in XAML. - /// - /// The XML namespace - /// The class name - /// A new IReturnType that will search the referenced type on demand. - public IReturnType CreateType(string xmlNamespace, string className) - { - if (string.IsNullOrEmpty(className) || className.Contains(".")) - return null; - - if (xmlNamespace.StartsWith("clr-namespace:", StringComparison.OrdinalIgnoreCase)) { - return CreateClrNamespaceType(this.ProjectContent, xmlNamespace, className); - } else { - return new XamlClassReturnType(this, xmlNamespace, className); - } - } - - static IReturnType CreateClrNamespaceType(IProjectContent pc, string xmlNamespace, string className) - { - string namespaceName = GetNamespaceNameFromClrNamespace(xmlNamespace); - return new GetClassReturnType(pc, namespaceName + "." + className, 0); - } - - static string GetNamespaceNameFromClrNamespace(string xmlNamespace) - { - string namespaceName = xmlNamespace.Substring("clr-namespace:".Length); - int pos = namespaceName.IndexOf(';'); - if (pos >= 0) { - // we expect that the target type is also a reference of the project, so we - // can ignore the assembly part after the ; - namespaceName = namespaceName.Substring(0, pos); - } - return namespaceName; - } - - /// - /// Finds a type referenced in XAML. - /// - /// The XML namespace - /// The class name - /// Returns the referenced type, or null if it cannot be found. - public IReturnType FindType(string xmlNamespace, string className) - { - return FindType(this.ProjectContent, xmlNamespace, className); - } - - public static IReturnType FindType(IProjectContent pc, string xmlNamespace, string className) - { - if (pc == null) - throw new ArgumentNullException("pc"); - if (xmlNamespace == null || className == null) - return null; - if (xmlNamespace.StartsWith("clr-namespace:", StringComparison.OrdinalIgnoreCase)) { - return CreateClrNamespaceType(pc, xmlNamespace, className); - } - else { - IReturnType type = FindTypeInAssembly(pc, xmlNamespace, className); - if (type != null) - return type; - foreach (IProjectContent p in pc.ReferencedContents) { - type = FindTypeInAssembly(p, xmlNamespace, className); - if (type != null) - return type; - } - return null; - } - } - - static IReturnType FindTypeInAssembly(IProjectContent projectContent, string xmlNamespace, string className) - { - foreach (IAttribute att in projectContent.GetAssemblyAttributes()) { - if (att.PositionalArguments.Count == 2 - && att.AttributeType.FullyQualifiedName == "System.Windows.Markup.XmlnsDefinitionAttribute") { - string namespaceName = att.PositionalArguments[1] as string; - if (xmlNamespace.Equals(att.PositionalArguments[0]) && namespaceName != null) { - IClass c = projectContent.GetClass(namespaceName + "." + className, 0); - if (c != null) - return c.DefaultReturnType; - } - } - } - return null; - } - - public static IEnumerable GetNamespaceMembers(IProjectContent pc, string xmlNamespace) - { - if (pc == null) - throw new ArgumentNullException("pc"); - - if (!string.IsNullOrEmpty(xmlNamespace)) { - if (xmlNamespace.StartsWith("clr-namespace:", StringComparison.OrdinalIgnoreCase)) - return pc.GetNamespaceContents(GetNamespaceNameFromClrNamespace(xmlNamespace)).OfType(); - else { - var list = new List(); - AddNamespaceMembersInAssembly(pc, xmlNamespace, list); - foreach (IProjectContent p in pc.ReferencedContents) { - AddNamespaceMembersInAssembly(p, xmlNamespace, list); - } - return list.OfType(); - } - } - - return Enumerable.Empty(); - } - - static void AddNamespaceMembersInAssembly(IProjectContent projectContent, string xmlNamespace, List list) - { - foreach (IAttribute att in projectContent.GetAssemblyAttributes()) { - if (att.PositionalArguments.Count == 2 - && att.AttributeType.FullyQualifiedName == "System.Windows.Markup.XmlnsDefinitionAttribute") { - string namespaceName = att.PositionalArguments[1] as string; - if (xmlNamespace.Equals(att.PositionalArguments[0]) && namespaceName != null) { - projectContent.AddNamespaceContents(list, namespaceName, projectContent.Language, false); - } - } - } - } - } -} diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItem.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItem.cs deleted file mode 100644 index fa2370a7bb..0000000000 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItem.cs +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; - -using ICSharpCode.Core; -using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Editor; -using ICSharpCode.SharpDevelop.Editor.CodeCompletion; - -namespace ICSharpCode.XamlBinding -{ - class XamlCodeCompletionItem : CodeCompletionItem - { - public XamlCodeCompletionItem(IEntity entity, string prefix) - : base(entity) - { - if (string.IsNullOrEmpty(prefix)) - this.Text = entity.Name; - else - this.Text = prefix + ":" + entity.Name; - this.Content = this.Text; - } - - public XamlCodeCompletionItem(IEntity entity) - : base(entity) - { - this.Text = entity.Name; - this.Content = this.Text; - } - - public XamlCodeCompletionItem(string text, IEntity entity) - : base(entity) - { - this.Text = text; - this.Content = this.Text; - } - - public XamlCodeCompletionItem(IEntity entity, string prefix, string className) - : base(entity) - { - if (string.IsNullOrEmpty(prefix)) - this.Text = className + "." + entity.Name; - else - this.Text = prefix + ":" + className + "." + entity.Name; - this.Content = this.Text; - } - - public override string ToString() - { - return "[" + this.Text + "]"; - } - } - - class XamlLazyValueCompletionItem : XamlCodeCompletionItem - { - bool addType; - - public XamlLazyValueCompletionItem(IEntity entity, string text, bool addType) - : base(entity) - { - this.addType = addType; - this.Text = text; - this.Content = this.Text; - } - - public override void Complete(CompletionContext context) - { - if (addType) { - MarkAsUsed(); - string newText = Entity.DeclaringType.Name + "." + Text; - context.Editor.Document.Replace(context.StartOffset, context.Length, newText); - context.EndOffset = context.StartOffset + newText.Length; - } else - base.Complete(context); - } - } - - class XamlCompletionItem : DefaultCompletionItem - { - string prefix, @namespace, name; - - public XamlCompletionItem(string prefix, string @namespace, string name) - : base(prefix + ":" + name) - { - this.prefix = prefix; - this.@namespace = @namespace; - this.name = name; - this.Image = ClassBrowserIconService.Namespace; - } - } - - class SpecialCompletionItem : DefaultCompletionItem - { - public SpecialCompletionItem(string name) - : base(name) - { - this.Image = ClassBrowserIconService.Namespace; - } - } - - class SpecialValueCompletionItem : DefaultCompletionItem - { - public SpecialValueCompletionItem(string name) - : base(name) - { - this.Image = ClassBrowserIconService.Const; - } - } - - class XmlnsCompletionItem : DefaultCompletionItem - { - string @namespace, assembly; - bool isUrl; - - public bool IsUrl { - get { return isUrl; } - } - - public XmlnsCompletionItem(string @namespace, string assembly) - : base(@namespace + " (" + assembly + ")") - { - this.@namespace = @namespace; - this.assembly = assembly; - this.Image = ClassBrowserIconService.Namespace; - } - - public XmlnsCompletionItem(string @namespace, bool isUrl) - : base(@namespace) - { - this.@namespace = @namespace; - this.isUrl = isUrl; - this.assembly = string.Empty; - this.Image = ClassBrowserIconService.Namespace; - } - - public string Namespace { - get { return @namespace; } - } - - public string Assembly { - get { return assembly; } - } - - public override void Complete(CompletionContext context) - { - if (isUrl) - base.Complete(context); - else { - ITextEditor editor = context.Editor; - string newText = "clr-namespace:" + @namespace; - if (!string.IsNullOrEmpty(assembly)) - newText += ";assembly=" + assembly; - editor.Document.Replace(context.StartOffset, context.Length, newText); - context.EndOffset = context.StartOffset + newText.Length; - } - } - } - - class NewEventCompletionItem : DefaultCompletionItem - { - IEvent eventType; - - public IEvent EventType { - get { return eventType; } - } - - string targetName; - - public string TargetName { - get { return targetName; } - } - - public string HandlerName { get; private set; } - - public NewEventCompletionItem(IEvent eventType, string targetName) - : base(StringParser.Parse("${res:AddIns.XamlBinding.NewEventHandlerItem}")) - { - this.eventType = eventType; - this.targetName = targetName; - this.HandlerName = ParseNamePattern(this.TargetName, this.EventType.Name); - this.Image = ClassBrowserIconService.Event; - } - - public override void Complete(CompletionContext context) - { - context.Editor.Document.Replace(context.StartOffset, context.Length, this.HandlerName); - - context.EndOffset = context.StartOffset + this.HandlerName.Length; - } - - static readonly Regex namePatternRegex = new Regex("%[A-z0-9]*%", RegexOptions.Compiled); - - public static string ParseNamePattern(string objectName, string eventName) - { - string name = XamlBindingOptions.EventHandlerNamePattern; - - while (namePatternRegex.IsMatch(name)) { - Match match = namePatternRegex.Match(name); - switch (match.Value.ToUpperInvariant()) { - case "%OBJECT%": - if (char.IsUpper(match.Value[1])) - objectName = objectName.ToUpperInvariant()[0] + objectName.Substring(1, objectName.Length - 1); - else - objectName = objectName.ToLowerInvariant()[0] + objectName.Substring(1, objectName.Length - 1); - name = name.Replace(match.Index, match.Length, objectName); - break; - case "%EVENT%": - if (char.IsUpper(match.Value[1])) - eventName = eventName.ToUpperInvariant()[0] + eventName.Substring(1, eventName.Length - 1); - else - eventName = eventName.ToLowerInvariant()[0] + eventName.Substring(1, eventName.Length - 1); - name = name.Replace(match.Index, match.Length, eventName); - break; - case "%%": - name = name.Replace(match.Index, match.Length, "%"); - break; - default: - throw new ArgumentException("Pattern identifier invalid", match.Value); - } - } - - return name; - } - } - - class MarkupExtensionInsightItem : IInsightItem - { - IMethod ctor; - - public MarkupExtensionInsightItem(IMethod entity) - { - if (entity == null) - throw new ArgumentNullException("entity"); - this.ctor = entity; - } - - string headerText; - bool descriptionCreated; - string description; - - public object Header { - get { - if (headerText == null) { - IAmbience ambience = AmbienceService.GetCurrentAmbience(); - ambience.ConversionFlags = ConversionFlags.StandardConversionFlags; - headerText = ambience.Convert(ctor); - headerText = headerText.Insert(headerText.LastIndexOf(')'), (ctor.Parameters.Count > 0 ? ", " : "") + "Named Parameters ..."); - } - return headerText; - } - } - - public object Content { - get { - if (!descriptionCreated) { - string entityDoc = ctor.Documentation; - if (!string.IsNullOrEmpty(entityDoc)) { - description = CodeCompletionItem.ConvertDocumentation(entityDoc); - } - descriptionCreated = true; - } - return description; - } - } - } - - class MemberInsightItem : IInsightItem - { - string insightText; - string headerText; - string description; - bool descriptionCreated; - IMember member; - - public MemberInsightItem(IMember member, string insightText) - { - this.member = member; - this.insightText = insightText; - } - - public object Header { - get { - if (headerText == null) { - headerText = this.member.Name + "=\"" + insightText + "\""; - } - - return headerText; - } - } - - public object Content { - get { - if (!descriptionCreated) { - string entityDoc = member.Documentation; - if (!string.IsNullOrEmpty(entityDoc)) { - description = CodeCompletionItem.ConvertDocumentation(entityDoc); - } - descriptionCreated = true; - } - return description; - } - } - } -} diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs index 767f1ab01a..23589a8137 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs @@ -5,10 +5,8 @@ using System; using System.Collections.Generic; using System.Linq; -using ICSharpCode.NRefactory.Ast; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Dom.Refactoring; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor.CodeCompletion; using ICSharpCode.SharpDevelop.Gui; @@ -52,170 +50,170 @@ namespace ICSharpCode.XamlBinding return text.Length - i - 1; } - 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++; - } - } - } - - static bool CreateEventHandlerCode(CompletionContext context, NewEventCompletionItem completionItem, out int discriminator) - { - ParseInformation p = ParserService.GetParseInformation(context.Editor.FileName); - var unit = p.CompilationUnit; - var loc = context.Editor.Document.OffsetToPosition(context.StartOffset); - IClass c = unit.GetInnermostClass(loc.Line, loc.Column); - - discriminator = 1; - - if (c == null) - return false; - IMethod initializeComponent = c.Methods[0]; - CompoundClass compound = c.GetCompoundClass() as CompoundClass; - - IMethod invokeMethod = completionItem.EventType.ReturnType.GetMethods().FirstOrDefault(m => m.Name == "Invoke"); - - string handlerName = completionItem.HandlerName; - - if (invokeMethod == null) - throw new ArgumentException("delegateType is not a valid delegate!"); - - if (compound != null) { - foreach (IClass part in compound.Parts) { - IMember lastMember = part.Methods.LastOrDefault(); - - if (lastMember != null && lastMember.ToString() == initializeComponent.ToString()) - continue; - - if (completionItem.EventType.ReturnType == null) - return false; - - while (part.Methods.Any(m => m.Name == handlerName && - m.Parameters.Count == invokeMethod.Parameters.Count && - m.Parameters.SequenceEqual(invokeMethod.Parameters, new ParameterComparer()) - )) { - handlerName = completionItem.HandlerName + discriminator; - discriminator++; - } - - discriminator--; - - ParametrizedNode node = (ParametrizedNode)CodeGenerator.ConvertMember(invokeMethod, new ClassFinder(part, context.Editor.Caret.Line, context.Editor.Caret.Column)); - - node.Name = handlerName; - - node.Modifier = Modifiers.None; - - IViewContent viewContent = FileService.OpenFile(part.CompilationUnit.FileName, XamlBindingOptions.SwitchToCodeViewAfterInsertion); - IFileDocumentProvider document = viewContent as IFileDocumentProvider; - - if (viewContent != null && document != null) { - DomRegion domRegion; - - if (lastMember != null) { - unit.ProjectContent.Language.CodeGenerator.InsertCodeAfter(lastMember, new RefactoringDocumentAdapter(document.GetDocumentForFile(viewContent.PrimaryFile)), node); - domRegion = lastMember.BodyRegion; - } - else { - unit.ProjectContent.Language.CodeGenerator.InsertCodeAtEnd(part.Region, new RefactoringDocumentAdapter(document.GetDocumentForFile(viewContent.PrimaryFile)), node); - domRegion = part.Region; - } - - // move caret to generated code - ITextEditorProvider provider = viewContent as ITextEditorProvider; - if (provider != null) { - provider.TextEditor.JumpTo(domRegion.EndLine + 2, domRegion.EndColumn - 1); - } - } - return true; - } - } - - return false; - } +// 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++; +// } +// } +// } +// +// static bool CreateEventHandlerCode(CompletionContext context, NewEventCompletionItem completionItem, out int discriminator) +// { +// ParseInformation p = ParserService.GetParseInformation(context.Editor.FileName); +// var unit = p.CompilationUnit; +// var loc = context.Editor.Document.OffsetToPosition(context.StartOffset); +// IClass c = unit.GetInnermostClass(loc.Line, loc.Column); +// +// discriminator = 1; +// +// if (c == null) +// return false; +// IMethod initializeComponent = c.Methods[0]; +// CompoundClass compound = c.GetCompoundClass() as CompoundClass; +// +// IMethod invokeMethod = completionItem.EventType.ReturnType.GetMethods().FirstOrDefault(m => m.Name == "Invoke"); +// +// string handlerName = completionItem.HandlerName; +// +// if (invokeMethod == null) +// throw new ArgumentException("delegateType is not a valid delegate!"); +// +// if (compound != null) { +// foreach (IClass part in compound.Parts) { +// IMember lastMember = part.Methods.LastOrDefault(); +// +// if (lastMember != null && lastMember.ToString() == initializeComponent.ToString()) +// continue; +// +// if (completionItem.EventType.ReturnType == null) +// return false; +// +// while (part.Methods.Any(m => m.Name == handlerName && +// m.Parameters.Count == invokeMethod.Parameters.Count && +// m.Parameters.SequenceEqual(invokeMethod.Parameters, new ParameterComparer()) +// )) { +// handlerName = completionItem.HandlerName + discriminator; +// discriminator++; +// } +// +// discriminator--; +// +// ParametrizedNode node = (ParametrizedNode)CodeGenerator.ConvertMember(invokeMethod, new ClassFinder(part, context.Editor.Caret.Line, context.Editor.Caret.Column)); +// +// node.Name = handlerName; +// +// node.Modifier = Modifiers.None; +// +// IViewContent viewContent = FileService.OpenFile(part.CompilationUnit.FileName, XamlBindingOptions.SwitchToCodeViewAfterInsertion); +// IFileDocumentProvider document = viewContent as IFileDocumentProvider; +// +// if (viewContent != null && document != null) { +// DomRegion domRegion; +// +// if (lastMember != null) { +// unit.ProjectContent.Language.CodeGenerator.InsertCodeAfter(lastMember, new RefactoringDocumentAdapter(document.GetDocumentForFile(viewContent.PrimaryFile)), node); +// domRegion = lastMember.BodyRegion; +// } +// else { +// unit.ProjectContent.Language.CodeGenerator.InsertCodeAtEnd(part.Region, new RefactoringDocumentAdapter(document.GetDocumentForFile(viewContent.PrimaryFile)), node); +// domRegion = part.Region; +// } +// +// // move caret to generated code +// ITextEditorProvider provider = viewContent as ITextEditorProvider; +// if (provider != null) { +// provider.TextEditor.JumpTo(domRegion.EndLine + 2, domRegion.EndColumn - 1); +// } +// } +// return true; +// } +// } +// +// return false; +// } } } diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs index 348dad54a6..a6cc6fef44 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs @@ -1,23 +1,26 @@ // Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) -using ICSharpCode.AvalonEdit.Xml; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Xml; + +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.Xml; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.XmlEditor; namespace ICSharpCode.XamlBinding { // Fetch a copy of all relevant values of the AXmlDocument so that XamlContext can be used // without having to acquire the reader lock. - public class ElementWrapper { + public class ElementWrapper + { public ElementWrapper(AXmlElement element) { this.LocalName = element.LocalName; @@ -63,7 +66,8 @@ namespace ICSharpCode.XamlBinding } } - public class AttributeWrapper { + public class AttributeWrapper + { public string LocalName { get; set; } public string Namespace { get; set; } public string Prefix { get; set; } @@ -94,7 +98,8 @@ namespace ICSharpCode.XamlBinding } } - public class XamlContext : ExpressionContext { + public class XamlContext + { public ElementWrapper ActiveElement { get; set; } public ElementWrapper ParentElement { get; set; } public List Ancestors { get; set; } @@ -109,15 +114,6 @@ namespace ICSharpCode.XamlBinding public ReadOnlyCollection IgnoredXmlns { get; set; } public string XamlNamespacePrefix { get; set; } - public IProjectContent ProjectContent { - get { - if (ParseInformation != null) - return ParseInformation.CompilationUnit.ProjectContent; - else - return null; - } - } - public XamlContext() {} public bool InAttributeValueOrMarkupExtension { @@ -129,14 +125,10 @@ namespace ICSharpCode.XamlBinding get { return Description == XamlContextDescription.InComment || Description == XamlContextDescription.InCData; } } - - public override bool ShowEntry(ICompletionEntry o) - { - return true; - } } - public class XamlCompletionContext : XamlContext { + public class XamlCompletionContext : XamlContext + { public XamlCompletionContext() { } public XamlCompletionContext(XamlContext context) @@ -161,7 +153,8 @@ namespace ICSharpCode.XamlBinding public ITextEditor Editor { get; set; } } - public enum XamlContextDescription { + public enum XamlContextDescription + { /// /// Outside any tag /// diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlExpressionContext.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlExpressionContext.cs index 768ac5e5f6..2512fcc52f 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlExpressionContext.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlExpressionContext.cs @@ -3,7 +3,7 @@ using System; using System.Text; -using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.XmlEditor; namespace ICSharpCode.XamlBinding @@ -11,7 +11,7 @@ namespace ICSharpCode.XamlBinding /// /// Represents the context of a location in a XAML document. /// - public sealed class XamlExpressionContext : ExpressionContext + public sealed class XamlExpressionContext { public static readonly XamlExpressionContext Empty = new XamlExpressionContext(new XmlElementPath(), null, false); @@ -28,11 +28,6 @@ namespace ICSharpCode.XamlBinding this.InAttributeValue = inAttributeValue; } - public override bool ShowEntry(ICompletionEntry o) - { - return true; - } - public override string ToString() { StringBuilder b = new StringBuilder(); diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlExpressionFinder.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlExpressionFinder.cs deleted file mode 100644 index 32ade19891..0000000000 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlExpressionFinder.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Text; -using System.Xml; -using ICSharpCode.Core; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.XmlEditor; - -namespace ICSharpCode.XamlBinding -{ - /// - /// Description of XamlExpressionFinder. - /// - public class XamlExpressionFinder : IExpressionFinder - { - public static readonly XamlExpressionFinder Instance = new XamlExpressionFinder(); - - static bool IsValidChar(char c) - { - return char.IsLetterOrDigit(c) || c == '_' || c == ':' || c == '.'; - } - - public ExpressionResult FindExpression(string text, int offset) - { - int pos = offset - 1; - while (pos > 0 && IsValidChar(text[pos])) { - pos--; - } - pos++; - return new ExpressionResult(text.Substring(pos, offset - pos), GetContext(text, offset)); - } - - public ExpressionResult FindFullExpression(string text, int offset) - { - int start = offset - 1; - while (start > 0 && IsValidChar(text[start])) { - start--; - } - start++; - while (offset < text.Length && IsValidChar(text[offset])) { - offset++; - } - - var startLocation = Utils.GetLocationInfoFromOffset(text, start); - var endLocation = Utils.GetLocationInfoFromOffset(text, offset); - - return new ExpressionResult(text.Substring(start, offset - start), GetContext(text, offset)) { Region = new DomRegion(startLocation.Line, startLocation.Column, endLocation.Line, endLocation.Column) }; - } - - public string RemoveLastPart(string expression) - { - return ""; - } - - static ExpressionContext GetContext(string text, int offset) - { - XmlElementPath path = XmlParser.GetActiveElementStartPathAtIndex(text, offset); - if (path == null || path.Elements.Count == 0) { - if (offset > 0 && text[offset - 1] == '<') - return XamlExpressionContext.Empty; - else - return ExpressionContext.Default; - } - string attributeName = XmlParser.GetAttributeNameAtIndex(text, offset); - if (!string.IsNullOrEmpty(attributeName)) { - return new XamlExpressionContext(path, attributeName, XmlParser.IsInsideAttributeValue(text, offset)); - } - else { - return new XamlExpressionContext(path, null, false); - } - } - } -} diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlLanguageBinding.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlLanguageBinding.cs index 6e30d1c2b1..0af90ee93b 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlLanguageBinding.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlLanguageBinding.cs @@ -4,7 +4,6 @@ using System; using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Rendering; -using ICSharpCode.AvalonEdit.Xml; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Gui; @@ -15,7 +14,7 @@ namespace ICSharpCode.XamlBinding /// public class XamlLanguageBinding : XmlEditor.XmlLanguageBinding { - XamlColorizer colorizer; +// XamlColorizer colorizer; TextView textView; XamlOutlineContentHost contentHost; @@ -31,11 +30,11 @@ namespace ICSharpCode.XamlBinding // GetService returns null if (textView != null) { if (WorkbenchSingleton.Workbench != null) { - if (XamlBindingOptions.UseAdvancedHighlighting) { - colorizer = new XamlColorizer(editor, textView); - // attach the colorizer - textView.LineTransformers.Add(colorizer); - } +// if (XamlBindingOptions.UseAdvancedHighlighting) { +// colorizer = new XamlColorizer(editor, textView); +// // attach the colorizer +// textView.LineTransformers.Add(colorizer); +// } // add the XamlOutlineContentHost, which manages the tree view contentHost = new XamlOutlineContentHost(editor); textView.Services.AddService(typeof(IOutlineContentHost), contentHost); @@ -52,10 +51,10 @@ namespace ICSharpCode.XamlBinding // if we added something before if (textView != null) { // remove and dispose everything we added - if (colorizer != null) { - textView.LineTransformers.Remove(colorizer); - colorizer.Dispose(); - } +// if (colorizer != null) { +// textView.LineTransformers.Remove(colorizer); +// colorizer.Dispose(); +// } if (contentHost != null) { textView.Services.RemoveService(typeof(IOutlineContentHost)); contentHost.Dispose(); diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs index d644ab0f9e..41853517d8 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs @@ -5,11 +5,12 @@ using System; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; + using ICSharpCode.Core; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.Parser; namespace ICSharpCode.XamlBinding { @@ -33,13 +34,11 @@ namespace ICSharpCode.XamlBinding { if (this.editor == null || !FileUtility.IsEqualFileName(this.editor.FileName, e.FileName)) return; - if (!e.IsPrimaryParseInfoForFile) - return; - - var cu = e.NewCompilationUnit as XamlCompilationUnit; - if (cu != null && cu.TreeRootNode != null) - UpdateTree(cu.TreeRootNode); +// var cu = e.NewCompilationUnit as XamlCompilationUnit; +// +// if (cu != null && cu.TreeRootNode != null) +// UpdateTree(cu.TreeRootNode); } void UpdateTree(NodeWrapper root) diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs index a128a0e7de..ff86aecd6b 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs @@ -7,6 +7,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Input; +using ICSharpCode.NRefactory.Editor; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.TreeView; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParsedFile.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParsedFile.cs new file mode 100644 index 0000000000..28e0d75a56 --- /dev/null +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParsedFile.cs @@ -0,0 +1,97 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; + +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.Core; +using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.Editor; +using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.TypeSystem.Implementation; +using ICSharpCode.NRefactory.Xml; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Parser; +using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.SharpDevelop.Refactoring; + +namespace ICSharpCode.XamlBinding +{ + public sealed class XamlParsedFile : IParsedFile + { + FileName fileName; + AXmlDocument document; + List errors; + ITypeDefinition xamlTypeDefinition; + + XamlParsedFile(FileName fileName, AXmlDocument document) + { + this.fileName = fileName; + this.document = document; + this.errors = new List(); + } + + public static XamlParsedFile Create(FileName fileName, string fileContent, AXmlDocument document) + { + XamlParsedFile file = new XamlParsedFile(fileName, document); + + file.errors.AddRange(document.SyntaxErrors.Select(err => new Error(ErrorType.Error, err.Description))); + + file.lastWriteTime = DateTime.UtcNow; + return file; + } + + public string FileName { + get { return fileName; } + } + + DateTime lastWriteTime = DateTime.UtcNow; + + public DateTime LastWriteTime { + get { return lastWriteTime; } + } + + public IList TopLevelTypeDefinitions { + get { + throw new NotImplementedException(); + } + } + + public IList AssemblyAttributes { + get { return EmptyList.Instance; } + } + + public IList ModuleAttributes { + get { return EmptyList.Instance; } + } + + public IList Errors { + get { return errors; } + } + + public IUnresolvedTypeDefinition GetTopLevelTypeDefinition(TextLocation location) + { + throw new NotImplementedException(); + } + + public IUnresolvedTypeDefinition GetInnermostTypeDefinition(TextLocation location) + { + throw new NotImplementedException(); + } + + public IUnresolvedMember GetMember(TextLocation location) + { + throw new NotImplementedException(); + } + + public ITypeResolveContext GetTypeResolveContext(ICompilation compilation, TextLocation loc) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs index 1423a1e7aa..0c1200ceb5 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs @@ -2,15 +2,23 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading; using ICSharpCode.AvalonEdit.Document; -using ICSharpCode.AvalonEdit.Xml; using ICSharpCode.Core; +using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.Editor; +using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.TypeSystem.Implementation; +using ICSharpCode.NRefactory.Xml; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.SharpDevelop.Refactoring; namespace ICSharpCode.XamlBinding { @@ -27,10 +35,10 @@ namespace ICSharpCode.XamlBinding set { lexerTags = value; } } - public LanguageProperties Language - { - get { return LanguageProperties.CSharp; } - } +// public LanguageProperties Language +// { +// get { return LanguageProperties.CSharp; } +// } public XamlParser() { @@ -47,98 +55,110 @@ namespace ICSharpCode.XamlBinding } AXmlParser parser = new AXmlParser(); - volatile ITextBufferVersion lastParsedVersion; + volatile ITextSourceVersion lastParsedVersion; /// /// Parse the given text and enter read lock. /// No parsing is done if the text is older than seen before. /// - public IDisposable ParseAndLock(ITextBuffer fileContent) - { - // Copy to ensure thread-safety - var lastVer = this.lastParsedVersion; - if (lastVer == null || // First parse - fileContent.Version == null || // Versioning not supported - !fileContent.Version.BelongsToSameDocumentAs(lastVer) || // Different document instance? Can happen after closing and reopening of file. - fileContent.Version.CompareAge(lastVer) > 0) // Is fileContent newer? - { - parser.Lock.EnterWriteLock(); - // Double check, now that we are thread-safe - lastVer = this.lastParsedVersion; - if (lastVer == null || fileContent.Version == null || !fileContent.Version.BelongsToSameDocumentAs(lastVer)) { - // First parse or versioning not supported - using (DebugTimer.Time("normal parse")) - parser.Parse(fileContent.Text, null); - this.lastParsedVersion = fileContent.Version; - } else if (fileContent.Version.CompareAge(lastParsedVersion) > 0) { - // Incremental parse - var changes = lastParsedVersion.GetChangesTo(fileContent.Version). - Select(c => new DocumentChangeEventArgs(c.Offset, c.RemovedText, c.InsertedText)); - using (DebugTimer.Time("incremental parse")) - parser.Parse(fileContent.Text, changes); - this.lastParsedVersion = fileContent.Version; - } else { - // fileContent is older - no need to parse - } - parser.Lock.EnterReadLock(); - parser.Lock.ExitWriteLock(); - } else { - // fileContent is older - no need to parse - parser.Lock.EnterReadLock(); - } - return new CallbackOnDispose(() => parser.Lock.ExitReadLock()); - } - - public ICompilationUnit Parse(IProjectContent projectContent, string fileName, ITextBuffer fileContent) +// public IDisposable ParseAndLock(ITextSource fileContent) +// { +// // Copy to ensure thread-safety +// var lastVer = this.lastParsedVersion; +// if (lastVer == null || // First parse +// fileContent.Version == null || // Versioning not supported +// !fileContent.Version.BelongsToSameDocumentAs(lastVer) || // Different document instance? Can happen after closing and reopening of file. +// fileContent.Version.CompareAge(lastVer) > 0) // Is fileContent newer? +// { +// parser.Lock.EnterWriteLock(); +// // Double check, now that we are thread-safe +// lastVer = this.lastParsedVersion; +// if (lastVer == null || fileContent.Version == null || !fileContent.Version.BelongsToSameDocumentAs(lastVer)) { +// // First parse or versioning not supported +// using (DebugTimer.Time("normal parse")) +// parser.Parse(fileContent.Text, null); +// this.lastParsedVersion = fileContent.Version; +// } else if (fileContent.Version.CompareAge(lastParsedVersion) > 0) { +// // Incremental parse +// var changes = lastParsedVersion.GetChangesTo(fileContent.Version). +// Select(c => new DocumentChangeEventArgs(c.Offset, c.RemovedText, c.InsertedText)); +// using (DebugTimer.Time("incremental parse")) +// parser.Parse(fileContent.Text, changes); +// this.lastParsedVersion = fileContent.Version; +// } else { +// // fileContent is older - no need to parse +// } +// parser.Lock.EnterReadLock(); +// parser.Lock.ExitWriteLock(); +// } else { +// // fileContent is older - no need to parse +// parser.Lock.EnterReadLock(); +// } +// return new CallbackOnDispose(() => parser.Lock.ExitReadLock()); +// } +// +// public ICompilationUnit Parse(IProjectContent projectContent, string fileName, ITextSource fileContent) +// { +// ICompilationUnit compilationUnit; +// +// using (ParseAndLock(fileContent)) { +// var document = parser.LastDocument; +// +// CompilationUnitCreatorVisitor visitor = +// new CompilationUnitCreatorVisitor(projectContent, fileContent.Text, fileName, lexerTags); +// +// document.AcceptVisitor(visitor); +// +// compilationUnit = visitor.CompilationUnit; +// } +// +// // During project load all XAML files are parsed +// // most of them are not opened, thus fileContent.Version is null. +// // We can clear the parser data, because the file will be reparsed +// // as soon as it is opened by the user. +// +// // This will save us some memory, because we only use the +// // compilation unit created by the visitor above for code completion. +// if (fileContent.Version == null) { +// parser.Lock.EnterWriteLock(); +// // double-checked locking (other threads might parse the document in the meantime) +// if (lastParsedVersion == null) { +// parser.Clear(); +// } +// parser.Lock.ExitWriteLock(); +// } +// +// return compilationUnit; +// } + + volatile IncrementalParserState parserState = null; + + public ParseInformation Parse(FileName fileName, ITextSource fileContent, bool fullParseInformationRequested) { - ICompilationUnit compilationUnit; - - using (ParseAndLock(fileContent)) { - var document = parser.LastDocument; - - CompilationUnitCreatorVisitor visitor = - new CompilationUnitCreatorVisitor(projectContent, fileContent.Text, fileName, lexerTags); - - document.AcceptVisitor(visitor); - - compilationUnit = visitor.CompilationUnit; + AXmlParser parser = new AXmlParser(); + AXmlDocument document; + try { + document = parser.ParseIncremental(parserState, fileContent, out parserState); + } catch (Exception ex) { + LoggingService.Error(ex); + document = null; // TODO empty document? } + XamlParsedFile parsedFile = XamlParsedFile.Create(fileName, fileContent.Text, document); - // During project load all XAML files are parsed - // most of them are not opened, thus fileContent.Version is null. - // We can clear the parser data, because the file will be reparsed - // as soon as it is opened by the user. - - // This will save us some memory, because we only use the - // compilation unit created by the visitor above for code completion. - if (fileContent.Version == null) { - parser.Lock.EnterWriteLock(); - // double-checked locking (other threads might parse the document in the meantime) - if (lastParsedVersion == null) { - parser.Clear(); - } - parser.Lock.ExitWriteLock(); - } - - return compilationUnit; + // TODO if (fullParseInformationRequested) + return new ParseInformation(parsedFile, false); } - /// - /// Wraps AXmlParser.LastDocument. Returns the last cached version of the document. - /// - /// No read lock is held by the current thread. - public AXmlDocument LastDocument { - get { return parser.LastDocument; } - } - - public IExpressionFinder CreateExpressionFinder(string fileName) + public ResolveResult Resolve(ParseInformation parseInfo, TextLocation location, ICompilation compilation, CancellationToken cancellationToken) { - return XamlExpressionFinder.Instance; + throw new NotImplementedException(); } - - public IResolver CreateResolver() + + public void FindLocalReferences(ParseInformation parseInfo, ITextSource fileContent, IVariable variable, ICompilation compilation, Action callback, CancellationToken cancellationToken) { - return new XamlResolver(); + throw new NotImplementedException(); } } + + } diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs deleted file mode 100644 index 94f3123072..0000000000 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Xml; - -using ICSharpCode.Core; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.XmlEditor; - -namespace ICSharpCode.XamlBinding -{ - /// - /// Description of XamlResolver. - /// - public class XamlResolver : IResolver - { - IClass callingClass; - string resolveExpression; - int caretLine, caretColumn; - XamlContext context; - - public ResolveResult Resolve(ExpressionResult expressionResult, ParseInformation parseInfo, string fileContent) - { - if (parseInfo == null || (string.IsNullOrEmpty(fileContent) && !(expressionResult.Context is XamlContext))) - return null; - - this.resolveExpression = expressionResult.Expression; - this.caretLine = expressionResult.Region.BeginLine; - this.caretColumn = expressionResult.Region.BeginColumn; - this.callingClass = parseInfo.CompilationUnit.GetInnermostClass(caretLine, caretColumn); - this.context = expressionResult.Context as XamlContext ?? CompletionDataHelper.ResolveContext(fileContent, parseInfo.CompilationUnit.FileName, Utils.GetOffsetFromFilePos(fileContent, caretLine, caretColumn)); - - switch (this.context.Description) { - case XamlContextDescription.AtTag: - case XamlContextDescription.None: - return ResolveElementName(resolveExpression); - case XamlContextDescription.InTag: - return ResolveAttribute(resolveExpression) ?? ResolveElementName(resolveExpression); - case XamlContextDescription.InAttributeValue: - MemberResolveResult mrr = ResolveAttribute(context.Attribute.Name); - if (mrr != null) { - var rr = ResolveAttributeValue(mrr.ResolvedMember, resolveExpression) ?? mrr; - return rr; - } - break; - case XamlContextDescription.InMarkupExtension: - return ResolveMarkupExtension(resolveExpression); - } - - return null; - } - - ResolveResult ResolveMarkupExtension(string expression) - { - if (context.AttributeValue.IsString) - return null; - - object data = Utils.GetMarkupDataAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset); - - // resolve markup extension type - if ((data as string) == expression) { - return ResolveElementName(expression + "Extension") ?? ResolveElementName(expression); - } else { - MarkupExtensionInfo info = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset); - TypeResolveResult extensionType = (ResolveElementName(info.ExtensionType + "Extension") ?? ResolveElementName(info.ExtensionType)) as TypeResolveResult; - if (extensionType != null && extensionType.ResolvedType != null) { - var value = data as AttributeValue; - - switch (extensionType.ResolvedType.FullyQualifiedName) { - case "System.Windows.Markup.StaticExtension": - case "System.Windows.Markup.TypeExtension": - if (value != null && value.IsString) { - return ResolveElementName(expression) ?? ResolveAttribute(expression); - } - goto default; // "fall through" - default: - if (data is KeyValuePair) { - var pair = (KeyValuePair)data; - var member = ResolveNamedAttribute(pair.Key); - if (pair.Value.StartOffset + pair.Key.Length >= context.ValueStartOffset) { - return member; - } else { - if (pair.Value.IsString && member != null) - return ResolveAttributeValue(member.ResolvedMember, expression) ?? ResolveElementName(expression); - } - } - break; - } - } - - return null; - } - } - - MemberResolveResult ResolveNamedAttribute(string expression) - { - MarkupExtensionInfo info = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset); - TypeResolveResult extensionType = (ResolveElementName(info.ExtensionType + "Extension") ?? ResolveElementName(info.ExtensionType)) as TypeResolveResult; - - if (extensionType != null && extensionType.ResolvedType != null) { - return ResolvePropertyName(extensionType.ResolvedType, expression, false); - } - - return null; - } - - ResolveResult ResolveElementName(string exp) - { - string xmlNamespace; - string name; - - this.resolveExpression = exp; - if (resolveExpression.Contains(":")) { - string prefix = resolveExpression.Substring(0, resolveExpression.IndexOf(':')); - name = resolveExpression.Substring(resolveExpression.IndexOf(':') + 1); - if (!context.XmlnsDefinitions.TryGetValue(prefix, out xmlNamespace)) - xmlNamespace = null; - } - else { - if (!context.XmlnsDefinitions.TryGetValue("", out xmlNamespace)) - xmlNamespace = null; - name = resolveExpression; - } - if (name.Contains(".")) { - string propertyName = name.Substring(name.IndexOf('.') + 1); - name = name.Substring(0, name.IndexOf('.')); - return ResolveProperty(xmlNamespace, name, propertyName, true); - } - else { - IProjectContent pc = context.ProjectContent; - IReturnType resolvedType = XamlCompilationUnit.FindType(pc, xmlNamespace, name); - IClass resolvedClass = resolvedType != null ? resolvedType.GetUnderlyingClass() : null; - if (resolvedClass != null) { - return new TypeResolveResult(callingClass, null, resolvedClass); - } - else { - return null; - } - } - } - - MemberResolveResult ResolveProperty(string xmlNamespace, string className, string propertyName, bool allowAttached) - { - IProjectContent pc = context.ProjectContent; - IReturnType resolvedType = XamlCompilationUnit.FindType(pc, xmlNamespace, className); - if (resolvedType != null && resolvedType.GetUnderlyingClass() != null) { - return ResolvePropertyName(resolvedType, propertyName, allowAttached); - } - return null; - } - - MemberResolveResult ResolvePropertyName(IReturnType resolvedType, string propertyName, bool allowAttached) - { - IMember member = resolvedType.GetProperties().Find(delegate(IProperty p) { return p.Name == propertyName; }); - if (member == null) { - member = resolvedType.GetEvents().Find(delegate(IEvent p) { return p.Name == propertyName; }); - } - if (member == null && allowAttached) { - IMethod method = resolvedType.GetMethods().Find( - delegate(IMethod p) { - return p.IsStatic && p.Parameters.Count == 1 && p.Name == "Get" + propertyName; - }); - member = method; - if (member != null) { - member = new DefaultProperty(resolvedType.GetUnderlyingClass(), propertyName) { ReturnType = method.ReturnType }; - } else { - IMethod m = resolvedType.GetMethods().Find( - delegate(IMethod p) { - return p.IsPublic && p.IsStatic && p.Parameters.Count == 2 && (p.Name == "Add" + propertyName + "Handler" || p.Name == "Remove" + propertyName + "Handler"); - }); - member = m; - if (member != null) - member = new DefaultEvent(resolvedType.GetUnderlyingClass(), propertyName) { ReturnType = m.Parameters[1].ReturnType }; - } - } - if (member != null) - return new MemberResolveResult(callingClass, null, member); - return null; - } - - MemberResolveResult ResolveAttribute(string attributeName) - { - if (context.ActiveElement == null) { - return null; - } - string attributeXmlNamespace; - if (attributeName.Contains(":")) { - string prefix = attributeName.Substring(0, attributeName.IndexOf(':')); - if (!context.XmlnsDefinitions.TryGetValue(prefix, out attributeXmlNamespace)) - attributeXmlNamespace = null; - attributeName = attributeName.Substring(attributeName.IndexOf(':') + 1); - } - else { - if (!context.XmlnsDefinitions.TryGetValue("", out attributeXmlNamespace)) - attributeXmlNamespace = null; - } - if (attributeName.Contains(".")) { - string className = attributeName.Substring(0, attributeName.IndexOf('.')); - attributeName = attributeName.Substring(attributeName.IndexOf('.') + 1); - return ResolveProperty(attributeXmlNamespace, className, attributeName, true); - } - else { - var lastElement = context.ActiveElement; - return ResolveProperty(lastElement.Namespace, lastElement.LocalName, attributeName, false); - } - } - - ResolveResult ResolveAttributeValue(IMember propertyOrEvent, string expression) - { - if (propertyOrEvent == null) - return null; - if (propertyOrEvent is IEvent && callingClass != null) { - return new MethodGroupResolveResult(callingClass, null, callingClass.DefaultReturnType, expression); - } else if (propertyOrEvent is IProperty && callingClass != null) { - if (propertyOrEvent.Name == "Name") { - foreach (IField f in callingClass.Fields) { - if (f.Name == expression) - return new MemberResolveResult(callingClass, null, f); - } - } - return ResolveElementName(expression); - } - - IReturnType type = propertyOrEvent.ReturnType; - if (type == null) return null; - IClass c = type.GetUnderlyingClass(); - if (c == null) return null; - - if (c.ClassType == ClassType.Enum) { - foreach (IField f in c.Fields) { - if (f.Name == expression) - return new MemberResolveResult(callingClass, null, f); - } - } - return null; - } - - public static ResolveResult Resolve(string expression, XamlCompletionContext context) - { - return new XamlResolver().Resolve(new ExpressionResult(expression, context), context.ParseInformation, null); - } - - public static ResolveResult Resolve(string expression, XamlContext context) - { - return new XamlResolver().Resolve(new ExpressionResult(expression, context), context.ParseInformation, null); - } - - public static MemberResolveResult ResolveMember(string expression, XamlCompletionContext context) - { - if (context.ParseInformation == null || string.IsNullOrEmpty(context.Editor.Document.Text)) - return null; - - var expressionResult = new ExpressionResult(expression, context); - - XamlResolver resolver = new XamlResolver(); - resolver.resolveExpression = expression; - resolver.caretLine = expressionResult.Region.BeginLine; - resolver.caretColumn = expressionResult.Region.BeginColumn; - resolver.callingClass = context.ParseInformation.CompilationUnit.GetInnermostClass(resolver.caretLine, resolver.caretColumn); - resolver.context = context; - - return resolver.ResolveNamedAttribute(expression); - } - } -} diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlSymbolSearch.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlSymbolSearch.cs new file mode 100644 index 0000000000..73c82d14f6 --- /dev/null +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlSymbolSearch.cs @@ -0,0 +1,32 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Threading.Tasks; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop.Editor.Search; +using ICSharpCode.SharpDevelop.Refactoring; + +namespace ICSharpCode.XamlBinding +{ + /// + /// Description of XamlSymbolSearch. + /// + public class XamlSymbolSearch : ISymbolSearch + { + public XamlSymbolSearch(IEntity entity) + { + } + + public double WorkAmount { + get { + throw new NotImplementedException(); + } + } + + public Task FindReferencesAsync(SymbolSearchArgs searchArguments, Action callback) + { + throw new NotImplementedException(); + } + } +}