25 changed files with 853 additions and 3577 deletions
@ -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<NodeWrapper> nodeStack; |
|
||||||
IAmbience currentAmbience; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// string representation of the document, used to create DOM regions.
|
|
||||||
/// </summary>
|
|
||||||
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<NodeWrapper>(); |
|
||||||
} |
|
||||||
|
|
||||||
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<AXmlText>()) { |
|
||||||
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<NodeWrapper>() |
|
||||||
}; |
|
||||||
|
|
||||||
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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
@ -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 |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// IReturnType that gets created by XamlCompilationUnit.CreateType and will
|
|
||||||
/// run XamlCompilationUnit.FindType on demand.
|
|
||||||
/// </summary>
|
|
||||||
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; } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -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<Highlight> oldHighlightData) |
|
||||||
: this(editor, currentLine, textView) |
|
||||||
{ |
|
||||||
this.results = oldHighlightData; |
|
||||||
} |
|
||||||
|
|
||||||
IList<Highlight> 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<Highlight> results = new List<Highlight>(); |
|
||||||
|
|
||||||
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<HighlightingInfo> 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<DocumentLine, HighlightTask> highlightCache = new Dictionary<DocumentLine, HighlightTask>(); |
|
||||||
|
|
||||||
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<XamlColorizer> colorizers = new List<XamlColorizer>(); |
|
||||||
|
|
||||||
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<VisualLineElement> 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; } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -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 |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Description of XamlCompilationUnit.
|
|
||||||
/// </summary>
|
|
||||||
public class XamlCompilationUnit : DefaultCompilationUnit |
|
||||||
{ |
|
||||||
public XamlCompilationUnit(IProjectContent projectContent) |
|
||||||
: base(projectContent) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public NodeWrapper TreeRootNode { get; set; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a IReturnType looking for a class referenced in XAML.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="xmlNamespace">The XML namespace</param>
|
|
||||||
/// <param name="className">The class name</param>
|
|
||||||
/// <returns>A new IReturnType that will search the referenced type on demand.</returns>
|
|
||||||
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; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds a type referenced in XAML.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="xmlNamespace">The XML namespace</param>
|
|
||||||
/// <param name="className">The class name</param>
|
|
||||||
/// <returns>Returns the referenced type, or null if it cannot be found.</returns>
|
|
||||||
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<IClass> 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<IClass>(); |
|
||||||
else { |
|
||||||
var list = new List<ICompletionEntry>(); |
|
||||||
AddNamespaceMembersInAssembly(pc, xmlNamespace, list); |
|
||||||
foreach (IProjectContent p in pc.ReferencedContents) { |
|
||||||
AddNamespaceMembersInAssembly(p, xmlNamespace, list); |
|
||||||
} |
|
||||||
return list.OfType<IClass>(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return Enumerable.Empty<IClass>(); |
|
||||||
} |
|
||||||
|
|
||||||
static void AddNamespaceMembersInAssembly(IProjectContent projectContent, string xmlNamespace, List<ICompletionEntry> 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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -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 |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Description of XamlExpressionFinder.
|
|
||||||
/// </summary>
|
|
||||||
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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -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<Error> errors; |
||||||
|
ITypeDefinition xamlTypeDefinition; |
||||||
|
|
||||||
|
XamlParsedFile(FileName fileName, AXmlDocument document) |
||||||
|
{ |
||||||
|
this.fileName = fileName; |
||||||
|
this.document = document; |
||||||
|
this.errors = new List<Error>(); |
||||||
|
} |
||||||
|
|
||||||
|
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<IUnresolvedTypeDefinition> TopLevelTypeDefinitions { |
||||||
|
get { |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public IList<IUnresolvedAttribute> AssemblyAttributes { |
||||||
|
get { return EmptyList<IUnresolvedAttribute>.Instance; } |
||||||
|
} |
||||||
|
|
||||||
|
public IList<IUnresolvedAttribute> ModuleAttributes { |
||||||
|
get { return EmptyList<IUnresolvedAttribute>.Instance; } |
||||||
|
} |
||||||
|
|
||||||
|
public IList<Error> 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(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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 |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Description of XamlResolver.
|
|
||||||
/// </summary>
|
|
||||||
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<string, AttributeValue>) { |
|
||||||
var pair = (KeyValuePair<string, AttributeValue>)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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -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 |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of XamlSymbolSearch.
|
||||||
|
/// </summary>
|
||||||
|
public class XamlSymbolSearch : ISymbolSearch |
||||||
|
{ |
||||||
|
public XamlSymbolSearch(IEntity entity) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public double WorkAmount { |
||||||
|
get { |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public Task FindReferencesAsync(SymbolSearchArgs searchArguments, Action<SearchedFile> callback) |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue