Permalink
Browse files

Update semantic highlighting when new parse information arrives.

  • Loading branch information...
1 parent 04d88d5 commit 269597e6192d01ba80d06a1c92cbc58fc09a7e89 @dgrunwald dgrunwald committed Sep 19, 2011
@@ -61,7 +61,6 @@
<Compile Include="Configuration\AssemblyInfo.cs" />
<EmbeddedResource Include="Resources\BuildOptions.xfrm" />
<EmbeddedResource Include="Resources\MyNamespaceSupportForCSharp.cs" />
- <Compile Include="Src\CSharpAdvancedHighlighter.cs" />
<Compile Include="Src\CSharpBracketSearcher.cs" />
<Compile Include="Src\CSharpLanguageBinding.cs" />
<Compile Include="Src\CSharpProjectBinding.cs" />
@@ -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(); }"/>
<!-- 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="FieldAccess" fontStyle="italic" exampleText="return this.name;"/>
@@ -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();
- }
- }
-}
-*/
@@ -34,7 +34,7 @@ public override void Attach(ITextEditor editor)
this.editor = editor;
ISyntaxHighlighter highlighter = editor.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter;
if (highlighter != null) {
- semanticHighlighter = new CSharpSemanticHighlighter(editor, highlighter.HighlightingDefinition);
+ semanticHighlighter = new CSharpSemanticHighlighter(editor, highlighter);
highlighter.AddAdditionalHighlighter(semanticHighlighter);
}
}
@@ -44,6 +44,7 @@ public override void Detach()
ISyntaxHighlighter highlighter = editor.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter;
if (highlighter != null) {
highlighter.RemoveAdditionalHighlighter(semanticHighlighter);
+ semanticHighlighter.Dispose();
semanticHighlighter = null;
}
this.editor = null;
@@ -4,8 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Linq;
-using System.Threading.Tasks;
+
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
@@ -21,34 +20,66 @@ namespace CSharpBinding
/// <summary>
/// Semantic highlighting for C#.
/// </summary>
- public class CSharpSemanticHighlighter : DepthFirstAstVisitor<object, object>, IHighlighter, IResolveVisitorNavigator
+ public class CSharpSemanticHighlighter : DepthFirstAstVisitor<object, object>, IHighlighter, IResolveVisitorNavigator, IDisposable
{
readonly ITextEditor textEditor;
+ readonly ISyntaxHighlighter syntaxHighlighter;
readonly HighlightingColor typeReferenceColor;
readonly HighlightingColor methodCallColor;
readonly HighlightingColor fieldAccessColor;
readonly HighlightingColor valueKeywordColor;
+ HashSet<IDocumentLine> invalidLines = new HashSet<IDocumentLine>();
+
int lineNumber;
HighlightedLine line;
ResolveVisitor resolveVisitor;
bool isInAccessor;
- public CSharpSemanticHighlighter(ITextEditor textEditor, IHighlightingDefinition highlightingDefinition)
+ public CSharpSemanticHighlighter(ITextEditor textEditor, ISyntaxHighlighter syntaxHighlighter)
{
if (textEditor == null)
throw new ArgumentNullException("textEditor");
- if (highlightingDefinition == null)
- throw new ArgumentNullException("highlightingDefinition");
+ if (syntaxHighlighter == null)
+ throw new ArgumentNullException("syntaxHighlighter");
this.textEditor = textEditor;
+ this.syntaxHighlighter = syntaxHighlighter;
+
+ IHighlightingDefinition highlightingDefinition = syntaxHighlighter.HighlightingDefinition;
this.typeReferenceColor = highlightingDefinition.GetNamedColor("TypeReferences");
this.methodCallColor = highlightingDefinition.GetNamedColor("MethodCall");
this.fieldAccessColor = highlightingDefinition.GetNamedColor("FieldAccess");
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; }
}
@@ -59,16 +90,18 @@ IEnumerable<HighlightingColor> IHighlighter.GetColorStack(int lineNumber)
public HighlightedLine HighlightLine(int lineNumber)
{
- Task<ParseInformation> parseInfoTask = ParserService.ParseAsync(textEditor.FileName, textEditor.Document);
- if (!parseInfoTask.IsCompleted) {
- Debug.WriteLine("Semantic highlighting for line {0} - parser not completed", lineNumber);
+ ParseInformation parseInfo = ParserService.GetCachedParseInformation(textEditor.FileName, textEditor.Document.Version);
+ if (parseInfo == null) {
+ invalidLines.Add(textEditor.Document.GetLineByNumber(lineNumber));
+ Debug.WriteLine("Semantic highlighting for line {0} - marking as invalid", lineNumber);
return null;
}
- ParseInformation parseInfo = parseInfoTask.Result;
CSharpParsedFile parsedFile = parseInfo.ParsedFile as CSharpParsedFile;
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;
+ }
using (var ctx = ParserService.GetTypeResolveContext(parseInfo.ProjectContent).Synchronize()) {
CSharpResolver resolver = new CSharpResolver(ctx);
@@ -246,7 +279,7 @@ public override object VisitMethodDeclaration(MethodDeclaration methodDeclaratio
public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
{
- Colorize(typeDeclaration, typeReferenceColor);
+ Colorize(typeDeclaration.NameToken, typeReferenceColor);
foreach (var node in typeDeclaration.TypeParameters)
node.AcceptVisitor(this);
foreach (var node in typeDeclaration.BaseTypes)
@@ -257,5 +290,14 @@ public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, obj
node.AcceptVisitor(this);
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;
+ }
}
}
Oops, something went wrong.

0 comments on commit 269597e

Please sign in to comment.