Browse Source

Update semantic highlighting when new parse information arrives.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
269597e619
  1. 1
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
  2. 2
      src/AddIns/BackendBindings/CSharpBinding/Project/Resources/CSharp-Semantic.xshd
  3. 145
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpAdvancedHighlighter.cs
  4. 3
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs
  5. 68
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpSemanticHighlighter.cs
  6. 32
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizableHighlightingColorizer.cs
  7. 26
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs
  8. 19
      src/Main/Base/Project/Src/Editor/ISyntaxHighlighter.cs
  9. 4
      src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
  10. 34
      src/Main/Base/Project/Src/Services/ParserService/ParserService.cs

1
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj

@ -61,7 +61,6 @@
<Compile Include="Configuration\AssemblyInfo.cs" /> <Compile Include="Configuration\AssemblyInfo.cs" />
<EmbeddedResource Include="Resources\BuildOptions.xfrm" /> <EmbeddedResource Include="Resources\BuildOptions.xfrm" />
<EmbeddedResource Include="Resources\MyNamespaceSupportForCSharp.cs" /> <EmbeddedResource Include="Resources\MyNamespaceSupportForCSharp.cs" />
<Compile Include="Src\CSharpAdvancedHighlighter.cs" />
<Compile Include="Src\CSharpBracketSearcher.cs" /> <Compile Include="Src\CSharpBracketSearcher.cs" />
<Compile Include="Src\CSharpLanguageBinding.cs" /> <Compile Include="Src\CSharpLanguageBinding.cs" />
<Compile Include="Src\CSharpProjectBinding.cs" /> <Compile Include="Src\CSharpProjectBinding.cs" />

2
src/AddIns/BackendBindings/CSharpBinding/Project/Resources/CSharp-Semantic.xshd

@ -31,7 +31,7 @@
<Color name="TypeKeywords" fontWeight="bold" foreground="DarkCyan" exampleText="if (x is int) { a = x as int; type = typeof(int); size = sizeof(int); c = new object(); }"/> <Color name="TypeKeywords" fontWeight="bold" foreground="DarkCyan" exampleText="if (x is int) { a = x as int; type = typeof(int); size = sizeof(int); c = new object(); }"/>
<!-- Colors used for semantic highlighting --> <!-- Colors used for semantic highlighting -->
<Color name="TypeReferences" foreground="DarkCyan" exampleText="System.Uri uri;"/> <Color name="TypeReferences" foreground="#004085" exampleText="System.Uri uri;"/>
<Color name="MethodCall" foreground="MidnightBlue" fontWeight="bold" exampleText="o.ToString();"/> <Color name="MethodCall" foreground="MidnightBlue" fontWeight="bold" exampleText="o.ToString();"/>
<Color name="FieldAccess" fontStyle="italic" exampleText="return this.name;"/> <Color name="FieldAccess" fontStyle="italic" exampleText="return this.name;"/>

145
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpAdvancedHighlighter.cs

@ -1,145 +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.Drawing;
using System.Diagnostics;
using ICSharpCode.SharpDevelop.Dom.CSharp;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
namespace CSharpBinding
{
public class CSharpAdvancedHighlighter : AsynchronousAdvancedHighlighter
{
public override void Initialize(TextEditorControl textEditor)
{
base.Initialize(textEditor);
ParserService.ParserUpdateStepFinished += OnUpdateStep;
}
public override void Dispose()
{
ParserService.ParserUpdateStepFinished -= OnUpdateStep;
base.Dispose();
}
void OnUpdateStep(object sender, ParserUpdateStepEventArgs e)
{
if (FileUtility.IsEqualFileName(e.FileName, this.TextEditor.FileName)) {
ParseInformation parseInfo = e.ParseInformation;
// if (parseInfo == null && this.storedParseInformation)
// parseInfo = ParserService.GetParseInformation(this.TextEditor.FileName);
// if (parseInfo != null) {
// ICompilationUnit cu = parseInfo.MostRecentCompilationUnit;
// }
WorkbenchSingleton.SafeThreadAsyncCall(MarkOutstanding);
}
}
static bool IsInMultilineCommentOrStringLiteral(LineSegment line)
{
if (line.HighlightSpanStack == null || line.HighlightSpanStack.IsEmpty) {
return false;
}
return !line.HighlightSpanStack.Peek().StopEOL;
}
protected override void MarkWords(int lineNumber, LineSegment currentLine, List<TextWord> words)
{
if (IsInMultilineCommentOrStringLiteral(currentLine)) {
return;
}
ParseInformation parseInfo = ParserService.GetParseInformation(this.TextEditor.FileName);
if (parseInfo == null) return;
CSharpExpressionFinder finder = new CSharpExpressionFinder(parseInfo);
Func<string, int, ExpressionResult> findExpressionMethod;
IClass callingClass = parseInfo.MostRecentCompilationUnit.GetInnermostClass(lineNumber, 0);
if (callingClass != null) {
if (GetCurrentMember(callingClass, lineNumber, 0) != null) {
findExpressionMethod = finder.FindFullExpressionInMethod;
} else {
findExpressionMethod = finder.FindFullExpressionInTypeDeclaration;
}
} else {
findExpressionMethod = finder.FindFullExpression;
}
string lineText = this.Document.GetText(currentLine.Offset, currentLine.Length);
bool changedLine = false;
// now go through the word list:
foreach (TextWord word in words) {
if (word.IsWhiteSpace) continue;
if (char.IsLetter(lineText[word.Offset]) || lineText[word.Offset] == '_') {
ExpressionResult result = findExpressionMethod(lineText, word.Offset);
if (result.Expression != null) {
// result.Expression
if (ICSharpCode.NRefactory.Parser.CSharp.Keywords.IsNonIdentifierKeyword(result.Expression))
continue;
// convert text editor to DOM coordinates:
resolveCount++;
ResolveResult rr = ParserService.Resolve(result, lineNumber + 1, word.Offset + 1, this.TextEditor.FileName, this.TextEditor.Text);
if (rr is MixedResolveResult || rr is TypeResolveResult) {
changedLine = true;
word.SyntaxColor = this.Document.HighlightingStrategy.GetColorFor("TypeReference");
} else if (rr == null) {
changedLine = true;
word.SyntaxColor = this.Document.HighlightingStrategy.GetColorFor("UnknownEntity");
}
}
}
}
if (markingOutstanding && changedLine) {
this.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, lineNumber));
}
}
static IMember GetCurrentMember(IClass callingClass, int caretLine, int caretColumn)
{
if (callingClass == null)
return null;
foreach (IMethod method in callingClass.Methods) {
if (method.Region.IsInside(caretLine, caretColumn) || method.BodyRegion.IsInside(caretLine, caretColumn)) {
return method;
}
}
foreach (IProperty property in callingClass.Properties) {
if (property.Region.IsInside(caretLine, caretColumn) || property.BodyRegion.IsInside(caretLine, caretColumn)) {
return property;
}
}
return null;
}
bool markingOutstanding;
int resolveCount;
protected override void MarkOutstanding()
{
#if DEBUG
int time = Environment.TickCount;
#endif
markingOutstanding = true;
resolveCount = 0;
base.MarkOutstanding();
markingOutstanding = false;
#if DEBUG
time = Environment.TickCount - time;
if (time > 0) {
LoggingService.Info("CSharpHighlighter took " + time + "ms for " + resolveCount + " resolves");
}
#endif
this.Document.CommitUpdate();
}
}
}
*/

3
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs

@ -34,7 +34,7 @@ namespace CSharpBinding
this.editor = editor; this.editor = editor;
ISyntaxHighlighter highlighter = editor.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter; ISyntaxHighlighter highlighter = editor.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter;
if (highlighter != null) { if (highlighter != null) {
semanticHighlighter = new CSharpSemanticHighlighter(editor, highlighter.HighlightingDefinition); semanticHighlighter = new CSharpSemanticHighlighter(editor, highlighter);
highlighter.AddAdditionalHighlighter(semanticHighlighter); highlighter.AddAdditionalHighlighter(semanticHighlighter);
} }
} }
@ -44,6 +44,7 @@ namespace CSharpBinding
ISyntaxHighlighter highlighter = editor.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter; ISyntaxHighlighter highlighter = editor.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter;
if (highlighter != null) { if (highlighter != null) {
highlighter.RemoveAdditionalHighlighter(semanticHighlighter); highlighter.RemoveAdditionalHighlighter(semanticHighlighter);
semanticHighlighter.Dispose();
semanticHighlighter = null; semanticHighlighter = null;
} }
this.editor = null; this.editor = null;

68
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpSemanticHighlighter.cs

@ -4,8 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
@ -21,34 +20,66 @@ namespace CSharpBinding
/// <summary> /// <summary>
/// Semantic highlighting for C#. /// Semantic highlighting for C#.
/// </summary> /// </summary>
public class CSharpSemanticHighlighter : DepthFirstAstVisitor<object, object>, IHighlighter, IResolveVisitorNavigator public class CSharpSemanticHighlighter : DepthFirstAstVisitor<object, object>, IHighlighter, IResolveVisitorNavigator, IDisposable
{ {
readonly ITextEditor textEditor; readonly ITextEditor textEditor;
readonly ISyntaxHighlighter syntaxHighlighter;
readonly HighlightingColor typeReferenceColor; readonly HighlightingColor typeReferenceColor;
readonly HighlightingColor methodCallColor; readonly HighlightingColor methodCallColor;
readonly HighlightingColor fieldAccessColor; readonly HighlightingColor fieldAccessColor;
readonly HighlightingColor valueKeywordColor; readonly HighlightingColor valueKeywordColor;
HashSet<IDocumentLine> invalidLines = new HashSet<IDocumentLine>();
int lineNumber; int lineNumber;
HighlightedLine line; HighlightedLine line;
ResolveVisitor resolveVisitor; ResolveVisitor resolveVisitor;
bool isInAccessor; bool isInAccessor;
public CSharpSemanticHighlighter(ITextEditor textEditor, IHighlightingDefinition highlightingDefinition) public CSharpSemanticHighlighter(ITextEditor textEditor, ISyntaxHighlighter syntaxHighlighter)
{ {
if (textEditor == null) if (textEditor == null)
throw new ArgumentNullException("textEditor"); throw new ArgumentNullException("textEditor");
if (highlightingDefinition == null) if (syntaxHighlighter == null)
throw new ArgumentNullException("highlightingDefinition"); throw new ArgumentNullException("syntaxHighlighter");
this.textEditor = textEditor; this.textEditor = textEditor;
this.syntaxHighlighter = syntaxHighlighter;
IHighlightingDefinition highlightingDefinition = syntaxHighlighter.HighlightingDefinition;
this.typeReferenceColor = highlightingDefinition.GetNamedColor("TypeReferences"); this.typeReferenceColor = highlightingDefinition.GetNamedColor("TypeReferences");
this.methodCallColor = highlightingDefinition.GetNamedColor("MethodCall"); this.methodCallColor = highlightingDefinition.GetNamedColor("MethodCall");
this.fieldAccessColor = highlightingDefinition.GetNamedColor("FieldAccess"); this.fieldAccessColor = highlightingDefinition.GetNamedColor("FieldAccess");
this.valueKeywordColor = highlightingDefinition.GetNamedColor("NullOrValueKeywords"); this.valueKeywordColor = highlightingDefinition.GetNamedColor("NullOrValueKeywords");
ParserService.ParserUpdateStepFinished += ParserService_ParserUpdateStepFinished;
ParserService.LoadSolutionProjectsThreadEnded += ParserService_LoadSolutionProjectsThreadEnded;
} }
public IDocument Document { public void Dispose()
{
ParserService.ParserUpdateStepFinished -= ParserService_ParserUpdateStepFinished;
ParserService.LoadSolutionProjectsThreadEnded -= ParserService_LoadSolutionProjectsThreadEnded;
}
void ParserService_LoadSolutionProjectsThreadEnded(object sender, EventArgs e)
{
syntaxHighlighter.InvalidateAll();
}
void ParserService_ParserUpdateStepFinished(object sender, ParserUpdateStepEventArgs e)
{
if (e.FileName == textEditor.FileName && invalidLines.Count > 0) {
foreach (IDocumentLine line in invalidLines) {
if (!line.IsDeleted) {
syntaxHighlighter.InvalidateLine(line);
}
}
invalidLines.Clear();
}
}
IDocument IHighlighter.Document {
get { return textEditor.Document; } get { return textEditor.Document; }
} }
@ -59,16 +90,18 @@ namespace CSharpBinding
public HighlightedLine HighlightLine(int lineNumber) public HighlightedLine HighlightLine(int lineNumber)
{ {
Task<ParseInformation> parseInfoTask = ParserService.ParseAsync(textEditor.FileName, textEditor.Document); ParseInformation parseInfo = ParserService.GetCachedParseInformation(textEditor.FileName, textEditor.Document.Version);
if (!parseInfoTask.IsCompleted) { if (parseInfo == null) {
Debug.WriteLine("Semantic highlighting for line {0} - parser not completed", lineNumber); invalidLines.Add(textEditor.Document.GetLineByNumber(lineNumber));
Debug.WriteLine("Semantic highlighting for line {0} - marking as invalid", lineNumber);
return null; return null;
} }
ParseInformation parseInfo = parseInfoTask.Result;
CSharpParsedFile parsedFile = parseInfo.ParsedFile as CSharpParsedFile; CSharpParsedFile parsedFile = parseInfo.ParsedFile as CSharpParsedFile;
CompilationUnit cu = parseInfo.Annotation<CompilationUnit>(); CompilationUnit cu = parseInfo.Annotation<CompilationUnit>();
if (cu == null || parsedFile == null) if (cu == null || parsedFile == null) {
Debug.WriteLine("Semantic highlighting for line {0} - not a C# file?", lineNumber);
return null; return null;
}
using (var ctx = ParserService.GetTypeResolveContext(parseInfo.ProjectContent).Synchronize()) { using (var ctx = ParserService.GetTypeResolveContext(parseInfo.ProjectContent).Synchronize()) {
CSharpResolver resolver = new CSharpResolver(ctx); CSharpResolver resolver = new CSharpResolver(ctx);
@ -246,7 +279,7 @@ namespace CSharpBinding
public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data) public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
{ {
Colorize(typeDeclaration, typeReferenceColor); Colorize(typeDeclaration.NameToken, typeReferenceColor);
foreach (var node in typeDeclaration.TypeParameters) foreach (var node in typeDeclaration.TypeParameters)
node.AcceptVisitor(this); node.AcceptVisitor(this);
foreach (var node in typeDeclaration.BaseTypes) foreach (var node in typeDeclaration.BaseTypes)
@ -257,5 +290,14 @@ namespace CSharpBinding
node.AcceptVisitor(this); node.AcceptVisitor(this);
return null; return null;
} }
public override object VisitVariableInitializer(VariableInitializer variableInitializer, object data)
{
if (variableInitializer.Parent is FieldDeclaration) {
Colorize(variableInitializer.NameToken, fieldAccessColor);
}
variableInitializer.Initializer.AcceptVisitor(this);
return null;
}
} }
} }

32
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizableHighlightingColorizer.cs

@ -6,13 +6,13 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Rendering; using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor;
@ -109,31 +109,39 @@ namespace ICSharpCode.AvalonEdit.AddIn
this.customizations = customizations; this.customizations = customizations;
} }
protected override void OnDocumentChanged(TextView textView) protected override void DeregisterServices(TextView textView)
{ {
textView.Services.RemoveService(typeof(ISyntaxHighlighter)); textView.Services.RemoveService(typeof(ISyntaxHighlighter));
base.OnDocumentChanged(textView); base.DeregisterServices(textView);
}
protected override void RegisterServices(TextView textView)
{
base.RegisterServices(textView);
textView.Services.AddService(typeof(ISyntaxHighlighter), (CustomizingHighlighter)textView.GetService(typeof(IHighlighter))); textView.Services.AddService(typeof(ISyntaxHighlighter), (CustomizingHighlighter)textView.GetService(typeof(IHighlighter)));
} }
protected override IHighlighter CreateHighlighter(TextView textView, TextDocument document) protected override IHighlighter CreateHighlighter(TextView textView, TextDocument document)
{ {
return new CustomizingHighlighter(customizations, highlightingDefinition, base.CreateHighlighter(textView, document)); return new CustomizingHighlighter(textView, customizations, highlightingDefinition, base.CreateHighlighter(textView, document));
} }
sealed class CustomizingHighlighter : IHighlighter, ISyntaxHighlighter sealed class CustomizingHighlighter : IHighlighter, ISyntaxHighlighter
{ {
readonly TextView textView;
readonly IEnumerable<CustomizedHighlightingColor> customizations; readonly IEnumerable<CustomizedHighlightingColor> customizations;
readonly IHighlightingDefinition highlightingDefinition; readonly IHighlightingDefinition highlightingDefinition;
readonly IHighlighter baseHighlighter; readonly IHighlighter baseHighlighter;
List<IHighlighter> additionalHighlighters = new List<IHighlighter>(); List<IHighlighter> additionalHighlighters = new List<IHighlighter>();
public CustomizingHighlighter(IEnumerable<CustomizedHighlightingColor> customizations, IHighlightingDefinition highlightingDefinition, IHighlighter baseHighlighter) public CustomizingHighlighter(TextView textView, IEnumerable<CustomizedHighlightingColor> customizations, IHighlightingDefinition highlightingDefinition, IHighlighter baseHighlighter)
{ {
Debug.Assert(textView != null);
Debug.Assert(customizations != null); Debug.Assert(customizations != null);
Debug.Assert(highlightingDefinition != null); Debug.Assert(highlightingDefinition != null);
Debug.Assert(baseHighlighter != null); Debug.Assert(baseHighlighter != null);
this.textView = textView;
this.customizations = customizations; this.customizations = customizations;
this.highlightingDefinition = highlightingDefinition; this.highlightingDefinition = highlightingDefinition;
this.baseHighlighter = baseHighlighter; this.baseHighlighter = baseHighlighter;
@ -195,6 +203,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
return line; return line;
} }
#region MergeHighlighting
/// <summary> /// <summary>
/// Merges the highlighting sections from additionalLine into line. /// Merges the highlighting sections from additionalLine into line.
/// </summary> /// </summary>
@ -297,6 +306,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
} }
} }
} }
#endregion
HighlightingColor CustomizeColor(HighlightingColor color) HighlightingColor CustomizeColor(HighlightingColor color)
{ {
@ -323,6 +333,16 @@ namespace ICSharpCode.AvalonEdit.AddIn
else else
return new CustomizedBrush(color.Value); return new CustomizedBrush(color.Value);
} }
public void InvalidateLine(IDocumentLine line)
{
textView.Redraw(line, DispatcherPriority.Background);
}
public void InvalidateAll()
{
textView.Redraw(DispatcherPriority.Background);
}
} }
sealed class CustomizedBrush : HighlightingBrush sealed class CustomizedBrush : HighlightingBrush

26
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs

@ -32,14 +32,27 @@ namespace ICSharpCode.AvalonEdit.Highlighting
void textView_DocumentChanged(object sender, EventArgs e) void textView_DocumentChanged(object sender, EventArgs e)
{ {
OnDocumentChanged((TextView)sender); TextView textView = (TextView)sender;
DeregisterServices(textView);
RegisterServices(textView);
} }
protected virtual void OnDocumentChanged(TextView textView) /// <summary>
/// This method is called when a text view is removed from this HighlightingColorizer,
/// and also when the TextDocument on any associated text view changes.
/// </summary>
protected virtual void DeregisterServices(TextView textView)
{ {
// remove existing highlighter, if any exists // remove existing highlighter, if any exists
textView.Services.RemoveService(typeof(IHighlighter)); textView.Services.RemoveService(typeof(IHighlighter));
}
/// <summary>
/// This method is called when a new text view is added to this HighlightingColorizer,
/// and also when the TextDocument on any associated text view changes.
/// </summary>
protected virtual void RegisterServices(TextView textView)
{
TextDocument document = textView.Document; TextDocument document = textView.Document;
if (document != null) { if (document != null) {
IHighlighter highlighter = CreateHighlighter(textView, document); IHighlighter highlighter = CreateHighlighter(textView, document);
@ -61,17 +74,16 @@ namespace ICSharpCode.AvalonEdit.Highlighting
base.OnAddToTextView(textView); base.OnAddToTextView(textView);
textView.DocumentChanged += textView_DocumentChanged; textView.DocumentChanged += textView_DocumentChanged;
textView.VisualLineConstructionStarting += textView_VisualLineConstructionStarting; textView.VisualLineConstructionStarting += textView_VisualLineConstructionStarting;
OnDocumentChanged(textView); RegisterServices(textView);
} }
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnRemoveFromTextView(TextView textView) protected override void OnRemoveFromTextView(TextView textView)
{ {
base.OnRemoveFromTextView(textView); DeregisterServices(textView);
textView.Services.RemoveService(typeof(IHighlighter));
textView.Services.RemoveService(typeof(DocumentHighlighter));
textView.DocumentChanged -= textView_DocumentChanged; textView.DocumentChanged -= textView_DocumentChanged;
textView.VisualLineConstructionStarting -= textView_VisualLineConstructionStarting; textView.VisualLineConstructionStarting -= textView_VisualLineConstructionStarting;
base.OnRemoveFromTextView(textView);
} }
void textView_VisualLineConstructionStarting(object sender, VisualLineConstructionStartEventArgs e) void textView_VisualLineConstructionStarting(object sender, VisualLineConstructionStartEventArgs e)

19
src/Main/Base/Project/Src/Editor/ISyntaxHighlighter.cs

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.NRefactory.Editor;
namespace ICSharpCode.SharpDevelop.Editor namespace ICSharpCode.SharpDevelop.Editor
{ {
@ -33,6 +34,24 @@ namespace ICSharpCode.SharpDevelop.Editor
/// Removes an additional highlighting engine. /// Removes an additional highlighting engine.
/// </summary> /// </summary>
void RemoveAdditionalHighlighter(IHighlighter highlighter); void RemoveAdditionalHighlighter(IHighlighter highlighter);
/// <summary>
/// Invalidates a line, causing it to be re-highlighted.
/// </summary>
/// <remarks>
/// This method is intended to be called by additional highlighters that process external information
/// (e.g. semantic highlighting).
/// </remarks>
void InvalidateLine(IDocumentLine line);
/// <summary>
/// Invalidates all lines, causing-them to be re-highlighted.
/// </summary>
/// <remarks>
/// This method is intended to be called by additional highlighters that process external information
/// (e.g. semantic highlighting).
/// </remarks>
void InvalidateAll();
} }
public static class SyntaxHighligherKnownSpanNames public static class SyntaxHighligherKnownSpanNames

4
src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs

@ -5,8 +5,8 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
@ -29,7 +29,7 @@ namespace ICSharpCode.SharpDevelop.Parser
if (project == null) if (project == null)
throw new ArgumentNullException("project"); throw new ArgumentNullException("project");
this.project = project; this.project = project;
this.typeResolveContext = MinimalResolveContext.Instance; this.typeResolveContext = new CompositeTypeResolveContext(new ITypeResolveContext[] { this, MinimalResolveContext.Instance });
this.initializing = true; this.initializing = true;
LoadSolutionProjects.AddJob(Initialize, "Loading " + project.Name + "...", GetInitializationWorkAmount()); LoadSolutionProjects.AddJob(Initialize, "Loading " + project.Name + "...", GetInitializationWorkAmount());

34
src/Main/Base/Project/Src/Services/ParserService/ParserService.cs

@ -10,6 +10,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Threading; using System.Windows.Threading;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Editor;
@ -412,6 +413,19 @@ namespace ICSharpCode.SharpDevelop.Parser
return cachedParseInformation; // read volatile return cachedParseInformation; // read volatile
} }
public ParseInformation GetCachedParseInformation(ITextSourceVersion version)
{
if (version == null)
return GetCachedParseInformation();
lock (this) {
if (bufferVersion != null && bufferVersion.BelongsToSameDocumentAs(version)) {
if (bufferVersion.CompareAge(version) >= 0)
return cachedParseInformation;
}
}
return null;
}
public IParsedFile GetExistingParsedFile(IProjectContent content) public IParsedFile GetExistingParsedFile(IProjectContent content)
{ {
if (content == null) { if (content == null) {
@ -821,6 +835,26 @@ namespace ICSharpCode.SharpDevelop.Parser
return null; return null;
} }
/// <summary>
/// Gets full parse information for the specified file, if it is available and at least as recent as the specified version.
/// </summary>
/// <returns>
/// If only the IParsedFile is available (non-full parse information), this method
/// returns null.
/// If parse information is avaiable but potentially outdated (older than <paramref name="version"/>,
/// or belonging to a different document), this method returns null.
/// </returns>
public static ParseInformation GetCachedParseInformation(FileName fileName, ITextSourceVersion version)
{
if (string.IsNullOrEmpty(fileName))
return null;
FileEntry entry = GetFileEntry(fileName, false);
if (entry != null)
return entry.GetCachedParseInformation(version);
else
return null;
}
/// <summary> /// <summary>
/// Gets parse information for the specified file. /// Gets parse information for the specified file.
/// </summary> /// </summary>

Loading…
Cancel
Save