Browse Source

Enable new context actions (Create Local, Extract Field, Implement Interface).

Allow clicking on track adorners.
Don't serialize project content on shutdown when it hasn't changed.
newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
80dc644829
  1. 14
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
  2. 1
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
  3. 16
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDRedundantUsingIssue.cs
  4. 50
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/EnhancedScrollBar.cs
  5. 4
      src/Main/Base/Project/Src/Project/MSBuildInternals.cs
  6. 79
      src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs

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

@ -145,7 +145,7 @@ @@ -145,7 +145,7 @@
<Class id = "RedundantThis"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.RedundantThisIssue" />
<Class id = "RedundantUsing"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.RedundantUsingIssue" />
class = "CSharpBinding.Refactoring.SDRedundantUsingIssue" />
<Class id = "StringIsNullOrEmpty"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.StringIsNullOrEmptyIssue" />
<Class id = "UseVarKeyword"
@ -178,18 +178,20 @@ @@ -178,18 +178,20 @@
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateDelegateAction" />
<CSharpCodeActionProvider id = "CreateEventInvocator"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateEventInvocatorAction" />
<CSharpCodeActionProvider id = "CreateLocalVariable"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateLocalVariableAction" />
<CSharpCodeActionProvider id = "CreateField"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateFieldAction" />
<CSharpCodeActionProvider id = "CreateIndexer"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateIndexerAction" />
<CSharpCodeActionProvider id = "CreateLocalVariable"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateLocalVariableAction" />
<CSharpCodeActionProvider id = "CreateMethodDeclaration"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateMethodDeclarationAction" />
<CSharpCodeActionProvider id = "CreateProperty"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreatePropertyAction" />
<CSharpCodeActionProvider id = "DeclareLocalVariable"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.DeclareLocalVariableAction" />
<CSharpCodeActionProvider id = "ExtractField"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.ExtractFieldAction" />
<CSharpCodeActionProvider id = "FlipOperatorArguments"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.FlipOperatorArgumentsAction" />
<CSharpCodeActionProvider id = "GenerateGetter"
@ -198,6 +200,12 @@ @@ -198,6 +200,12 @@
class = "ICSharpCode.NRefactory.CSharp.Refactoring.GeneratePropertyAction" />
<CSharpCodeActionProvider id = "GenerateSwitchLabels"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.GenerateSwitchLabelsAction" />
<CSharpCodeActionProvider id = "ImplementAbstractMembers"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.ImplementAbstractMembersAction" />
<CSharpCodeActionProvider id = "ImplementInterface"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.ImplementInterfaceAction" />
<CSharpCodeActionProvider id = "ImplementInterfaceExplicit"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.ImplementInterfaceExplicitAction" />
<CSharpCodeActionProvider id = "InlineLocalVariable"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.InlineLocalVariableAction" />
<CSharpCodeActionProvider id = "InsertAnonymousMethodSignature"

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

@ -74,6 +74,7 @@ @@ -74,6 +74,7 @@
<Compile Include="Src\Refactoring\CSharpContextActionWrapper.cs" />
<Compile Include="Src\Refactoring\IssueManager.cs" />
<Compile Include="Src\Refactoring\IssueOptionsViewModel.cs" />
<Compile Include="Src\Refactoring\SDRedundantUsingIssue.cs" />
<Compile Include="Src\Refactoring\SDScript.cs" />
<EmbeddedResource Include="Resources\BuildOptions.xfrm" />
<EmbeddedResource Include="Resources\MyNamespaceSupportForCSharp.cs" />

16
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDRedundantUsingIssue.cs

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
// 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.NRefactory.CSharp.Refactoring;
namespace CSharpBinding.Refactoring
{
public class SDRedundantUsingIssue : RedundantUsingIssue
{
public SDRedundantUsingIssue()
{
base.NamespacesToKeep.Add("System");
}
}
}

50
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/EnhancedScrollBar.cs

@ -214,6 +214,8 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -214,6 +214,8 @@ namespace ICSharpCode.AvalonEdit.AddIn
this.editor = enhanchedScrollBar.editor;
this.textMarkerService = enhanchedScrollBar.textMarkerService;
this.Cursor = Cursors.Hand;
triangleGeometry = new StreamGeometry();
using (var ctx = triangleGeometry.Open()) {
const double triangleSize = 6.5;
@ -247,7 +249,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -247,7 +249,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
var textView = editor.TextArea.TextView;
double documentHeight = textView.DocumentHeight;
foreach (var marker in textMarkerService.TextMarkers) {
if ((marker.MarkerTypes & (TextMarkerTypes.ScrollBarLeftTriangle | TextMarkerTypes.ScrollBarRightTriangle)) == 0)
if (!IsVisibleInAdorner(marker))
continue;
var location = document.GetLocation(marker.StartOffset);
double visualTop = textView.GetVisualTopByDocumentLine(location.Line);
@ -271,6 +273,52 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -271,6 +273,52 @@ namespace ICSharpCode.AvalonEdit.AddIn
drawingContext.Pop();
}
}
bool IsVisibleInAdorner(ITextMarker marker)
{
return (marker.MarkerTypes & (TextMarkerTypes.ScrollBarLeftTriangle | TextMarkerTypes.ScrollBarRightTriangle)) != 0;
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
var marker = FindNextMarker(e);
if (marker != null) {
var location = editor.Document.GetLocation(marker.StartOffset);
// Use JumpTo() if possible
var textEditor = editor.TextArea.GetService(typeof(ITextEditor)) as ITextEditor;
if (textEditor != null)
textEditor.JumpTo(location.Line, location.Column);
else
editor.ScrollTo(location.Line, location.Column);
}
}
ITextMarker FindNextMarker(MouseButtonEventArgs e)
{
var mousePos = e.GetPosition(this);
var renderSize = this.RenderSize;
var document = editor.Document;
var textView = editor.TextArea.TextView;
double documentHeight = textView.DocumentHeight;
ITextMarker bestMarker = null;
double bestDistance = double.PositiveInfinity;
foreach (var marker in textMarkerService.TextMarkers) {
if (!IsVisibleInAdorner(marker))
continue;
var location = document.GetLocation(marker.StartOffset);
double visualTop = textView.GetVisualTopByDocumentLine(location.Line);
double renderPos = visualTop / documentHeight * renderSize.Height;
double distance = Math.Abs(renderPos - mousePos.Y);
if (distance < bestDistance) {
bestDistance = distance;
bestMarker = marker;
}
}
return bestMarker;
}
}
#endregion
}

4
src/Main/Base/Project/Src/Project/MSBuildInternals.cs

@ -220,11 +220,11 @@ namespace ICSharpCode.SharpDevelop.Project @@ -220,11 +220,11 @@ namespace ICSharpCode.SharpDevelop.Project
BuildParameters parameters = new BuildParameters(baseProject.MSBuildProjectCollection);
parameters.Loggers = loggers;
LoggingService.Debug("Started build for ResolveAssemblyReferences");
//LoggingService.Debug("Started build for ResolveAssemblyReferences");
BuildResult result = BuildManager.DefaultBuildManager.Build(parameters, requestData);
if (result == null)
throw new InvalidOperationException("BuildResult is null");
LoggingService.Debug("Build for ResolveAssemblyReferences finished: " + result.OverallResult);
//LoggingService.Debug("Build for ResolveAssemblyReferences finished: " + result.OverallResult);
}
IEnumerable<ProjectItemInstance> resolvedAssemblyProjectItems = project.GetItems("_ResolveAssemblyReferenceResolvedFiles");

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

@ -33,6 +33,14 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -33,6 +33,14 @@ namespace ICSharpCode.SharpDevelop.Parser
IAssemblyReference[] references = { MinimalCorlib.Instance };
bool disposed;
/// <summary>
/// Counter that gets decremented whenever a file gets parsed.
/// Once the counter reaches zero, it stays at zero and triggers
/// serialization of the project content on disposal.
/// This is intended to prevent serialization of (almost) unchanged projects.
/// </summary>
bool serializedProjectContentIsUpToDate;
// time necessary for loading references, in relation to time for a single C# file
const int LoadingReferencesWorkAmount = 15;
@ -69,37 +77,55 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -69,37 +77,55 @@ namespace ICSharpCode.SharpDevelop.Parser
{
ProjectService.ProjectItemAdded -= OnProjectItemAdded;
ProjectService.ProjectItemRemoved -= OnProjectItemRemoved;
IProjectContent pc;
bool serializeOnDispose;
lock (lockObj) {
if (disposed)
return;
disposed = true;
pc = this.projectContent;
serializeOnDispose = !this.serializedProjectContentIsUpToDate;
}
foreach (var parsedFile in projectContent.Files) {
foreach (var parsedFile in pc.Files) {
SD.ParserService.RemoveOwnerProject(FileName.Create(parsedFile.FileName), project);
}
var pc = projectContent;
Task.Run(
if (serializeOnDispose)
SerializeAsync(cacheFileName, pc).FireAndForget();
}
#region Caching logic (serialization)
static Task SerializeAsync(string cacheFileName, IProjectContent pc)
{
if (cacheFileName == null)
return Task.FromResult<object>(null);
return Task.Run(
delegate {
pc = pc.RemoveAssemblyReferences(pc.AssemblyReferences);
int serializableFileCount = 0;
List<IParsedFile> nonSerializableParsedFiles = new List<IParsedFile>();
foreach (var parsedFile in pc.Files) {
if (!parsedFile.GetType().IsSerializable || parsedFile.LastWriteTime == default(DateTime))
nonSerializableParsedFiles.Add(parsedFile);
else
if (IsSerializable(parsedFile))
serializableFileCount++;
else
nonSerializableParsedFiles.Add(parsedFile);
}
// remove non-serializable parsed files
if (nonSerializableParsedFiles.Count > 0)
pc = pc.UpdateProjectContent(nonSerializableParsedFiles, null);
if (serializableFileCount > 3)
if (serializableFileCount > 3) {
LoggingService.Debug("Serializing " + serializableFileCount + " files to " + cacheFileName);
SaveToCache(cacheFileName, pc);
else
} else {
RemoveCache(cacheFileName);
}).FireAndForget();
}
});
}
#region Caching logic (serialization)
static bool IsSerializable(IParsedFile parsedFile)
{
return parsedFile != null && parsedFile.GetType().IsSerializable && parsedFile.LastWriteTime != default(DateTime);
}
static string GetCacheFileName(FileName projectFileName)
{
@ -139,9 +165,6 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -139,9 +165,6 @@ namespace ICSharpCode.SharpDevelop.Parser
static void SaveToCache(string cacheFileName, IProjectContent pc)
{
if (cacheFileName == null)
return;
LoggingService.Debug("Serializing to " + cacheFileName);
try {
Directory.CreateDirectory(Path.GetDirectoryName(cacheFileName));
using (FileStream fs = new FileStream(cacheFileName, FileMode.Create, FileAccess.Write)) {
@ -160,7 +183,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -160,7 +183,7 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
void RemoveCache(string cacheFileName)
static void RemoveCache(string cacheFileName)
{
if (cacheFileName == null)
return;
@ -187,8 +210,10 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -187,8 +210,10 @@ namespace ICSharpCode.SharpDevelop.Parser
{
// This method is called by the parser service within the parser service (per-file) lock.
lock (lockObj) {
if (!disposed)
if (!disposed) {
projectContent = projectContent.UpdateProjectContent(oldFile, newFile);
serializedProjectContentIsUpToDate = false;
}
SD.ParserService.InvalidateCurrentSolutionSnapshot();
}
}
@ -228,6 +253,9 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -228,6 +253,9 @@ namespace ICSharpCode.SharpDevelop.Parser
object progressLock = new object();
double fileCountInverse = 1.0 / filesToParse.Count;
int fileCountLoadedFromCache = 0;
int fileCountParsed = 0;
int fileCountParsedAndSerializable = 0;
Parallel.ForEach(
filesToParse,
new ParallelOptions {
@ -237,8 +265,9 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -237,8 +265,9 @@ namespace ICSharpCode.SharpDevelop.Parser
fileName => {
ITextSource content = finder.CreateForOpenFile(fileName);
bool wasLoadedFromCache = false;
IParsedFile parsedFile = null;
if (content == null && cachedPC != null) {
IParsedFile parsedFile = cachedPC.GetFile(fileName);
parsedFile = cachedPC.GetFile(fileName);
if (parsedFile != null && parsedFile.LastWriteTime == File.GetLastWriteTimeUtc(fileName)) {
SD.ParserService.RegisterParsedFile(fileName, project, parsedFile);
wasLoadedFromCache = true;
@ -253,14 +282,26 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -253,14 +282,26 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
if (content != null) {
SD.ParserService.ParseFile(fileName, content, project);
parsedFile = SD.ParserService.ParseFile(fileName, content, project);
}
}
lock (progressLock) {
if (wasLoadedFromCache) {
fileCountLoadedFromCache++;
} else {
fileCountParsed++;
if (IsSerializable(parsedFile))
fileCountParsedAndSerializable++;
}
progressMonitor.Progress += fileCountInverse;
}
}
);
});
LoggingService.Debug(projectContent.AssemblyName + ": ParseFiles() finished. "
+ fileCountLoadedFromCache + " files were re-used from CC cache; "
+ fileCountParsed + " files were parsed (" + fileCountParsedAndSerializable + " of those are serializable)");
lock (lockObj) {
serializedProjectContentIsUpToDate = (fileCountLoadedFromCache > 0 && fileCountParsedAndSerializable == 0);
}
}
Task ResolveReferencesAsync(ICollection<ProjectItem> projectItems, IProgressMonitor progressMonitor)

Loading…
Cancel
Save