Browse Source

Add semantic highlighting for C#.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
b7b259896d
  1. 6
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
  2. 5
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
  3. 291
      src/AddIns/BackendBindings/CSharpBinding/Project/Resources/CSharp-Semantic.xshd
  4. 24
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs
  5. 261
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpSemanticHighlighter.cs
  6. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  7. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
  8. 173
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizableHighlightingColorizer.cs
  9. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs
  10. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/FoldingManager.cs
  11. 15
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/DocumentHighlighter.cs
  12. 22
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs
  13. 12
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingManager.cs
  14. 18
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/IHighlighter.cs
  15. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  16. 39
      src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditSyntaxHighlighterAdapter.cs
  17. 16
      src/Main/Base/Project/Src/Editor/ISyntaxHighlighter.cs
  18. 47
      src/Main/Base/Project/Src/Services/ParserService/ParserService.cs

6
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin

@ -65,11 +65,9 @@ @@ -65,11 +65,9 @@
extensions=".cs" />
</Path>
<!--
<Path name = "/AddIns/DefaultTextEditor/AdvancedHighlighter/C#">
<Class id = "CSharpHighlighter" class = "CSharpBinding.CSharpAdvancedHighlighter"/>
<Path name = "/SharpDevelop/ViewContent/AvalonEdit/SyntaxModes">
<SyntaxMode id="C#" name="C#" extensions=".cs" resource="Resources.CSharp-Semantic.xshd" />
</Path>
-->
<Path path = "/SharpDevelop/BackendBindings/ProjectOptions/C#">
<OptionPanel id = "Application"

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

@ -39,6 +39,9 @@ @@ -39,6 +39,9 @@
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<OutputPath>..\..\..\..\..\AddIns\BackendBindings\CSharpBinding\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>DEBUG</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Build.Utilities.v4.0" />
<Reference Include="PresentationCore">
@ -62,6 +65,7 @@ @@ -62,6 +65,7 @@
<Compile Include="Src\CSharpBracketSearcher.cs" />
<Compile Include="Src\CSharpLanguageBinding.cs" />
<Compile Include="Src\CSharpProjectBinding.cs" />
<Compile Include="Src\CSharpSemanticHighlighter.cs" />
<Compile Include="Src\FormattingStrategy\CSharpFormattingStrategy.cs" />
<Compile Include="Src\FormattingStrategy\DocumentAccessor.cs" />
<Compile Include="Src\OptionPanels\BuildOptions.cs">
@ -80,6 +84,7 @@ @@ -80,6 +84,7 @@
<Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>Configuration\GlobalAssemblyInfo.cs</Link>
</Compile>
<EmbeddedResource Include="Resources\CSharp-Semantic.xshd" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj">

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

@ -0,0 +1,291 @@ @@ -0,0 +1,291 @@
<?xml version="1.0"?>
<SyntaxDefinition name="C#" extensions=".cs" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<!-- This is a variant of the AvalonEdit C# highlighting that has several constructs disabled.
The disabled constructs (e.g. contextual keywords) are highlighted using the CSharpSemanticHighlighter instead.
-->
<!-- The named colors 'Comment' and 'String' are used in SharpDevelop to detect if a line is inside a multiline string/comment -->
<Color name="Comment" foreground="Green" exampleText="// comment" />
<Color name="String" foreground="Blue" exampleText="string text = &quot;Hello, World!&quot;"/>
<Color name="Char" foreground="Magenta" exampleText="char linefeed = '\n';"/>
<Color name="Preprocessor" foreground="Green" exampleText="#region Title" />
<Color name="Punctuation" exampleText="a(b.c);" />
<Color name="ValueTypes" fontWeight="bold" foreground="Red" exampleText="bool b = true;" />
<Color name="ReferenceTypes" foreground="Red" exampleText="object o;" />
<Color name="NumberLiteral" foreground="DarkBlue" exampleText="3.1415f"/>
<Color name="ThisOrBaseReference" fontWeight="bold" exampleText="this.Do(); base.Do();"/>
<Color name="NullOrValueKeywords" fontWeight="bold" exampleText="if (value == null)"/>
<Color name="Keywords" fontWeight="bold" foreground="Blue" exampleText="if (a) {} else {}"/>
<Color name="GotoKeywords" foreground="Navy" exampleText="continue; return null;"/>
<Color name="ContextKeywords" foreground="Navy" exampleText="var a = from x in y select z;"/>
<Color name="ExceptionKeywords" fontWeight="bold" foreground="Teal" exampleText="try {} catch {} finally {}"/>
<Color name="CheckedKeyword" fontWeight="bold" foreground="DarkGray" exampleText="checked {}"/>
<Color name="UnsafeKeywords" foreground="Olive" exampleText="unsafe { fixed (..) {} }"/>
<Color name="OperatorKeywords" fontWeight="bold" foreground="Pink" exampleText="public static implicit operator..."/>
<Color name="ParameterModifiers" fontWeight="bold" foreground="DeepPink" exampleText="(ref int a, params int[] b)"/>
<Color name="Modifiers" foreground="Brown" exampleText="static readonly int a;"/>
<Color name="Visibility" fontWeight="bold" foreground="Blue" exampleText="public override void ToString();"/>
<Color name="NamespaceKeywords" fontWeight="bold" foreground="Green" exampleText="namespace A.B { using System; }"/>
<Color name="GetSetAddRemove" foreground="SaddleBrown" exampleText="int Prop { get; set; }"/>
<Color name="TrueFalse" fontWeight="bold" foreground="DarkCyan" exampleText="b = false; a = true;" />
<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="MethodCall" foreground="MidnightBlue" fontWeight="bold" exampleText="o.ToString();"/>
<Color name="FieldAccess" fontStyle="italic" exampleText="return this.name;"/>
<RuleSet name="CommentMarkerSet">
<Keywords fontWeight="bold" foreground="Red">
<Word>TODO</Word>
<Word>FIXME</Word>
</Keywords>
<Keywords fontWeight="bold" foreground="#E0E000">
<Word>HACK</Word>
<Word>UNDONE</Word>
</Keywords>
</RuleSet>
<!-- This is the main ruleset. -->
<RuleSet>
<Span color="Preprocessor">
<Begin>\#</Begin>
<RuleSet name="PreprocessorSet">
<Span> <!-- preprocessor directives that allow comments -->
<Begin fontWeight="bold">
(define|undef|if|elif|else|endif|line)\b
</Begin>
<RuleSet>
<Span color="Comment" ruleSet="CommentMarkerSet">
<Begin>//</Begin>
</Span>
</RuleSet>
</Span>
<Span> <!-- preprocessor directives that don't allow comments -->
<Begin fontWeight="bold">
(region|endregion|error|warning|pragma)\b
</Begin>
</Span>
</RuleSet>
</Span>
<Span color="Comment">
<Begin color="XmlDoc/DocComment">///</Begin>
<RuleSet>
<Import ruleSet="XmlDoc/DocCommentSet"/>
<Import ruleSet="CommentMarkerSet"/>
</RuleSet>
</Span>
<Span color="Comment" ruleSet="CommentMarkerSet">
<Begin>//</Begin>
</Span>
<Span color="Comment" ruleSet="CommentMarkerSet" multiline="true">
<Begin>/\*</Begin>
<End>\*/</End>
</Span>
<Span color="String">
<Begin>"</Begin>
<End>"</End>
<RuleSet>
<!-- span for escape sequences -->
<Span begin="\\" end="."/>
</RuleSet>
</Span>
<Span color="Char">
<Begin>'</Begin>
<End>'</End>
<RuleSet>
<!-- span for escape sequences -->
<Span begin="\\" end="."/>
</RuleSet>
</Span>
<Span color="String" multiline="true">
<Begin color="String">@"</Begin>
<End>"</End>
<RuleSet>
<!-- span for escape sequences -->
<Span begin='""' end=""/>
</RuleSet>
</Span>
<!-- don't highlight "@int" as keyword -->
<Rule>
@[\w\d_]+
</Rule>
<Keywords color="ThisOrBaseReference">
<Word>this</Word>
<Word>base</Word>
</Keywords>
<Keywords color="TypeKeywords">
<Word>as</Word>
<Word>is</Word>
<Word>new</Word>
<Word>sizeof</Word>
<Word>typeof</Word>
<Word>stackalloc</Word>
</Keywords>
<Keywords color="TrueFalse">
<Word>true</Word>
<Word>false</Word>
</Keywords>
<Keywords color="Keywords">
<Word>else</Word>
<Word>if</Word>
<Word>switch</Word>
<Word>case</Word>
<Word>default</Word>
<Word>do</Word>
<Word>for</Word>
<Word>foreach</Word>
<Word>in</Word>
<Word>while</Word>
<Word>lock</Word>
</Keywords>
<Keywords color="GotoKeywords">
<Word>break</Word>
<Word>continue</Word>
<Word>goto</Word>
<Word>return</Word>
</Keywords>
<Keywords color="ContextKeywords">
<Word>yield</Word>
<Word>partial</Word>
<Word>global</Word>
<Word>where</Word>
<Word>select</Word>
<Word>group</Word>
<Word>by</Word>
<Word>into</Word>
<Word>from</Word>
<Word>ascending</Word>
<Word>descending</Word>
<Word>orderby</Word>
<Word>let</Word>
<Word>join</Word>
<Word>on</Word>
<Word>equals</Word>
<Word>var</Word>
<Word>dynamic</Word>
<Word>await</Word>
</Keywords>
<Keywords color="ExceptionKeywords">
<Word>try</Word>
<Word>throw</Word>
<Word>catch</Word>
<Word>finally</Word>
</Keywords>
<Keywords color="CheckedKeyword">
<Word>checked</Word>
<Word>unchecked</Word>
</Keywords>
<Keywords color="UnsafeKeywords">
<Word>fixed</Word>
<Word>unsafe</Word>
</Keywords>
<Keywords color="ValueTypes">
<Word>bool</Word>
<Word>byte</Word>
<Word>char</Word>
<Word>decimal</Word>
<Word>double</Word>
<Word>enum</Word>
<Word>float</Word>
<Word>int</Word>
<Word>long</Word>
<Word>sbyte</Word>
<Word>short</Word>
<Word>struct</Word>
<Word>uint</Word>
<Word>ushort</Word>
<Word>ulong</Word>
</Keywords>
<Keywords color="ReferenceTypes">
<Word>class</Word>
<Word>interface</Word>
<Word>delegate</Word>
<Word>object</Word>
<Word>string</Word>
<Word>void</Word>
</Keywords>
<Keywords color="OperatorKeywords">
<Word>explicit</Word>
<Word>implicit</Word>
<Word>operator</Word>
</Keywords>
<Keywords color="ParameterModifiers">
<Word>params</Word>
<Word>ref</Word>
<Word>out</Word>
</Keywords>
<Keywords color="Modifiers">
<Word>abstract</Word>
<Word>const</Word>
<Word>event</Word>
<Word>extern</Word>
<Word>override</Word>
<Word>readonly</Word>
<Word>sealed</Word>
<Word>static</Word>
<Word>virtual</Word>
<Word>volatile</Word>
<Word>async</Word>
</Keywords>
<Keywords color="Visibility">
<Word>public</Word>
<Word>protected</Word>
<Word>private</Word>
<Word>internal</Word>
</Keywords>
<Keywords color="NamespaceKeywords">
<Word>namespace</Word>
<Word>using</Word>
</Keywords>
<Keywords color="GetSetAddRemove">
<Word>get</Word>
<Word>set</Word>
<Word>add</Word>
<Word>remove</Word>
</Keywords>
<Keywords color="NullOrValueKeywords">
<Word>null</Word>
<!--<Word>value</Word>-->
</Keywords>
<!-- Digits -->
<Rule color="NumberLiteral">
\b0[xX][0-9a-fA-F]+ # hex number
|
( \b\d+(\.[0-9]+)? #number with optional floating point
| \.[0-9]+ #or just starting with floating point
)
([eE][+-]?[0-9]+)? # optional exponent
</Rule>
<Rule color="Punctuation">
[?,.;()\[\]{}+\-/%*&lt;&gt;^+~!|&amp;]+
</Rule>
</RuleSet>
</SyntaxDefinition>

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

@ -20,14 +20,34 @@ namespace CSharpBinding @@ -20,14 +20,34 @@ namespace CSharpBinding
// public override LanguageProperties Properties {
// get { return LanguageProperties.CSharp; }
// }
//
//
public override IBracketSearcher BracketSearcher {
get { return new CSharpBracketSearcher(); }
}
ITextEditor editor;
CSharpSemanticHighlighter semanticHighlighter;
public override void Attach(ITextEditor editor)
{
//CSharpBackgroundCompiler.Init();
base.Attach(editor);
this.editor = editor;
ISyntaxHighlighter highlighter = editor.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter;
if (highlighter != null) {
semanticHighlighter = new CSharpSemanticHighlighter(editor, highlighter.HighlightingDefinition);
highlighter.AddAdditionalHighlighter(semanticHighlighter);
}
}
public override void Detach()
{
ISyntaxHighlighter highlighter = editor.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter;
if (highlighter != null) {
highlighter.RemoveAdditionalHighlighter(semanticHighlighter);
semanticHighlighter = null;
}
this.editor = null;
base.Detach();
}
}
}

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

@ -0,0 +1,261 @@ @@ -0,0 +1,261 @@
// 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.Threading.Tasks;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Parser;
namespace CSharpBinding
{
/// <summary>
/// Semantic highlighting for C#.
/// </summary>
public class CSharpSemanticHighlighter : DepthFirstAstVisitor<object, object>, IHighlighter, IResolveVisitorNavigator
{
readonly ITextEditor textEditor;
readonly HighlightingColor typeReferenceColor;
readonly HighlightingColor methodCallColor;
readonly HighlightingColor fieldAccessColor;
readonly HighlightingColor valueKeywordColor;
int lineNumber;
HighlightedLine line;
ResolveVisitor resolveVisitor;
bool isInAccessor;
public CSharpSemanticHighlighter(ITextEditor textEditor, IHighlightingDefinition highlightingDefinition)
{
if (textEditor == null)
throw new ArgumentNullException("textEditor");
if (highlightingDefinition == null)
throw new ArgumentNullException("highlightingDefinition");
this.textEditor = textEditor;
this.typeReferenceColor = highlightingDefinition.GetNamedColor("TypeReferences");
this.methodCallColor = highlightingDefinition.GetNamedColor("MethodCall");
this.fieldAccessColor = highlightingDefinition.GetNamedColor("FieldAccess");
this.valueKeywordColor = highlightingDefinition.GetNamedColor("NullOrValueKeywords");
}
public IDocument Document {
get { return textEditor.Document; }
}
IEnumerable<HighlightingColor> IHighlighter.GetColorStack(int lineNumber)
{
return null;
}
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);
return null;
}
ParseInformation parseInfo = parseInfoTask.Result;
CSharpParsedFile parsedFile = parseInfo.ParsedFile as CSharpParsedFile;
CompilationUnit cu = parseInfo.Annotation<CompilationUnit>();
if (cu == null || parsedFile == null)
return null;
using (var ctx = ParserService.GetTypeResolveContext(parseInfo.ProjectContent).Synchronize()) {
CSharpResolver resolver = new CSharpResolver(ctx);
resolveVisitor = new ResolveVisitor(resolver, parsedFile, this);
resolveVisitor.Scan(cu);
HighlightedLine line = new HighlightedLine(textEditor.Document, textEditor.Document.GetLineByNumber(lineNumber));
this.line = line;
this.lineNumber = lineNumber;
cu.AcceptVisitor(this);
this.line = null;
this.resolveVisitor = null;
Debug.WriteLine("Semantic highlighting for line {0} - added {1} sections", lineNumber, line.Sections.Count);
return line;
}
}
HighlightingColor GetColor(ResolveResult rr)
{
if (rr is TypeResolveResult)
return typeReferenceColor;
MemberResolveResult mrr = rr as MemberResolveResult;
if (mrr != null) {
if (mrr.Member is IField)
return fieldAccessColor;
}
return null;
}
void Colorize(AstNode node, HighlightingColor color)
{
if (node.IsNull || color == null)
return;
Colorize(node.StartLocation, node.EndLocation, color);
}
void Colorize(TextLocation start, TextLocation end, HighlightingColor color)
{
if (color == null)
return;
if (start.Line == lineNumber && end.Line == lineNumber) {
int lineStartOffset = line.DocumentLine.Offset;
int startOffset = lineStartOffset + start.Column - 1;
int endOffset = lineStartOffset + end.Column - 1;
line.Sections.Add(new HighlightedSection {
Offset = startOffset,
Length = endOffset - startOffset,
Color = color
});
}
}
ResolveVisitorNavigationMode IResolveVisitorNavigator.Scan(AstNode node)
{
if (node.StartLocation.Line <= lineNumber && node.EndLocation.Line >= lineNumber) {
if (node is SimpleType || node is MemberType
|| node is IdentifierExpression || node is MemberReferenceExpression
|| node is InvocationExpression)
{
return ResolveVisitorNavigationMode.Resolve;
} else {
return ResolveVisitorNavigationMode.Scan;
}
} else {
return ResolveVisitorNavigationMode.Skip;
}
}
void IResolveVisitorNavigator.Resolved(AstNode node, ResolveResult result)
{
}
void IResolveVisitorNavigator.ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
{
}
protected override object VisitChildren(AstNode node, object data)
{
for (var child = node.FirstChild; child != null; child = child.NextSibling) {
if (child.StartLocation.Line <= lineNumber && child.EndLocation.Line >= lineNumber)
child.AcceptVisitor(this);
}
return null;
}
public override object VisitSimpleType(SimpleType simpleType, object data)
{
if (resolveVisitor.GetResolveResult(simpleType) is TypeResolveResult)
Colorize(simpleType.IdentifierToken, typeReferenceColor);
foreach (AstNode node in simpleType.TypeArguments)
node.AcceptVisitor(this);
return null;
}
public override object VisitMemberType(MemberType memberType, object data)
{
// Ensure we visit/colorize the children in the correct order.
// This is required so that the resulting HighlightedSections are sorted correctly.
memberType.Target.AcceptVisitor(this);
if (resolveVisitor.GetResolveResult(memberType) is TypeResolveResult)
Colorize(memberType.MemberNameToken, typeReferenceColor);
foreach (AstNode node in memberType.TypeArguments)
node.AcceptVisitor(this);
return null;
}
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
{
Identifier ident = identifierExpression.GetChildByRole(IdentifierExpression.Roles.Identifier);
if (isInAccessor && identifierExpression.Identifier == "value") {
Colorize(ident, valueKeywordColor);
} else {
ResolveResult rr = resolveVisitor.GetResolveResult(identifierExpression);
Colorize(ident, GetColor(rr));
}
foreach (AstNode node in identifierExpression.TypeArguments)
node.AcceptVisitor(this);
return null;
}
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
{
memberReferenceExpression.Target.AcceptVisitor(this);
ResolveResult rr = resolveVisitor.GetResolveResult(memberReferenceExpression);
Colorize(memberReferenceExpression.MemberNameToken, GetColor(rr));
foreach (AstNode node in memberReferenceExpression.TypeArguments)
node.AcceptVisitor(this);
return null;
}
public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
{
Expression target = invocationExpression.Target;
target.AcceptVisitor(this);
var rr = resolveVisitor.GetResolveResult(invocationExpression) as CSharpInvocationResolveResult;
if (rr != null && !rr.IsDelegateInvocation) {
if (target is IdentifierExpression || target is MemberReferenceExpression || target is PointerReferenceExpression) {
Colorize(target.GetChildByRole(AstNode.Roles.Identifier), methodCallColor);
}
}
foreach (AstNode node in invocationExpression.Arguments)
node.AcceptVisitor(this);
return null;
}
public override object VisitAccessor(Accessor accessor, object data)
{
isInAccessor = true;
try {
return base.VisitAccessor(accessor, data);
} finally {
isInAccessor = false;
}
}
public override object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data)
{
methodDeclaration.ReturnType.AcceptVisitor(this);
Colorize(methodDeclaration.NameToken, methodCallColor);
foreach (var node in methodDeclaration.TypeParameters)
node.AcceptVisitor(this);
foreach (var node in methodDeclaration.Parameters)
node.AcceptVisitor(this);
foreach (var node in methodDeclaration.Constraints)
node.AcceptVisitor(this);
methodDeclaration.Body.AcceptVisitor(this);
return null;
}
public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
{
Colorize(typeDeclaration, typeReferenceColor);
foreach (var node in typeDeclaration.TypeParameters)
node.AcceptVisitor(this);
foreach (var node in typeDeclaration.BaseTypes)
node.AcceptVisitor(this);
foreach (var node in typeDeclaration.Constraints)
node.AcceptVisitor(this);
foreach (var node in typeDeclaration.Members)
node.AcceptVisitor(this);
return null;
}
}
}

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs

@ -212,8 +212,6 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -212,8 +212,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
codeEditorView.TextArea.LeftMargins.Add(new ChangeMarkerMargin(changeWatcher));
}
textView.Services.AddService(typeof(ISyntaxHighlighter), new AvalonEditSyntaxHighlighterAdapter(textView));
codeEditorView.TextArea.MouseRightButtonDown += TextAreaMouseRightButtonDown;
codeEditorView.TextArea.ContextMenuOpening += TextAreaContextMenuOpening;
codeEditorView.TextArea.TextCopied += textEditor_TextArea_TextCopied;

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs

@ -515,7 +515,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -515,7 +515,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
protected override IVisualLineTransformer CreateColorizer(IHighlightingDefinition highlightingDefinition)
{
return new CustomizableHighlightingColorizer(
highlightingDefinition.MainRuleSet,
highlightingDefinition,
FetchCustomizations(highlightingDefinition.Name));
}

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

@ -14,6 +14,7 @@ using ICSharpCode.AvalonEdit.Highlighting; @@ -14,6 +14,7 @@ using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.AvalonEdit.AddIn
{
@ -22,6 +23,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -22,6 +23,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
/// </summary>
public class CustomizableHighlightingColorizer : HighlightingColorizer
{
#region ApplyCustomizationsToDefaultElements
public const string DefaultTextAndBackground = "Default text/background";
public const string SelectedText = "Selected text";
public const string NonPrintableCharacters = "Non-printable characters";
@ -93,31 +95,47 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -93,31 +95,47 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
}
}
#endregion
readonly IHighlightingDefinition highlightingDefinition;
readonly IEnumerable<CustomizedHighlightingColor> customizations;
public CustomizableHighlightingColorizer(HighlightingRuleSet ruleSet, IEnumerable<CustomizedHighlightingColor> customizations)
: base(ruleSet)
public CustomizableHighlightingColorizer(IHighlightingDefinition highlightingDefinition, IEnumerable<CustomizedHighlightingColor> customizations)
: base(highlightingDefinition.MainRuleSet)
{
if (customizations == null)
throw new ArgumentNullException("customizations");
this.highlightingDefinition = highlightingDefinition;
this.customizations = customizations;
}
protected override void OnDocumentChanged(TextView textView)
{
textView.Services.RemoveService(typeof(ISyntaxHighlighter));
base.OnDocumentChanged(textView);
textView.Services.AddService(typeof(ISyntaxHighlighter), (CustomizingHighlighter)textView.GetService(typeof(IHighlighter)));
}
protected override IHighlighter CreateHighlighter(TextView textView, TextDocument document)
{
return new CustomizingHighlighter(customizations, base.CreateHighlighter(textView, document));
return new CustomizingHighlighter(customizations, highlightingDefinition, base.CreateHighlighter(textView, document));
}
sealed class CustomizingHighlighter : IHighlighter
sealed class CustomizingHighlighter : IHighlighter, ISyntaxHighlighter
{
readonly IEnumerable<CustomizedHighlightingColor> customizations;
readonly IHighlightingDefinition highlightingDefinition;
readonly IHighlighter baseHighlighter;
List<IHighlighter> additionalHighlighters = new List<IHighlighter>();
public CustomizingHighlighter(IEnumerable<CustomizedHighlightingColor> customizations, IHighlighter baseHighlighter)
public CustomizingHighlighter(IEnumerable<CustomizedHighlightingColor> customizations, IHighlightingDefinition highlightingDefinition, IHighlighter baseHighlighter)
{
Debug.Assert(customizations != null);
Debug.Assert(highlightingDefinition != null);
Debug.Assert(baseHighlighter != null);
this.customizations = customizations;
this.highlightingDefinition = highlightingDefinition;
this.baseHighlighter = baseHighlighter;
}
@ -125,20 +143,161 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -125,20 +143,161 @@ namespace ICSharpCode.AvalonEdit.AddIn
get { return baseHighlighter.Document; }
}
public ImmutableStack<HighlightingSpan> GetSpanStack(int lineNumber)
public IHighlightingDefinition HighlightingDefinition {
get { return highlightingDefinition; }
}
public void AddAdditionalHighlighter(IHighlighter highlighter)
{
return baseHighlighter.GetSpanStack(lineNumber);
if (highlighter == null)
throw new ArgumentNullException("highlighter");
if (highlighter.Document != baseHighlighter.Document)
throw new ArgumentException("Additional highlighters must use the same document as the base highlighter");
additionalHighlighters.Add(highlighter);
}
public void RemoveAdditionalHighlighter(IHighlighter highlighter)
{
additionalHighlighters.Remove(highlighter);
}
public IEnumerable<string> GetSpanColorNamesFromLineStart(int lineNumber)
{
// delayed evaluation doesn't cause a problem here: GetColorStack is called immediately,
// only the where/select portion is evaluated later. But that won't be a problem because the
// HighlightingColor instance shouldn't change once it's in use.
return from color in GetColorStack(lineNumber - 1)
where color.Name != null
select color.Name;
}
public IEnumerable<HighlightingColor> GetColorStack(int lineNumber)
{
List<HighlightingColor> list = new List<HighlightingColor>();
for (int i = additionalHighlighters.Count - 1; i >= 0; i--) {
var s = additionalHighlighters[i].GetColorStack(lineNumber);
if (s != null)
list.AddRange(s);
}
list.AddRange(baseHighlighter.GetColorStack(lineNumber));
return list;
}
public HighlightedLine HighlightLine(int lineNumber)
{
HighlightedLine line = baseHighlighter.HighlightLine(lineNumber);
foreach (IHighlighter h in additionalHighlighters) {
MergeHighlighting(line, h.HighlightLine(lineNumber));
}
foreach (HighlightedSection section in line.Sections) {
section.Color = CustomizeColor(section.Color);
}
return line;
}
/// <summary>
/// Merges the highlighting sections from additionalLine into line.
/// </summary>
void MergeHighlighting(HighlightedLine line, HighlightedLine additionalLine)
{
if (additionalLine == null)
return;
ValidateInvariants(line);
ValidateInvariants(additionalLine);
int pos = 0;
Stack<int> activeSectionEndOffsets = new Stack<int>();
int lineEndOffset = line.DocumentLine.EndOffset;
activeSectionEndOffsets.Push(lineEndOffset);
foreach (HighlightedSection newSection in additionalLine.Sections) {
int newSectionStart = newSection.Offset;
// Track the existing sections using the stack, up to the point where
// we need to insert the first part of the newSection
while (pos < line.Sections.Count) {
HighlightedSection s = line.Sections[pos];
if (newSection.Offset < s.Offset)
break;
while (s.Offset > activeSectionEndOffsets.Peek()) {
activeSectionEndOffsets.Pop();
}
activeSectionEndOffsets.Push(s.Offset + s.Length);
pos++;
}
// Now insert the new section
// Create a copy of the stack so that we can track the sections we traverse
// during the insertion process:
Stack<int> insertionStack = new Stack<int>(activeSectionEndOffsets.Reverse());
// The stack enumerator reverses the order of the elements, so we call Reverse() to restore
// the original order.
int i;
for (i = pos; i < line.Sections.Count; i++) {
HighlightedSection s = line.Sections[i];
if (newSection.Offset + newSection.Length <= s.Offset)
break;
// Insert a segment in front of s:
Insert(line.Sections, ref i, ref newSectionStart, s.Offset, newSection.Color, insertionStack);
while (s.Offset > insertionStack.Peek()) {
insertionStack.Pop();
}
insertionStack.Push(s.Offset + s.Length);
}
Insert(line.Sections, ref i, ref newSectionStart, newSection.Offset + newSection.Length, newSection.Color, insertionStack);
}
ValidateInvariants(line);
}
void Insert(IList<HighlightedSection> sections, ref int pos, ref int newSectionStart, int insertionEndPos, HighlightingColor color, Stack<int> insertionStack)
{
if (newSectionStart >= insertionEndPos) {
// nothing to insert here
return;
}
while (insertionStack.Peek() <= newSectionStart) {
insertionStack.Pop();
}
while (insertionStack.Peek() < insertionEndPos) {
int end = insertionStack.Pop();
// insert the portion from newSectionStart to end
sections.Insert(pos++, new HighlightedSection {
Offset = newSectionStart,
Length = end - newSectionStart,
Color = color
});
newSectionStart = end;
}
sections.Insert(pos++, new HighlightedSection {
Offset = newSectionStart,
Length = insertionEndPos - newSectionStart,
Color = color
});
newSectionStart = insertionEndPos;
}
[Conditional("DEBUG")]
void ValidateInvariants(HighlightedLine line)
{
int lineStartOffset = line.DocumentLine.Offset;
int lineEndOffset = line.DocumentLine.EndOffset;
for (int i = 0; i < line.Sections.Count; i++) {
HighlightedSection s1 = line.Sections[i];
if (s1.Offset < lineStartOffset || s1.Length < 0 || s1.Offset + s1.Length > lineEndOffset)
throw new InvalidOperationException("Section is outside line bounds");
for (int j = i + 1; j < line.Sections.Count; j++) {
HighlightedSection s2 = line.Sections[j];
if (s2.Offset >= s1.Offset + s1.Length) {
// s2 is after s1
} else if (s2.Offset >= s1.Offset && s2.Offset + s2.Length <= s1.Offset + s1.Length) {
// s2 is nested within s1
} else {
throw new InvalidOperationException("Sections are overlapping or incorrectly sorted.");
}
}
}
}
HighlightingColor CustomizeColor(HighlightingColor color)
{
if (color == null || color.Name == null)

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs

@ -349,7 +349,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options @@ -349,7 +349,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options
colorizer = null;
if (item != null) {
if (item.ParentDefinition != null) {
colorizer = new CustomizableHighlightingColorizer(item.ParentDefinition.MainRuleSet, customizationsForCurrentLanguage);
colorizer = new CustomizableHighlightingColorizer(item.ParentDefinition, customizationsForCurrentLanguage);
textView.LineTransformers.Add(colorizer);
}
textEditor.Select(0, 0);

9
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/FoldingManager.cs

@ -36,15 +36,6 @@ namespace ICSharpCode.AvalonEdit.Folding @@ -36,15 +36,6 @@ namespace ICSharpCode.AvalonEdit.Folding
document.VerifyAccess();
TextDocumentWeakEventManager.Changed.AddListener(document, this);
}
/// <summary>
/// Creates a new FoldingManager instance.
/// </summary>
[Obsolete("Use the (TextDocument) constructor instead.")]
public FoldingManager(TextView textView, TextDocument document)
: this(document)
{
}
#endregion
#region ReceiveWeakEvent

15
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/DocumentHighlighter.cs

@ -157,7 +157,14 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -157,7 +157,14 @@ namespace ICSharpCode.AvalonEdit.Highlighting
}
}
/// <inheritdoc/>
/// <summary>
/// Gets the span stack at the end of the specified line.
/// -> GetSpanStack(1) returns the spans at the start of the second line.
/// </summary>
/// <remarks>
/// GetSpanStack(0) is valid and will return <see cref="InitialSpanStack"/>.
/// The elements are returned in inside-out order (first element of result enumerable is the color of the innermost span).
/// </remarks>
public SpanStack GetSpanStack(int lineNumber)
{
ThrowUtil.CheckInRangeInclusive(lineNumber, "lineNumber", 0, document.LineCount);
@ -173,6 +180,12 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -173,6 +180,12 @@ namespace ICSharpCode.AvalonEdit.Highlighting
return storedSpanStacks[lineNumber];
}
/// <inheritdoc/>
public IEnumerable<HighlightingColor> GetColorStack(int lineNumber)
{
return GetSpanStack(lineNumber).Select(s => s.SpanColor).Where(s => s != null);
}
void CheckIsHighlighting()
{
if (isHighlighting) {

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

@ -30,36 +30,20 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -30,36 +30,20 @@ namespace ICSharpCode.AvalonEdit.Highlighting
this.ruleSet = ruleSet;
}
/// <summary>
/// This constructor is obsolete - please use the other overload instead.
/// </summary>
/// <param name="textView">UNUSED</param>
/// <param name="ruleSet">The root highlighting rule set.</param>
[Obsolete("The TextView parameter is no longer used, please use the constructor taking only HighlightingRuleSet instead")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "textView")]
public HighlightingColorizer(TextView textView, HighlightingRuleSet ruleSet)
: this(ruleSet)
{
}
void textView_DocumentChanged(object sender, EventArgs e)
{
OnDocumentChanged((TextView)sender);
}
void OnDocumentChanged(TextView textView)
protected virtual void OnDocumentChanged(TextView textView)
{
// remove existing highlighter, if any exists
textView.Services.RemoveService(typeof(IHighlighter));
textView.Services.RemoveService(typeof(DocumentHighlighter));
TextDocument document = textView.Document;
if (document != null) {
IHighlighter highlighter = CreateHighlighter(textView, document);
textView.Services.AddService(typeof(IHighlighter), highlighter);
// for backward compatiblity, we're registering using both the interface and concrete types
if (highlighter is DocumentHighlighter)
textView.Services.AddService(typeof(DocumentHighlighter), highlighter);
}
}
@ -99,7 +83,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -99,7 +83,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
// We need to detect this case and issue a redraw (through TextViewDocumentHighligher.OnHighlightStateChanged)
// before the visual line construction reuses existing lines that were built using the invalid highlighting state.
lineNumberBeingColorized = e.FirstLineInView.LineNumber - 1;
highlighter.GetSpanStack(lineNumberBeingColorized);
highlighter.GetColorStack(lineNumberBeingColorized);
lineNumberBeingColorized = 0;
}
}
@ -119,7 +103,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -119,7 +103,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
// But even if we didn't highlight it, we'll have to update the highlighting state for it so that the
// proof inside TextViewDocumentHighlighter.OnHighlightStateChanged holds.
lineNumberBeingColorized = context.VisualLine.LastDocumentLine.LineNumber;
highlighter.GetSpanStack(lineNumberBeingColorized);
highlighter.GetColorStack(lineNumberBeingColorized);
lineNumberBeingColorized = 0;
}
}

12
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingManager.cs

@ -137,18 +137,6 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -137,18 +137,6 @@ namespace ICSharpCode.AvalonEdit.Highlighting
}
}
/// <summary>
/// Gets the names of the registered highlightings.
/// </summary>
[ObsoleteAttribute("Use the HighlightingDefinitions property instead.")]
public IEnumerable<string> HighlightingNames {
get {
lock (lockObj) {
return new List<string>(highlightingsByName.Keys);
}
}
}
/// <summary>
/// Gets a highlighting definition by extension.
/// Returns null if the definition is not found.

18
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/IHighlighter.cs

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.AvalonEdit.Utils;
using System.Collections.Generic;
using ICSharpCode.NRefactory.Editor;
namespace ICSharpCode.AvalonEdit.Highlighting
@ -18,12 +18,18 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -18,12 +18,18 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// </summary>
IDocument Document { get; }
/// <summary>
/// Gets the span stack at the end of the specified line.
/// -> GetSpanStack(1) returns the spans at the start of the second line.
/// <summary>
/// Gets the stack of active colors (the colors associated with the active spans) at the end of the specified line.
/// -> GetColorStack(1) returns the colors at the start of the second line.
/// </summary>
/// <remarks>GetSpanStack(0) is valid and will always return the empty stack.</remarks>
ImmutableStack<HighlightingSpan> GetSpanStack(int lineNumber);
/// <remarks>
/// GetColorStack(0) is valid and will return the empty stack.
/// The elements are returned in inside-out order (first element of result enumerable is the color of the innermost span).
/// </remarks>
IEnumerable<HighlightingColor> GetColorStack(int lineNumber);
// Starting with SD 5.0, this interface exports GetColorStack() instead of GetSpanStack().
// This was done because custom highlighter implementations might not use the HighlightingSpan class (AST-based highlighting).
/// <summary>
/// Highlights the specified document line.

1
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -96,7 +96,6 @@ @@ -96,7 +96,6 @@
</Compile>
<Compile Include="Src\Commands\SharpDevelopRoutedCommands.cs" />
<Compile Include="Src\Editor\AddInHighlightingResource.cs" />
<Compile Include="Src\Editor\AvalonEdit\AvalonEditSyntaxHighlighterAdapter.cs" />
<Compile Include="Src\Editor\AvalonEdit\AvalonEditTextEditorAdapter.cs" />
<Compile Include="Src\Editor\AvalonEdit\IndentationStrategyAdapter.cs" />
<Compile Include="Src\Editor\AvalonEdit\ISnippetElementProvider.cs" />

39
src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditSyntaxHighlighterAdapter.cs

@ -1,39 +0,0 @@ @@ -1,39 +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.Linq;
using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Highlighting;
namespace ICSharpCode.SharpDevelop.Editor.AvalonEdit
{
public class AvalonEditSyntaxHighlighterAdapter : ISyntaxHighlighter
{
ITextEditorComponent textEditor;
public AvalonEditSyntaxHighlighterAdapter(ITextEditorComponent textEditor)
{
if (textEditor == null)
throw new ArgumentNullException("textEditor");
this.textEditor = textEditor;
}
public IEnumerable<string> GetSpanColorNamesFromLineStart(int lineNumber)
{
IHighlighter highlighter = textEditor.GetService(typeof(IHighlighter)) as IHighlighter;
if (highlighter != null) {
// delayed evaluation doesn't cause a problem here: GetSpanStack is called immediately,
// only the where/select portian is evaluated later. But that won't be a problem because the
// HighlightingSpan instance shouldn't change once it's in use.
return from span in highlighter.GetSpanStack(lineNumber - 1)
where span.SpanColor != null && span.SpanColor.Name != null
select span.SpanColor.Name;
} else {
return Enumerable.Empty<string>();
}
}
}
}

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

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.AvalonEdit.Highlighting;
namespace ICSharpCode.SharpDevelop.Editor
{
@ -17,6 +18,21 @@ namespace ICSharpCode.SharpDevelop.Editor @@ -17,6 +18,21 @@ namespace ICSharpCode.SharpDevelop.Editor
/// Nested spans are returned in inside-out order (first element of result enumerable is the innermost span).
/// </summary>
IEnumerable<string> GetSpanColorNamesFromLineStart(int lineNumber);
/// <summary>
/// Gets the highlighting definition that is being used.
/// </summary>
IHighlightingDefinition HighlightingDefinition { get; }
/// <summary>
/// Adds an additional highlighting engine that runs in addition to the XSHD-based highlighting.
/// </summary>
void AddAdditionalHighlighter(IHighlighter highlighter);
/// <summary>
/// Removes an additional highlighting engine.
/// </summary>
void RemoveAdditionalHighlighter(IHighlighter highlighter);
}
public static class SyntaxHighligherKnownSpanNames

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

@ -658,13 +658,30 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -658,13 +658,30 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
Task<ParseInformation> runningAsyncParseTask;
ITextSourceVersion runningAsyncParseFileContentVersion;
public Task<ParseInformation> ParseAsync(ITextSource fileContent)
{
bool lookupOpenFileOnTargetThread;
SnapshotFileContentForAsyncOperation(ref fileContent, out lookupOpenFileOnTargetThread);
// TODO: don't use background task if fileContent was specified and up-to-date parse info is available
return System.Threading.Tasks.Task.Factory.StartNew(
ITextSourceVersion fileContentVersion = fileContent != null ? fileContent.Version : null;
if (fileContentVersion != null) {
// Optimization:
// don't start a background task if fileContent was specified and up-to-date parse info is available
lock (this) {
if (cachedParseInformation != null && bufferVersion != null && bufferVersion.BelongsToSameDocumentAs(fileContentVersion)) {
if (bufferVersion.CompareAge(fileContentVersion) >= 0) {
TaskCompletionSource<ParseInformation> tcs = new TaskCompletionSource<ParseInformation>();
tcs.SetResult(cachedParseInformation);
return tcs.Task;
}
}
}
}
var task = new Task<ParseInformation>(
delegate {
try {
if (lookupOpenFileOnTargetThread) {
@ -677,9 +694,29 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -677,9 +694,29 @@ namespace ICSharpCode.SharpDevelop.Parser
} catch (Exception ex) {
MessageService.ShowException(ex, "Error during async parse");
return null;
} finally {
lock (this) {
this.runningAsyncParseTask = null;
this.runningAsyncParseFileContentVersion = null;
}
}
}
);
if (fileContentVersion != null) {
// Optimization: when additional async parse runs are requested while the parser is already
// running for that file content, return the task that's already running
// instead of starting additional copies.
lock (this) {
if (runningAsyncParseTask != null && runningAsyncParseFileContentVersion.BelongsToSameDocumentAs(fileContentVersion)) {
if (runningAsyncParseFileContentVersion.CompareAge(fileContentVersion) >= 0)
return runningAsyncParseTask;
}
this.runningAsyncParseTask = task;
this.runningAsyncParseFileContentVersion = fileContentVersion;
}
}
task.Start();
return task;
}
public Task<IParsedFile> ParseFileAsync(IProjectContent parentProjectContent, ITextSource fileContent)
@ -1097,8 +1134,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -1097,8 +1134,7 @@ namespace ICSharpCode.SharpDevelop.Parser
var parseInfo = entry.Parse(fileContent);
if (parseInfo == null)
return null;
IProject project = GetProject(parseInfo.ProjectContent);
var context = project != null ? project.TypeResolveContext : GetDefaultTypeResolveContext();
var context = GetTypeResolveContext(parseInfo.ProjectContent);
ResolveResult rr;
using (var ctx = context.Synchronize()) {
rr = entry.parser.Resolve(parseInfo, location, ctx, cancellationToken);
@ -1118,8 +1154,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -1118,8 +1154,7 @@ namespace ICSharpCode.SharpDevelop.Parser
var parseInfo = parseInfoTask.Result;
if (parseInfo == null)
return null;
IProject project = GetProject(parseInfo.ProjectContent);
var context = project != null ? project.TypeResolveContext : GetDefaultTypeResolveContext();
var context = GetTypeResolveContext(parseInfo.ProjectContent);
ResolveResult rr;
using (var ctx = context.Synchronize()) {
rr = entry.parser.Resolve(parseInfo, location, ctx, cancellationToken);

Loading…
Cancel
Save