diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/UtilsTests.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/UtilsTests.cs
index 912c751015..62bb433407 100644
--- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/UtilsTests.cs
+++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/UtilsTests.cs
@@ -18,117 +18,134 @@ namespace ICSharpCode.XamlBinding.Tests
public class UtilsTests
{
[Test]
- public void XmlNamespacesForOffsetSimple()
+ public void DiffTestSimple()
{
- string xaml = File.ReadAllText("Test1.xaml");
- int offset = xaml.IndexOf("CheckBox") + "CheckBox ".Length;
+ string xaml = "";
+ int offset = " {
- {"xmlns", "http://schemas.microsoft.com/netfx/2007/xaml/presentation"},
- {"xmlns:x", "http://schemas.microsoft.com/winfx/2006/xaml"}
- };
+ int actualResult = Utils.GetOffsetFromValueStart(xaml, offset);
- var result = Utils.GetXmlNamespacesForOffset(xaml, offset);
+ Assert.AreEqual(expectedResult, actualResult);
+ }
+
+ [Test]
+ public void DiffTestSimple2()
+ {
+ string xaml = "";
+ int offset = " {
- {"xmlns", "http://schemas.microsoft.com/netfx/2007/xaml/presentation"},
- {"xmlns:x", "http://schemas.microsoft.com/winfx/2006/xaml"},
- {"xmlns:y", "clr-namespace:ICSharpCode.Profiler.Controls;assembly=ICSharpCode.Profiler.Controls"}
- };
+ string text = @"SharpDevelop uses the MSBuild
+libraries for compilation. But when you compile a project
+inside SharpDevelop, there's more going on than a
+simple call to MSBuild.";
- var result = Utils.GetXmlNamespacesForOffset(xaml, offset);
+ int expected = 0;
+ int line = 1;
+ int col = 1;
- foreach (var p in result)
- Debug.Print(p.Key + " " + p.Value);
+ int result = Utils.GetOffsetFromFilePos(text, line, col);
- Assert.AreEqual(expectedResult, result, "Is not equal");
+ Assert.AreEqual(expected, result);
}
[Test]
- public void XmlNamespacesForOffsetComplex()
+ public void GetOffsetTest2()
{
- string xaml = File.ReadAllText("Test3.xaml");
- int offset = xaml.IndexOf("CheckBox") + "CheckBox ".Length;
+ string text = @"SharpDevelop uses the MSBuild
+libraries for compilation. But when you compile a project
+inside SharpDevelop, there's more going on than a
+simple call to MSBuild.";
- var expectedResult = new Dictionary {
- {"xmlns", "http://schemas.microsoft.com/netfx/2007/xaml/presentation"},
- {"xmlns:x", "clr-namespace:ICSharpCode.Profiler.Controls;assembly=ICSharpCode.Profiler.Controls"}
- };
+ int expected = 4;
+ int line = 1;
+ int col = 5;
- var result = Utils.GetXmlNamespacesForOffset(xaml, offset);
+ int result = Utils.GetOffsetFromFilePos(text, line, col);
- foreach (var p in result)
- Debug.Print(p.Key + " " + p.Value);
-
- Assert.AreEqual(expectedResult, result, "Is not equal");
+ Assert.AreEqual(expected, result);
}
[Test]
- public void DiffTestSimple()
+ public void GetOffsetTest3()
{
- string xaml = "";
- int offset = "";
- int offset = " { "xmlns", "xmlns:x", "xmlns:toolkit", "xmlns:chartingToolkit" };
+ int result = Utils.GetOffsetFromFilePos(text, line, col);
- Assert.AreEqual(expected.Count, list.Length, "Wrong count!");
- Assert.AreEqual(list, expected, "Wrong elements!");
+ Assert.AreEqual(expected, result);
}
[Test]
- public void ExistingAttributesWithInvalidSyntaxTest()
+ public void GetOffsetTest6()
{
- string xaml = " { "xmlns", "xmlns:x", "xmlns:toolkit", "xmlns:chartingToolkit" };
+ int result = Utils.GetOffsetFromFilePos(text, line, col);
- Assert.AreEqual(expected.Count, list.Length, "Wrong count!");
- Assert.AreEqual(list, expected, "Wrong elements!");
+ Assert.AreEqual(expected, result);
}
}
}
diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs
index e1c76934ca..12de96b84b 100644
--- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs
+++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs
@@ -41,27 +41,77 @@ namespace ICSharpCode.XamlBinding
public const string XamlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml";
- public static XamlContext ResolveContext(ITextEditor editor, char typedValue)
+ public static XamlContext ResolveContext(string text, string fileName, int line, int col)
{
- string text = editor.Document.Text;
- int offset = editor.Caret.Offset;
- XamlResolver resolver = new XamlResolver();
+ int offset = Utils.GetOffsetFromFilePos(text, line, col);
- ParseInformation info = ParserService.GetParseInformation(editor.FileName);
+ ParseInformation info = ParserService.GetParseInformation(fileName);
XmlElementPath path = XmlParser.GetActiveElementStartPathAtIndex(text, offset);
string attribute = XmlParser.GetAttributeNameAtIndex(text, offset);
string attributeValue = XmlParser.GetAttributeValueAtIndex(text, offset);
bool inAttributeValue = XmlParser.IsInsideAttributeValue(text, offset);
int offsetFromValueStart = Utils.GetOffsetFromValueStart(text, offset);
- ResolveResult rr = null;
AttributeValue value = null;
- XamlExpressionContext cxt = new XamlExpressionContext(path, attribute, inAttributeValue);
+ XamlContextDescription description = XamlContextDescription.InTag;
+
+ if (path == null || path.Elements.Count == 0) {
+ description = XamlContextDescription.None;
+ path = XmlParser.GetParentElementPath(text.Substring(0, offset));
+ } else {
+ int ltOffset = XmlParser.GetActiveElementStartIndex(text, offset);
+ if (ltOffset == -1)
+ description = XamlContextDescription.AtTag;
+ else {
+ string space = text.Substring(ltOffset + 1, offset - ltOffset - 1);
+ var last = path.Elements.LastOrDefault();
+ if (last != null && last.ToString().StartsWith(space, StringComparison.Ordinal))
+ description = XamlContextDescription.AtTag;
+ }
+ }
+
+ if (inAttributeValue)
+ description = XamlContextDescription.InAttributeValue;
+
+ if (value != null && !value.IsString)
+ description = XamlContextDescription.InMarkupExtension;
+
+ if (Utils.IsInsideXmlComment(text, offset))
+ description = XamlContextDescription.InComment;
- if (!string.IsNullOrEmpty(attribute)) {
- rr = resolver.Resolve(new ExpressionResult(attribute, cxt) { Region = new DomRegion(1,1) }, info, text);
+ Dictionary xmlnsDefs = new Dictionary();
+
+ using (XmlTextReader reader = Utils.CreateReaderAtTarget(text, line, col)) {
+ xmlnsDefs.AddRange(reader.GetNamespacesInScope(XmlNamespaceScope.All));
}
+ var context = new XamlContext() {
+ Description = description,
+ AttributeName = attribute,
+ AttributeValue = value,
+ RawAttributeValue = attributeValue,
+ ValueStartOffset = offsetFromValueStart,
+ Path = (path == null || path.Elements.Count == 0) ? null : path,
+ XmlnsDefinitions = xmlnsDefs,
+ ParseInformation = info
+ };
+
+ return context;
+ }
+
+ public static XamlCompletionContext ResolveCompletionContext(ITextEditor editor, char typedValue)
+ {
+ string text = editor.Document.Text;
+ int offset = editor.Caret.Offset;
+
+ ParseInformation info = ParserService.GetParseInformation(editor.FileName);
+ XmlElementPath path = XmlParser.GetActiveElementStartPathAtIndex(text, offset);
+ string attribute = XmlParser.GetAttributeNameAtIndex(text, offset);
+ string attributeValue = XmlParser.GetAttributeValueAtIndex(text, offset);
+ bool inAttributeValue = XmlParser.IsInsideAttributeValue(text, offset);
+ int offsetFromValueStart = Utils.GetOffsetFromValueStart(text, offset);
+ AttributeValue value = null;
+
value = MarkupExtensionParser.ParseValue(attributeValue);
XamlContextDescription description = XamlContextDescription.InTag;
@@ -92,33 +142,30 @@ namespace ICSharpCode.XamlBinding
Dictionary xmlnsDefs = new Dictionary();
- using (XmlTextReader reader = CreateReaderAtTarget(editor.Document.Text, editor.Caret.Line, editor.Caret.Column)) {
-
+ using (XmlTextReader reader = Utils.CreateReaderAtTarget(text, editor.Caret.Line, editor.Caret.Column)) {
+ xmlnsDefs.AddRange(reader.GetNamespacesInScope(XmlNamespaceScope.All));
}
- var context = new XamlContext() {
+ var context = new XamlCompletionContext() {
PressedKey = typedValue,
Description = description,
- ResolvedExpression = rr,
AttributeName = attribute,
AttributeValue = value,
RawAttributeValue = attributeValue,
ValueStartOffset = offsetFromValueStart,
Path = (path == null || path.Elements.Count == 0) ? null : path,
- XmlnsDefinitions = xmlnsDefs
+ XmlnsDefinitions = xmlnsDefs,
+ ParseInformation = info,
+ Editor = editor
};
- LoggingService.Debug(context);
-
return context;
}
- static List CreateListForAttributeName(ITextEditor editor, ParseInformation parseInfo, XamlExpressionContext context, string[] existingItems)
+ static List CreateListForAttributeName(XamlCompletionContext context, string[] existingItems)
{
- if (context.ElementPath.Elements.Count == 0)
- return null;
- QualifiedName lastElement = context.ElementPath.Elements.LastOrDefault();
- XamlCompilationUnit cu = parseInfo.BestCompilationUnit as XamlCompilationUnit;
+ QualifiedName lastElement = context.Path.Elements.LastOrDefault();
+ XamlCompilationUnit cu = context.ParseInformation.BestCompilationUnit as XamlCompilationUnit;
if (cu == null)
return null;
IReturnType rt = cu.CreateType(lastElement.Namespace, lastElement.Name.Trim('.'));
@@ -126,7 +173,7 @@ namespace ICSharpCode.XamlBinding
return null;
var list = new List();
- string xamlPrefix = Utils.GetXamlNamespacePrefix(editor.Document.Text, editor.Caret.Offset);
+ string xamlPrefix = Utils.GetXamlNamespacePrefix(context);
foreach (string item in xamlNamespaceAttributes) {
if (!existingItems.Contains(xamlPrefix + ":" + item))
@@ -252,7 +299,7 @@ namespace ICSharpCode.XamlBinding
return neededItems.ToList();
}
- public static ICompletionItemList CreateListForContext(ITextEditor editor, XamlContext context)
+ public static ICompletionItemList CreateListForContext(ITextEditor editor, XamlCompletionContext context)
{
XamlCompletionItemList list = new XamlCompletionItemList();
ParseInformation info = ParserService.GetParseInformation(editor.FileName);
@@ -267,18 +314,19 @@ namespace ICSharpCode.XamlBinding
case XamlContextDescription.AtTag:
list.Items.AddRange(standardElements);
if (editor.Document.GetCharAt(editor.Caret.Offset - 1) == '.' || context.PressedKey == '.') {
- var existing = Utils.GetListOfExistingAttributeNames(editor.Document.Text, Utils.GetParentElementStart(editor));
- list.Items.AddRange(CreateListForAttributeName(editor, info, new XamlExpressionContext(context.Path, null, false), existing).RemoveEvents());
+ var loc = editor.Document.OffsetToPosition(Utils.GetParentElementStart(editor));
+ var existing = Utils.GetListOfExistingAttributeNames(editor.Document.Text, loc.Line, loc.Column);
+ list.Items.AddRange(CreateListForAttributeName(context, existing).RemoveEvents());
} else
list.Items.AddRange(CreateListForElement(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column, false));
break;
case XamlContextDescription.InTag:
- var existingAttribs = Utils.GetListOfExistingAttributeNames(editor.Document.Text, editor.Caret.Offset);
- list.Items.AddRange(CreateListForAttributeName(editor, info, new XamlExpressionContext(context.Path, null, false), existingAttribs));
+ var existingAttribs = Utils.GetListOfExistingAttributeNames(editor.Document.Text, editor.Caret.Line, editor.Caret.Column);
+ list.Items.AddRange(CreateListForAttributeName(context, existingAttribs));
QualifiedName last = context.Path.Elements[context.Path.Elements.Count - 1];
- TypeResolveResult trr = new XamlResolver().Resolve(new ExpressionResult(last.Name, new XamlExpressionContext(context.Path, null, false)), info, editor.Document.Text) as TypeResolveResult;
+ TypeResolveResult trr = new XamlResolver().Resolve(new ExpressionResult(last.Name, context), info, editor.Document.Text) as TypeResolveResult;
if (trr != null && trr.ResolvedType != null && trr.ResolvedType.GetUnderlyingClass() != null) {
if (trr.ResolvedType.GetUnderlyingClass().ClassInheritanceTree.Any(i => i.FullyQualifiedName == "System.Windows.DependencyObject")) {
@@ -313,10 +361,10 @@ namespace ICSharpCode.XamlBinding
return false;
}
- public static IEnumerable CreateMarkupExtensionInsight(XamlContext context, ParseInformation info, ITextEditor editor)
+ public static IEnumerable CreateMarkupExtensionInsight(XamlCompletionContext context, ParseInformation info, ITextEditor editor)
{
var markup = GetInnermostMarkup(context.AttributeValue.ExtensionValue);
- var trr = ResolveMarkupExtensionType(markup, info, editor, context.Path);
+ var trr = ResolveMarkupExtensionType(markup, context);
if (trr != null) {
var ctors = trr.ResolvedType
@@ -331,14 +379,14 @@ namespace ICSharpCode.XamlBinding
}
}
- public static ICompletionItemList CreateMarkupExtensionCompletion(XamlContext context, ParseInformation info, ITextEditor editor)
+ public static ICompletionItemList CreateMarkupExtensionCompletion(XamlCompletionContext context, ParseInformation info, ITextEditor editor)
{
var list = new XamlCompletionItemList();
var path = XmlParser.GetActiveElementStartPathAtIndex(editor.Document.Text, editor.Caret.Offset);
var markup = GetInnermostMarkup(context.AttributeValue.ExtensionValue);
- var trr = ResolveMarkupExtensionType(markup, info, editor, path);
+ var trr = ResolveMarkupExtensionType(markup, context);
if (trr == null) {
list.Items.AddRange(CreateListOfMarkupExtensions(info, editor.Document.Text, editor.Caret.Line, editor.Caret.Column));
@@ -366,7 +414,7 @@ namespace ICSharpCode.XamlBinding
}
}
- static void DoPositionalArgsCompletion(XamlCompletionItemList list, XamlContext context, TypeResolveResult trr, ParseInformation info, ITextEditor editor)
+ static void DoPositionalArgsCompletion(XamlCompletionItemList list, XamlCompletionContext context, TypeResolveResult trr, ParseInformation info, ITextEditor editor)
{
switch (trr.ResolvedType.FullyQualifiedName) {
case "System.Windows.Markup.ArrayExtension":
@@ -375,7 +423,7 @@ namespace ICSharpCode.XamlBinding
break;
case "System.Windows.Markup.StaticExtension":
if (context.AttributeValue.ExtensionValue.PositionalArguments.Count == 1 && context.PressedKey == ' ') break;
- if (context.AttributeValue.ExtensionValue.PositionalArguments.Count <= 1) DoStaticExtensionCompletion(list, context, info, editor);
+ if (context.AttributeValue.ExtensionValue.PositionalArguments.Count <= 1) DoStaticExtensionCompletion(list, context);
break;
case "System.Windows.Markup.TypeExtension":
if (context.AttributeValue.ExtensionValue.PositionalArguments.Count == 1 && context.PressedKey == ' ') break;
@@ -421,7 +469,7 @@ namespace ICSharpCode.XamlBinding
}
}
- public static IEnumerable MemberCompletion(ITextEditor editor, IReturnType type)
+ public static IEnumerable MemberCompletion(XamlCompletionContext context, IReturnType type)
{
if (type == null || type.GetUnderlyingClass() == null)
yield break;
@@ -442,24 +490,27 @@ namespace ICSharpCode.XamlBinding
case ClassType.Delegate:
IMethod invoker = c.Methods.Where(method => method.Name == "Invoke").FirstOrDefault();
if (invoker != null) {
- var path = XmlParser.GetActiveElementStartPathAtIndex(editor.Document.Text, editor.Caret.Offset);
- if (path != null && path.Elements.Count > 0) {
- var item = path.Elements[path.Elements.Count - 1];
- string attribute = XmlParser.GetAttributeNameAtIndex(editor.Document.Text, editor.Caret.Offset);
- var evt = ResolveAttribute(attribute, editor) as IEvent;
+ if (context.Path != null) {
+ var item = context.Path.Elements.LastOrDefault();
+ var evt = ResolveAttribute(context.AttributeName, context) as IEvent;
if (evt == null)
break;
- string prefix = Utils.GetXamlNamespacePrefix(editor.Document.Text, editor.Caret.Offset);
- string name = Utils.GetAttributeValue(editor.Document.Text, editor.Caret.Offset, "name");
- if (string.IsNullOrEmpty(name))
- name = Utils.GetAttributeValue(editor.Document.Text, editor.Caret.Offset, (string.IsNullOrEmpty(prefix) ? "" : prefix + ":") + "name");
+ int offset = XmlParser.GetActiveElementStartIndex(context.Editor.Document.Text, context.Editor.Caret.Offset);
+
+ if (offset == -1)
+ break;
+
+ var loc = context.Editor.Document.OffsetToPosition(offset);
- Debug.Print("prefix: " + prefix + " name: " + name);
+ string prefix = Utils.GetXamlNamespacePrefix(context);
+ string name = Utils.GetAttributeValue(context.Editor.Document.Text, loc.Line, loc.Column + 1, "name");
+ if (string.IsNullOrEmpty(name))
+ name = Utils.GetAttributeValue(context.Editor.Document.Text, loc.Line, loc.Column + 1, (string.IsNullOrEmpty(prefix) ? "" : prefix + ":") + "name");
yield return new NewEventCompletionItem(evt, (string.IsNullOrEmpty(name)) ? item.Name : name);
- foreach (var eventItem in CompletionDataHelper.AddMatchingEventHandlers(editor, invoker))
+ foreach (var eventItem in CompletionDataHelper.AddMatchingEventHandlers(context.Editor, invoker))
yield return eventItem;
}
}
@@ -480,42 +531,38 @@ namespace ICSharpCode.XamlBinding
}
}
- static IEntity ResolveAttribute(string attribute, ITextEditor editor)
+ static IEntity ResolveAttribute(string attribute, XamlCompletionContext context)
{
XamlResolver resolver = new XamlResolver();
-
- var path = XmlParser.GetActiveElementStartPathAtIndex(editor.Document.Text, editor.Caret.Offset);
- var exp = new ExpressionResult(attribute, new XamlExpressionContext(path, attribute, false));
- var info = ParserService.GetParseInformation(editor.FileName);
-
- var mrr = resolver.Resolve(exp, info, editor.Document.Text) as MemberResolveResult;
+ var exp = new ExpressionResult(attribute, context);
+ var mrr = resolver.Resolve(exp, context.ParseInformation, context.Editor.Document.Text) as MemberResolveResult;
return mrr.ResolvedMember;
}
- static void DoStaticExtensionCompletion(XamlCompletionItemList list, XamlContext context, ParseInformation info, ITextEditor editor)
+ static void DoStaticExtensionCompletion(XamlCompletionItemList list, XamlCompletionContext context)
{
AttributeValue selItem = context.AttributeValue.ExtensionValue.PositionalArguments.LastOrDefault();
if (context.PressedKey == '.') {
if (selItem != null && selItem.IsString) {
- var rr = ResolveStringValue(selItem.StringValue, context.Path, info, editor) as TypeResolveResult;
+ var rr = ResolveStringValue(selItem.StringValue, context) as TypeResolveResult;
if (rr != null)
- list.Items.AddRange(MemberCompletion(editor, rr.ResolvedType));
+ list.Items.AddRange(MemberCompletion(context, rr.ResolvedType));
}
} else {
if (selItem != null && selItem.IsString) {
int index = selItem.StringValue.IndexOf('.');
string s = (index > -1) ? selItem.StringValue.Substring(0, index) : selItem.StringValue;
- var rr = ResolveStringValue(s, context.Path, info, editor) as TypeResolveResult;
+ var rr = ResolveStringValue(s, context) as TypeResolveResult;
if (rr != null) {
- list.Items.AddRange(MemberCompletion(editor, rr.ResolvedType));
+ list.Items.AddRange(MemberCompletion(context, rr.ResolvedType));
list.PreselectionLength = selItem.StringValue.Length - index - 1;
list.SuggestedItem = list.Items.FirstOrDefault(item => item.Text.StartsWith(selItem.StringValue.Substring(index + 1), StringComparison.OrdinalIgnoreCase));
} else
- DoStaticTypeCompletion(selItem, list, info, editor);
+ DoStaticTypeCompletion(selItem, list, context.ParseInformation, context.Editor);
} else {
- DoStaticTypeCompletion(selItem, list, info, editor);
+ DoStaticTypeCompletion(selItem, list, context.ParseInformation, context.Editor);
}
}
}
@@ -535,10 +582,10 @@ namespace ICSharpCode.XamlBinding
}
}
- static ResolveResult ResolveStringValue(string value, XmlElementPath path, ParseInformation info, ITextEditor editor)
+ static ResolveResult ResolveStringValue(string value, XamlCompletionContext context)
{
var resolver = new XamlResolver();
- var rr = resolver.Resolve(new ExpressionResult(value, new XamlExpressionContext(path, string.Empty, false)), info, editor.Document.Text);
+ var rr = resolver.Resolve(new ExpressionResult(value, context), context.ParseInformation, context.Editor.Document.Text);
return rr;
}
@@ -563,20 +610,19 @@ namespace ICSharpCode.XamlBinding
return markup;
}
- public static TypeResolveResult ResolveMarkupExtensionType(MarkupExtensionInfo markup, ParseInformation info, ITextEditor editor, XmlElementPath path)
+ public static TypeResolveResult ResolveMarkupExtensionType(MarkupExtensionInfo markup, XamlCompletionContext context)
{
XamlResolver resolver = new XamlResolver();
- TypeResolveResult trr = resolver.Resolve(new ExpressionResult(markup.ExtensionType, new XamlExpressionContext(path, null, false)), info, editor.Document.Text) as TypeResolveResult;
- if (trr == null) trr = resolver.Resolve(new ExpressionResult(markup.ExtensionType + "Extension", new XamlExpressionContext(path, null, false)), info, editor.Document.Text) as TypeResolveResult;
+ TypeResolveResult trr = resolver.Resolve(new ExpressionResult(markup.ExtensionType, context), context.ParseInformation, context.Editor.Document.Text) as TypeResolveResult;
+ if (trr == null) trr = resolver.Resolve(new ExpressionResult(markup.ExtensionType + "Extension", context), context.ParseInformation, context.Editor.Document.Text) as TypeResolveResult;
return trr;
}
- public static TypeResolveResult ResolveType(string name, XamlContext context, ITextEditor editor)
+ public static TypeResolveResult ResolveType(string name, XamlCompletionContext context)
{
return new XamlResolver()
- .Resolve(new ExpressionResult(name, new XamlExpressionContext(context.Path, null, false)),
- ParserService.GetParseInformation(editor.FileName), editor.Document.Text) as TypeResolveResult;
+ .Resolve(new ExpressionResult(name, context), context.ParseInformation, context.Editor.Document.Text) as TypeResolveResult;
}
public static IEnumerable AddMatchingEventHandlers(ITextEditor editor, IMethod delegateInvoker)
@@ -622,22 +668,9 @@ namespace ICSharpCode.XamlBinding
return result;
}
- static XmlTextReader CreateReaderAtTarget(string fileContent, int caretLine, int caretColumn)
- {
- XmlTextReader r = new XmlTextReader(new StringReader(fileContent));
-
- try {
- r.WhitespaceHandling = WhitespaceHandling.Significant;
- // move reader to correct position
- while (r.Read() && !IsReaderAtTarget(r, caretLine, caretColumn)) { }
- } catch (XmlException) {}
-
- return r;
- }
-
static string GetPrefixForNamespace(string @namespace, string fileContent, int caretLine, int caretColumn)
{
- using (XmlTextReader r = CreateReaderAtTarget(fileContent, caretLine, caretColumn)) {
+ using (XmlTextReader r = Utils.CreateReaderAtTarget(fileContent, caretLine, caretColumn)) {
foreach (var item in r.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml)) {
if (item.Value == @namespace) {
return item.Key;
@@ -650,7 +683,7 @@ namespace ICSharpCode.XamlBinding
static IDictionary> GetClassesFromContext(ParseInformation parseInfo, string fileContent, int caretLine, int caretColumn)
{
- using (XmlTextReader r = CreateReaderAtTarget(fileContent, caretLine, caretColumn)) {
+ using (XmlTextReader r = Utils.CreateReaderAtTarget(fileContent, caretLine, caretColumn)) {
IProjectContent pc = parseInfo.BestCompilationUnit.ProjectContent;
var result = new Dictionary>();
@@ -665,7 +698,7 @@ namespace ICSharpCode.XamlBinding
static List GetListOfAttachedProperties(ParseInformation parseInfo, string fileContent, int caretLine, int caretColumn, string[] existingItems)
{
- using (XmlTextReader r = CreateReaderAtTarget(fileContent, caretLine, caretColumn)) {
+ using (XmlTextReader r = Utils.CreateReaderAtTarget(fileContent, caretLine, caretColumn)) {
List result = new List();
IProjectContent pc = parseInfo.BestCompilationUnit.ProjectContent;
diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs
index daf78d900c..65a82f1c6e 100644
--- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs
+++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs
@@ -24,54 +24,25 @@ namespace ICSharpCode.XamlBinding
///
public static class Utils
{
- public static bool HasMatchingEndTag(string tagname, string text, int offset)
+ internal static bool IsReaderAtTarget(XmlTextReader r, int line, int col)
{
- int index = XmlParser.GetActiveElementStartIndex(text, offset);
- if (index == -1)
+ if (r.LineNumber > line)
+ return true;
+ else if (r.LineNumber == line)
+ return r.LinePosition >= col;
+ else
return false;
-
- text = text.Substring(index);
-
- var path = XmlParser.GetActiveElementStartPathAtIndex(text, index);
-
- XmlReader reader = XmlTextReader.Create(new StringReader(text));
- int startTags = 0;
- try {
- while (reader.Read()) {
- switch (reader.NodeType) {
- case XmlNodeType.Element:
- if (!reader.IsEmptyElement)
- startTags++;
- break;
- case XmlNodeType.EndElement:
- startTags--;
- if (startTags == 0 && tagname == reader.Name) {
- return true;
- }
- break;
- }
- }
- } catch (XmlException e) {
- Debug.Print(e.ToString());
- return false;
- }
-
- return false;
}
- public static string GetAttributeValue(string text, int offset, string name)
+ public static string GetAttributeValue(string text, int line, int col, string name)
{
- text = SimplifyToSingleElement(text, offset, "Test");
-
- if (text == null)
- return null;
-
- XmlTextReader reader = new XmlTextReader(new StringReader(text));
- reader.XmlResolver = null;
-
- try {
- reader.ReadToFollowing("Test");
+ try {
+ XmlTextReader reader = new XmlTextReader(new StringReader(text));
+ reader.XmlResolver = null;
+ while (reader.Read() && !IsReaderAtTarget(reader, line, col)) { }
+
+
if (!reader.MoveToFirstAttribute())
return null;
@@ -89,68 +60,6 @@ namespace ICSharpCode.XamlBinding
return null;
}
- public static Dictionary GetXmlNamespacesForOffset(string fileContent, int offset)
- {
- if (fileContent == null)
- throw new ArgumentNullException("fileContent");
- if (offset < 0 || offset > fileContent.Length)
- throw new ArgumentOutOfRangeException("offset", offset, "Value must be between 0 and " + fileContent.Length);
-
- var map = new Dictionary();
-
- int endIndex = fileContent.IndexOfAny(new char[] {'<', '>'}, offset);
- if (endIndex > -1)
- fileContent = fileContent.Substring(0, endIndex + 1);
-
- int lastWhiteSpacePos = fileContent.LastIndexOfAny(new char[] {' ', '\t', '\n', '\r'});
-
- bool inDouble = false, inSingle = false;
-
- for (int i = 0; i < fileContent.Length; i++) {
- if (fileContent[i] == '"' && !inSingle)
- inDouble = !inDouble;
- if (fileContent[i] == '\'' && !inDouble)
- inSingle = !inSingle;
- if (fileContent[i] == '>') {
- int lastDelimiterPos = fileContent.Substring(0, i + 1).LastIndexOfAny(new char[] {'>', '/'});
- if (inDouble) {
- fileContent.Insert(lastDelimiterPos, "\"");
- i++;
- inDouble = false;
- }
- if (inSingle) {
- fileContent.Insert(lastDelimiterPos, "'");
- inSingle = false;
- i++;
- }
- }
- }
-
- fileContent = fileContent.Replace("", " ").Replace("?>", " ").Replace("<", " ").Replace("/>", " ").Replace(">", " ").Replace("\n", " ").Replace("\r", " ").Replace("\t", " ");
- while (fileContent.Contains(" "))
- fileContent = fileContent.Replace(" ", " ");
-
- fileContent = fileContent.Replace("= \"", "=\"");
- fileContent = fileContent.Replace(" =\"", "=\"");
-
- Debug.Print(fileContent);
-
- string[] data = fileContent.Split(' ');
-
- var filter1 = data.Where(s => s.StartsWith("xmlns"));
-
- foreach (string item in filter1) {
- string[] parts = item.Split(new char[] {'='}, 2);
- if (parts.Length == 2) {
- if (map.ContainsKey(parts[0])) // replace namespace with new one
- map.Remove(parts[0]);
- map.Add(parts[0], parts[1].Trim('"', '\''));
- }
- }
-
- return map;
- }
-
public static int GetOffsetFromValueStart(string xaml, int offset)
{
if (xaml == null)
@@ -166,29 +75,25 @@ namespace ICSharpCode.XamlBinding
return offset - start - 1;
}
- public static string[] GetListOfExistingAttributeNames(string text, int offset)
+ public static string[] GetListOfExistingAttributeNames(string text, int line, int col)
{
List list = new List();
- text = SimplifyToSingleElement(text, offset, "Test");
-
if (text == null)
return list.ToArray();
- XmlReader reader = XmlTextReader.Create(new StringReader(text));
-
- try {
- reader.ReadToFollowing("Test");
-
- if (!reader.MoveToFirstAttribute())
- return list.ToArray();
-
- do {
- LoggingService.Debug("name: " + reader.Name + " value: " + reader.Value);
- list.Add(reader.Name);
- } while (reader.MoveToNextAttribute());
- } catch (XmlException e) {
- Debug.Print(e.ToString());
+ using (XmlReader reader = CreateReaderAtTarget(text, line, col)) {
+ try {
+ if (!reader.MoveToFirstAttribute())
+ return list.ToArray();
+
+ do {
+ LoggingService.Debug("name: " + reader.Name + " value: " + reader.Value);
+ list.Add(reader.Name);
+ } while (reader.MoveToNextAttribute());
+ } catch (XmlException e) {
+ Debug.Print(e.ToString());
+ }
}
foreach (var item in list)
@@ -214,44 +119,13 @@ namespace ICSharpCode.XamlBinding
}
static char[] whitespace = new char[] {' ', '\t', '\n', '\r'};
-
- static string SimplifyToSingleElement(string text, int offset, string name)
- {
- int index = XmlParser.GetActiveElementStartIndex(text, offset);
- if (index == -1) return null;
- index = text.IndexOfAny(whitespace, index);
- if (index == -1) return null;
- string newText = text.Substring(index);
- int endIndex = newText.IndexOfAny(new char[] { '<', '>' });
- if (endIndex == -1)
- endIndex = newText.Length;
- newText = newText.Substring(0, endIndex).Trim(' ', '\t', '\n', '\r', '/');
- LoggingService.Debug("text: '" + newText + "'");
- if (!newText.EndsWith("\"") && newText.LastIndexOfAny(whitespace) > -1) {
- newText = newText.Substring(0, newText.LastIndexOfAny(whitespace));
- }
-
- string namespaceDecls = "";
-
- var list = Utils.GetXmlNamespacesForOffset(text, offset);
-
- foreach (var item in list) {
- if (!Regex.IsMatch(text, item.Key + "\\s*=\\s*\""))
- namespaceDecls += item.Key + "=\"" + item.Value + "\" ";
- }
-
- text = "<" + name + " " + newText + " " + namespaceDecls + " />";
-
- return text;
- }
- public static string GetXamlNamespacePrefix(string xaml, int offset)
+ public static string GetXamlNamespacePrefix(XamlContext context)
{
- var list = Utils.GetXmlNamespacesForOffset(xaml, offset);
- var item = list.FirstOrDefault(i => i.Value == CompletionDataHelper.XamlNamespace);
-
- if (item.Key.StartsWith("xmlns:", StringComparison.OrdinalIgnoreCase))
- return item.Key.Substring("xmlns:".Length);
+ var item = context.XmlnsDefinitions.FirstOrDefault(i => i.Value == CompletionDataHelper.XamlNamespace);
+
+ if (item.Key != null)
+ return item.Key;
return string.Empty;
}
@@ -273,6 +147,28 @@ namespace ICSharpCode.XamlBinding
return interestingPart.LastIndexOf("