diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ParserFoldingStrategy.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ParserFoldingStrategy.cs
index f10d50ada4..e9a0a85466 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ParserFoldingStrategy.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ParserFoldingStrategy.cs
@@ -13,7 +13,7 @@ using ICSharpCode.SharpDevelop.Parser;
namespace ICSharpCode.AvalonEdit.AddIn
{
///
- /// Uses SharpDevelop.Dom to create parsing information.
+ /// Uses the NRefactory type system to create parsing information.
///
public class ParserFoldingStrategy : IDisposable
{
@@ -84,32 +84,50 @@ namespace ICSharpCode.AvalonEdit.AddIn
return;
}
DomRegion cRegion = c.BodyRegion;
- if (cRegion.IsEmpty)
- cRegion = c.Region;
- if (cRegion.BeginLine < cRegion.EndLine) {
- newFoldMarkers.Add(new NewFolding(GetOffset(cRegion.BeginLine, cRegion.BeginColumn),
- GetOffset(cRegion.EndLine, cRegion.EndColumn)));
+ if (c.BodyRegion.BeginLine < c.BodyRegion.EndLine) {
+ newFoldMarkers.Add(new NewFolding(GetStartOffset(c.BodyRegion), GetEndOffset(c.BodyRegion)));
}
foreach (var innerClass in c.NestedTypes) {
AddClassMembers(innerClass, newFoldMarkers);
}
foreach (var m in c.Members) {
- if (m.Region.EndLine < m.BodyRegion.EndLine) {
- newFoldMarkers.Add(new NewFoldingDefinition(GetOffset(m.Region.EndLine, m.Region.EndColumn),
- GetOffset(m.BodyRegion.EndLine, m.BodyRegion.EndColumn)));
+ if (m.BodyRegion.BeginLine < m.BodyRegion.EndLine) {
+ newFoldMarkers.Add(new NewFoldingDefinition(GetStartOffset(m.BodyRegion), GetEndOffset(m.BodyRegion)));
}
}
}
- int GetOffset(int line, int column)
+ int GetStartOffset(DomRegion bodyRegion)
{
- if (line < 1)
+ var document = textArea.Document;
+ if (bodyRegion.BeginLine < 1)
+ return 0;
+ if (bodyRegion.BeginLine > document.LineCount)
+ return document.TextLength;
+ var line = document.GetLineByNumber(bodyRegion.BeginLine);
+ int lineStart = line.Offset;
+ int bodyStartOffset = lineStart + bodyRegion.BeginColumn - 1;
+ for (int i = lineStart; i < bodyStartOffset; i++) {
+ if (!char.IsWhiteSpace(document.GetCharAt(i))) {
+ // Non-whitespace in front of body start:
+ // Use the body start as start offset
+ return bodyStartOffset;
+ }
+ }
+ // Only whitespace in front of body start:
+ // Use the end of the previous line as start offset
+ return line.PreviousLine != null ? line.PreviousLine.EndOffset : bodyStartOffset;
+ }
+
+ int GetEndOffset(DomRegion region)
+ {
+ if (region.EndLine < 1)
return 0;
var document = textArea.Document;
- if (line > document.LineCount)
+ if (region.EndLine > document.LineCount)
return document.TextLength;
- return document.GetOffset(line, column);
+ return document.GetOffset(region.End);
}
}
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs
index 9ec8883b9b..5a1680acdc 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs
@@ -34,11 +34,18 @@ namespace ICSharpCode.AvalonEdit.AddIn
get { return entity; }
}
- public EntityItem(IUnresolvedTypeDefinition typeDef)
+ public EntityItem(IUnresolvedTypeDefinition typeDef, ICompilation compilation)
{
this.IsInSamePart = true;
this.entity = typeDef;
- this.text = typeDef.Name;
+ var resolvedDefinition = typeDef.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)).GetDefinition();
+ if (resolvedDefinition != null) {
+ var ambience = compilation.GetAmbience();
+ ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.ShowDeclaringType;
+ this.text = ambience.ConvertEntity(resolvedDefinition);
+ } else {
+ this.text = typeDef.Name;
+ }
this.image = CompletionImage.GetImage(typeDef);
}
@@ -46,10 +53,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
this.IsInSamePart = true;
this.entity = member.UnresolvedMember;
- if (entity is ITypeDefinition)
- ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.ShowDeclaringType;
- else
- ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.ShowParameterList | ConversionFlags.ShowParameterNames;
+ ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.ShowParameterList | ConversionFlags.ShowParameterNames;
text = ambience.ConvertEntity(member);
image = CompletionImage.GetImage(member);
}
@@ -130,11 +134,12 @@ namespace ICSharpCode.AvalonEdit.AddIn
List classItems = new List();
List memberItems = new List();
- void DoUpdate(IUnresolvedFile compilationUnit)
+ void DoUpdate(IUnresolvedFile unresolvedFile)
{
classItems = new List();
- if (compilationUnit != null) {
- AddClasses(compilationUnit.TopLevelTypeDefinitions);
+ if (unresolvedFile != null) {
+ ICompilation compilation = SD.ParserService.GetCompilationForFile(FileName.Create(unresolvedFile.FileName));
+ AddClasses(unresolvedFile.TopLevelTypeDefinitions, compilation);
}
classItems.Sort();
classComboBox.ItemsSource = classItems;
@@ -163,13 +168,13 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
}
- void AddClasses(IEnumerable classes)
+ void AddClasses(IEnumerable classes, ICompilation compilation)
{
foreach (var c in classes) {
if (c.IsSynthetic)
continue;
- classItems.Add(new EntityItem(c));
- AddClasses(c.NestedTypes);
+ classItems.Add(new EntityItem(c, compilation));
+ AddClasses(c.NestedTypes, compilation);
}
}
diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
index bd3d8e277d..a339537725 100644
--- a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
+++ b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
@@ -141,6 +141,11 @@ namespace ICSharpCode.SharpDevelop.Parser
return cacheFileName;
}
+ ///
+ /// Magic number that identifies the SharpDevelop version used to create the cache file.
+ ///
+ const int cacheMagicNumber = 5002;
+
static IProjectContent TryReadFromCache(string cacheFileName)
{
if (cacheFileName == null || !File.Exists(cacheFileName))
@@ -149,6 +154,10 @@ namespace ICSharpCode.SharpDevelop.Parser
try {
using (FileStream fs = new FileStream(cacheFileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete, 4096, FileOptions.SequentialScan)) {
using (BinaryReader reader = new BinaryReaderWith7BitEncodedInts(fs)) {
+ if (reader.ReadByte() != cacheMagicNumber) {
+ LoggingService.Warn("Incorrect magic number");
+ return null;
+ }
FastSerializer s = new FastSerializer();
return (IProjectContent)s.Deserialize(reader);
}
@@ -165,6 +174,10 @@ namespace ICSharpCode.SharpDevelop.Parser
} catch (InvalidCastException ex) {
LoggingService.Warn(ex);
return null;
+ } catch (FormatException ex) {
+ // e.g. invalid 7-bit-encoded int
+ LoggingService.Warn(ex);
+ return null;
}
}
@@ -174,6 +187,7 @@ namespace ICSharpCode.SharpDevelop.Parser
Directory.CreateDirectory(Path.GetDirectoryName(cacheFileName));
using (FileStream fs = new FileStream(cacheFileName, FileMode.Create, FileAccess.Write)) {
using (BinaryWriter writer = new BinaryWriterWith7BitEncodedInts(fs)) {
+ writer.Write(cacheMagicNumber);
FastSerializer s = new FastSerializer();
s.Serialize(writer, pc);
}