diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs index ab84909aac..540b2bcd5d 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs @@ -83,6 +83,24 @@ namespace ICSharpCode.XamlBinding return text.Substring(offset, startIndex - offset + 1).Trim(); } + public static string GetWordAfterOffset(this string text, int startIndex) + { + if (string.IsNullOrEmpty(text)) + return string.Empty; + + int offset = startIndex = Math.Max(startIndex, 0); + + while (offset < text.Length && char.IsWhiteSpace(text[offset])) + offset++; + + while (offset < text.Length && !char.IsWhiteSpace(text[offset])) + offset++; + + offset = Math.Min(offset, text.Length - 1); + + return text.Substring(startIndex, offset - startIndex + 1).Trim(); + } + public static int GetLineNumber(this XObject item) { return (item as IXmlLineInfo).LineNumber; @@ -93,26 +111,6 @@ namespace ICSharpCode.XamlBinding return (item as IXmlLineInfo).LinePosition; } - public static void Remove(this XmlAttributeCollection coll, string name) - { - for (int i = 0; i < coll.Count; i++) { - if (coll[i].Name.Equals(name, StringComparison.Ordinal)) { - coll.RemoveAt(i); - i--; - } - } - } - - public static void Remove(this XmlAttributeCollection coll, string name, string namespaceURI) - { - for (int i = 0; i < coll.Count; i++) { - if (coll[i].LocalName.Equals(name, StringComparison.Ordinal) && coll[i].NamespaceURI.Equals(namespaceURI, StringComparison.Ordinal)) { - coll.RemoveAt(i); - i--; - } - } - } - public static IEnumerable RemoveEvents(this IEnumerable list) { foreach (var item in list) { @@ -124,15 +122,44 @@ namespace ICSharpCode.XamlBinding } } - public static IEnumerable RemoveProperties(this IEnumerable list) + public static bool IsCollectionType(this IClass c) { - foreach (var item in list) { - if (item is XamlCodeCompletionItem) { - var comItem = item as XamlCodeCompletionItem; - if (!(comItem.Entity is IProperty)) - yield return item; - } else yield return item; - } + if (c == null) + throw new ArgumentNullException("c"); + return c.ClassInheritanceTree.Any(cla => cla.FullyQualifiedName == "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 c) + { + if (c == null) + throw new ArgumentNullException("c"); + return c.ClassInheritanceTree.Any(cla => cla.FullyQualifiedName == "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; + } + + /// Works only if fullyQualyfiedClassName is the name of a class! + public static bool DerivesFrom(this IClass myClass, string fullyQualyfiedClassName) + { + return myClass.ClassInheritanceTreeClassesOnly.Any(c => c.FullyQualifiedName == fullyQualyfiedClassName); } } -} +} \ No newline at end of file diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs index d01735fb4f..4ed34fa20d 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs @@ -34,13 +34,35 @@ namespace ICSharpCode.XamlBinding return false; } + public static MarkupExtensionInfo GetInnermostMarkupExtensionInfo(MarkupExtensionInfo info) + { + var lastNamed = info.NamedArguments.LastOrDefault(); + var lastPositional = info.PositionalArguments.LastOrDefault(); + + if (lastNamed.Value != null) { + if (lastNamed.Value.IsString) + return info; + + return GetInnermostMarkupExtensionInfo(lastNamed.Value.ExtensionValue); + } else { + if (lastPositional != null) { + if (lastPositional.IsString) + return info; + + return GetInnermostMarkupExtensionInfo(lastPositional.ExtensionValue); + } + } + + return info; + } + public static string GetAttributeValue(string text, int line, int col, string name) { try { XmlReader reader = CreateReaderAtTarget(text, line, col); if (!reader.MoveToFirstAttribute()) { - /* int offset = GetOffsetFromFilePos(text, line, col) + 1; + /* int offset = GetOffsetFromFilePos(text, line, col) + 1; if (XmlParser.IsInsideAttributeValue(text, offset)) text = text.Substring(0, offset) + "\">"; @@ -52,7 +74,7 @@ namespace ICSharpCode.XamlBinding } reader = CreateReaderAtTarget(text, line, col); if (!reader.MoveToFirstAttribute()) */ - return null; + return null; } do { LoggingService.Debug("name: " + reader.Name + " value: " + reader.Value); @@ -132,8 +154,8 @@ namespace ICSharpCode.XamlBinding { var item = context.XmlnsDefinitions.FirstOrDefault(i => i.Value == CompletionDataHelper.XamlNamespace); - if (item.Key != null) - return item.Key; + if (item.Key != null) + return item.Key; return string.Empty; } @@ -173,7 +195,7 @@ namespace ICSharpCode.XamlBinding return content.Length; } } - + return offset + col - 1; } @@ -263,4 +285,4 @@ namespace ICSharpCode.XamlBinding return tmp; } } -} +} \ No newline at end of file diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlColorizer.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlColorizer.cs index ccc364a196..c6471585f6 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlColorizer.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlColorizer.cs @@ -114,7 +114,6 @@ namespace ICSharpCode.XamlBinding IEnumerable GetInfo() { int index = -1; - int ltCharIndex = -1; XamlContext context = null; List infos = new List(); diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItem.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItem.cs index 4d02331334..2921ee8075 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItem.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItem.cs @@ -42,6 +42,18 @@ namespace ICSharpCode.XamlBinding this.Text = text; } + public XamlCodeCompletionItem(IEntity entity, string prefix, string className, bool addOpeningBrace) + : base(entity) + { + if (string.IsNullOrEmpty(prefix)) + this.Text = className + "." + entity.Name; + else + this.Text = prefix + ":" + className + "." + entity.Name; + + if (addOpeningBrace) + this.Text = "<" + this.Text; + } + public override string ToString() { return "[" + this.Text + "]"; @@ -159,11 +171,14 @@ namespace ICSharpCode.XamlBinding 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; - foreach (Match match in Regex.Matches(name, "%[A-z0-9]*%")) { + while (namePatternRegex.IsMatch(name)) { + Match match = namePatternRegex.Match(name); switch (match.Value.ToLowerInvariant()) { case "%object%": if (char.IsUpper(match.Value[1])) @@ -277,4 +292,4 @@ namespace ICSharpCode.XamlBinding } } } -} +} \ No newline at end of file diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs index 6a5ccf437b..885de5f17c 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs @@ -35,7 +35,7 @@ namespace ICSharpCode.XamlBinding public static int CountWhiteSpacesAtEnd(string text) { if (string.IsNullOrEmpty(text)) - return 0; + return 0; int i = text.Length - 1; @@ -56,7 +56,8 @@ namespace ICSharpCode.XamlBinding XamlCodeCompletionItem cItem = item as XamlCodeCompletionItem; if (cItem.Entity is IProperty || cItem.Entity is IEvent) { - if (context.Editor.Document.GetCharAt(context.StartOffset - 1) != '.') { + if (context.Editor.Document.GetCharAt(context.StartOffset - 1) != '.' && + context.Editor.Document.GetCharAt(context.StartOffset - 1) != '<') { if (!item.Text.EndsWith("=", StringComparison.OrdinalIgnoreCase)) { context.Editor.Document.Insert(context.EndOffset, "=\"\""); context.Editor.Caret.Offset--; @@ -89,36 +90,6 @@ namespace ICSharpCode.XamlBinding XamlCodeCompletionBinding.Instance.CtrlSpace(context.Editor); } } - - if (cItem.Entity is IClass) { - IClass c = cItem.Entity as IClass; - if (c.FullyQualifiedName == "System.Windows.Style") { - string insertionString = ""; - if (!char.IsWhiteSpace(context.Editor.Document.GetCharAt(context.StartOffset - 1))) { - insertionString = " "; - } - - string prefix = Utils.GetXamlNamespacePrefix(CompletionDataHelper.ResolveCompletionContext(context.Editor, context.CompletionChar)); - if (!string.IsNullOrEmpty(prefix)) - prefix += ":"; - - insertionString += "TargetType=\"{" + prefix + "Type }\""; - context.Editor.Document.Insert(context.EndOffset, insertionString); - context.Editor.Caret.Offset = context.EndOffset + insertionString.Length - 2; - - XamlCodeCompletionBinding.Instance.CtrlSpace(context.Editor); - } else if (c.FullyQualifiedName == "System.Windows.Setter") { - string insertionString = ""; - if (!char.IsWhiteSpace(context.Editor.Document.GetCharAt(context.StartOffset - 1))) { - insertionString = " "; - } - insertionString += "Property=\"\""; - context.Editor.Document.Insert(context.EndOffset, insertionString); - context.Editor.Caret.Offset = context.EndOffset + insertionString.Length - 1; - - XamlCodeCompletionBinding.Instance.CtrlSpace(context.Editor); - } - } } if (item is NewEventCompletionItem) { @@ -193,4 +164,4 @@ namespace ICSharpCode.XamlBinding } } } -} +} \ No newline at end of file