Browse Source

fix issues with member value completion, event completion etc.

pull/32/merge
Siegfried Pammer 13 years ago
parent
commit
c0680b4e33
  1. 4
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs
  2. 1004
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs
  3. 15
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlAstResolver.cs
  4. 1
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj
  5. 154
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCodeCompletionBinding.cs
  6. 257
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs
  7. 12
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs

4
src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs

@ -690,8 +690,8 @@ namespace ICSharpCode.XamlBinding @@ -690,8 +690,8 @@ namespace ICSharpCode.XamlBinding
IMethod invoker = td.GetMethods(method => method.Name == "Invoke").FirstOrDefault();
if (invoker != null && context.ActiveElement != null) {
var item = context.ActiveElement;
var resolver = new XamlResolver(compilation);
var mrr = resolver.ResolveExpression(context.Attribute.ToQualifiedName().FullXmlName, context) as MemberResolveResult;
var resolver = new XamlAstResolver(compilation, context.ParseInformation);
var mrr = resolver.ResolveAttribute(context.Attribute) as MemberResolveResult;
IEvent evt;
if (mrr == null || (evt = mrr.Member as IEvent) == null)
return EmptyList<ICompletionItem>.Instance;

1004
src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs

File diff suppressed because it is too large Load Diff

15
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlAstResolver.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.XamlBinding @@ -52,7 +52,7 @@ namespace ICSharpCode.XamlBinding
return ErrorResolveResult.UnknownError;
}
internal ResolveResult ResolveAttribute(AXmlAttribute attribute, int offset, CancellationToken cancellationToken = default(CancellationToken))
internal ResolveResult ResolveAttribute(AXmlAttribute attribute, int offset = -1, CancellationToken cancellationToken = default(CancellationToken))
{
IMember member = null, underlying = null;
IType type = null;
@ -63,7 +63,7 @@ namespace ICSharpCode.XamlBinding @@ -63,7 +63,7 @@ namespace ICSharpCode.XamlBinding
propertyName = propertyName.Substring(propertyName.IndexOf('.') + 1);
ITypeReference reference = XamlUnresolvedFile.CreateTypeReference(namespaceName, name);
type = reference.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly));
member = FindMember(type, propertyName);
member = FindMember(type, propertyName);
if (member == null)
member = FindAttachedMember(type, propertyName, out underlying);
} else {
@ -73,7 +73,7 @@ namespace ICSharpCode.XamlBinding @@ -73,7 +73,7 @@ namespace ICSharpCode.XamlBinding
}
if (member == null)
return new UnknownMemberResolveResult(type, propertyName, EmptyList<IType>.Instance);
if (attribute.ValueSegment.Contains(offset, 1))
if (offset > -1 && attribute.ValueSegment.Contains(offset, 1))
return ResolveAttributeValue(member, attribute, cancellationToken);
if (underlying != null)
return new AttachedMemberResolveResult(new TypeResolveResult(underlying.DeclaringType), underlying, member);
@ -118,10 +118,7 @@ namespace ICSharpCode.XamlBinding @@ -118,10 +118,7 @@ namespace ICSharpCode.XamlBinding
IMember member = type.GetProperties(p => p.Name == propertyName).FirstOrDefault();
if (member != null)
return member;
member = type.GetEvents(e => e.Name == propertyName).FirstOrDefault();
if (member != null)
return member;
return null;
return type.GetEvents(e => e.Name == propertyName).FirstOrDefault();
}
IMember FindAttachedMember(IType type, string propertyName, out IMember underlyingMember)
@ -133,7 +130,7 @@ namespace ICSharpCode.XamlBinding @@ -133,7 +130,7 @@ namespace ICSharpCode.XamlBinding
ITypeResolveContext localContext = new SimpleTypeResolveContext(type.GetDefinition());
if (underlyingMember != null)
return new DefaultUnresolvedProperty { Name = propertyName }
.CreateResolved(localContext);
.CreateResolved(localContext);
underlyingMember = type
.GetMethods(m => m.IsPublic && m.IsStatic && m.Parameters.Count == 2
@ -141,7 +138,7 @@ namespace ICSharpCode.XamlBinding @@ -141,7 +138,7 @@ namespace ICSharpCode.XamlBinding
.FirstOrDefault();
if (underlyingMember != null)
return new DefaultUnresolvedEvent { Name = propertyName }
.CreateResolved(localContext);
.CreateResolved(localContext);
return null;
}

1
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj

@ -66,7 +66,6 @@ @@ -66,7 +66,6 @@
<ItemGroup>
<Compile Include="AttachedMemberResolveResult.cs" />
<Compile Include="CompletionDataGenerator.cs" />
<Compile Include="CompletionDataHelper.cs" />
<Compile Include="XamlAstResolver.cs" />
<Compile Include="XamlCodeCompletionBinding.cs" />
<Compile Include="XamlCompletionItem.cs" />

154
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCodeCompletionBinding.cs

@ -54,7 +54,7 @@ namespace ICSharpCode.XamlBinding @@ -54,7 +54,7 @@ namespace ICSharpCode.XamlBinding
if (endMarkerCount % 2 != 0) {
editor.Document.Insert(editor.Caret.Offset, ch.ToString());
editor.Caret.Offset--;
this.CtrlSpace(editor);
CtrlSpace(editor);
return CodeCompletionKeyPressResult.Completed;
}
}
@ -85,8 +85,8 @@ namespace ICSharpCode.XamlBinding @@ -85,8 +85,8 @@ namespace ICSharpCode.XamlBinding
}
break;
case XamlContextDescription.InMarkupExtension:
// if (DoMarkupExtensionCompletion(context))
// return CodeCompletionKeyPressResult.Completed;
if (DoMarkupExtensionCompletion(context))
return CodeCompletionKeyPressResult.Completed;
break;
case XamlContextDescription.InAttributeValue:
if (editor.SelectionLength != 0)
@ -110,7 +110,7 @@ namespace ICSharpCode.XamlBinding @@ -110,7 +110,7 @@ namespace ICSharpCode.XamlBinding
editor.Document.Insert(editor.Caret.Offset, "[]");
editor.Caret.Offset--;
this.CtrlSpace(editor);
CtrlSpace(editor);
return CodeCompletionKeyPressResult.EatKey;
}
break;
@ -147,7 +147,7 @@ namespace ICSharpCode.XamlBinding @@ -147,7 +147,7 @@ namespace ICSharpCode.XamlBinding
editor.Caret.Offset++;
}
this.CtrlSpace(editor);
CtrlSpace(editor);
return CodeCompletionKeyPressResult.EatKey;
} else {
DoMarkupExtensionCompletion(context);
@ -161,7 +161,7 @@ namespace ICSharpCode.XamlBinding @@ -161,7 +161,7 @@ namespace ICSharpCode.XamlBinding
string attributeName = (context.Attribute != null) ? context.Attribute.Name : string.Empty;
if (!attributeName.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase)) {
return this.CtrlSpace(editor, context)
return CtrlSpace(editor, context)
? CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion
: CodeCompletionKeyPressResult.None;
}
@ -186,72 +186,38 @@ namespace ICSharpCode.XamlBinding @@ -186,72 +186,38 @@ namespace ICSharpCode.XamlBinding
bool CtrlSpace(ITextEditor editor, XamlCompletionContext context)
{
if (context.Description == XamlContextDescription.InComment
|| context.Description == XamlContextDescription.InCData)
|| context.Description == XamlContextDescription.InCData
|| context.ActiveElement == null) {
return false;
if (context.ActiveElement != null) {
if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset) && context.Description != XamlContextDescription.InAttributeValue) {
XamlCompletionItemList list = generator.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;
}
if (context.Description != XamlContextDescription.InAttributeValue) {
XamlCompletionItemList list = generator.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", StringComparison.Ordinal) || context.ActiveElement.Name == "Condition") && context.Attribute.Name == "Value")
DoTriggerCompletion(context, completionList);
else {
if (context.Attribute.Name == "xml:space") {
completionList.Items.AddRange(new[] {
new XamlCompletionItem("preserve"),
new XamlCompletionItem("default")
});
}
XamlAstResolver resolver = new XamlAstResolver(compilation, context.ParseInformation);
var mrr = resolver.ResolveAttribute(context.Attribute, editor.Document.GetOffset(editor.Caret.Location)) as MemberResolveResult;
if (mrr != null && mrr.Type.Kind != TypeKind.Unknown) {
completionList.Items.AddRange(generator.MemberCompletion(context, mrr.Type, string.Empty));
editor.ShowInsightWindow(generator.MemberInsight(mrr));
switch (mrr.Type.FullName) {
case "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;
break;
case "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;
break;
}
}
}
completionList.SortItems();
if (context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) || context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase))
completionList.Items.AddRange(generator.CreateListForXmlnsCompletion(compilation));
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;
}
editor.ShowCompletionWindow(list);
return true;
}
// DO NOT USE generator.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", StringComparison.Ordinal) || context.ActiveElement.Name == "Condition") && context.Attribute.Name == "Value") {
DoTriggerCompletion(context, completionList);
} else if (!DoAttributeCompletion(context, completionList)) {
DoXmlAttributeCompletion(context, completionList);
}
return completionList.Items.Any();
}
return true;
}
return false;
}
@ -357,6 +323,58 @@ namespace ICSharpCode.XamlBinding @@ -357,6 +323,58 @@ namespace ICSharpCode.XamlBinding
}
}
bool DoAttributeCompletion(XamlCompletionContext context, XamlCompletionItemList completionList)
{
XamlAstResolver resolver = new XamlAstResolver(compilation, context.ParseInformation);
ITextEditor editor = context.Editor;
var mrr = resolver.ResolveAttribute(context.Attribute) as MemberResolveResult;
if (mrr != null && mrr.Type.Kind != TypeKind.Unknown) {
completionList.Items.AddRange(generator.MemberCompletion(context, mrr.Type, string.Empty));
editor.ShowInsightWindow(generator.MemberInsight(mrr));
editor.ShowCompletionWindow(completionList);
switch (mrr.Type.FullName) {
case "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;
break;
case "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;
break;
}
}
return completionList.Items.Any();
}
void DoXmlAttributeCompletion(XamlCompletionContext context, XamlCompletionItemList completionList)
{
if (context.Attribute.Name == "xml:space") {
completionList.Items.AddRange(new[] {
new XamlCompletionItem("preserve"),
new XamlCompletionItem("default")
});
}
if (context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) ||
context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase)) {
completionList.Items.AddRange(generator.CreateListForXmlnsCompletion(compilation));
ICompletionListWindow window = context.Editor.ShowCompletionWindow(completionList);
if (window != null) {
window.Width = 400;
}
}
}
bool DoMarkupExtensionCompletion(XamlCompletionContext context)
{
if (context.Description == XamlContextDescription.InMarkupExtension && context.AttributeValue != null && !context.AttributeValue.IsString) {

257
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs

@ -10,6 +10,7 @@ using ICSharpCode.NRefactory.TypeSystem; @@ -10,6 +10,7 @@ using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.XmlEditor;
namespace ICSharpCode.XamlBinding
@ -50,170 +51,96 @@ namespace ICSharpCode.XamlBinding @@ -50,170 +51,96 @@ 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.SyntaxTree;
// 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.SyntaxTree.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 = XamlContextResolver.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 XamlCompletionItem) {
XamlCompletionItem cItem = item as XamlCompletionItem;
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) {
CreateEventHandlerCode(xamlContext, item as NewEventCompletionItem);
}
if (item is XmlnsCompletionItem) {
context.Editor.Caret.Offset++;
}
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(XamlCompletionContext context, NewEventCompletionItem completionItem)
{
IProject project = SD.ProjectService.FindProjectContainingFile(context.Editor.FileName);
if (project == null) return false;
var unresolved = context.ParseInformation.UnresolvedFile.TypeDefinition;
if (unresolved == null) return false;
var compilation = SD.ParserService.GetCompilationForFile(context.Editor.FileName);
var definition = unresolved.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)).GetDefinition();
project.CodeGenerator.InsertEventHandler(definition, completionItem.HandlerName, completionItem.EventType, true);
return true;
}
}
}

12
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs

@ -80,18 +80,18 @@ namespace ICSharpCode.XamlBinding @@ -80,18 +80,18 @@ namespace ICSharpCode.XamlBinding
IDocument document = null;
foreach (var tag in TreeTraversal.PreOrder<AXmlObject>(xmlDocument, node => node.Children).OfType<AXmlTag>().Where(t => t.IsComment)) {
int matchLength;
AXmlText comment = tag.Children.OfType<AXmlText>().First();
int index = comment.Value.IndexOfAny(TaskListTokens, 0, out matchLength);
string commentText = fileContent.GetText(tag.StartOffset, tag.Length);
int index = commentText.IndexOfAny(TaskListTokens, 0, out matchLength);
if (index > -1) {
if (document == null)
document = fileContent as IDocument ?? new ReadOnlyDocument(fileContent, parseInfo.FileName);
do {
TextLocation startLocation = document.GetLocation(comment.StartOffset + index);
int startOffset = index + comment.StartOffset;
int endOffset = Math.Min(document.GetLineByOffset(startOffset).EndOffset, comment.EndOffset);
TextLocation startLocation = document.GetLocation(tag.StartOffset + index);
int startOffset = index + tag.StartOffset;
int endOffset = Math.Min(document.GetLineByOffset(startOffset).EndOffset, tag.EndOffset);
string content = document.GetText(startOffset, endOffset - startOffset);
parseInfo.TagComments.Add(new TagComment(content.Substring(0, matchLength), new DomRegion(parseInfo.FileName, startLocation.Line, startLocation.Column), content.Substring(matchLength)));
index = comment.Value.IndexOfAny(TaskListTokens, endOffset - comment.StartOffset, out matchLength);
index = commentText.IndexOfAny(TaskListTokens, endOffset - tag.StartOffset, out matchLength);
} while (index > -1);
}
}

Loading…
Cancel
Save