Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
authorMike Krüger <mkrueger@xamarin.com>2012-05-23 12:47:04 +0400
committerMike Krüger <mkrueger@xamarin.com>2012-05-23 12:47:04 +0400
commit7eb52d7b473a4c128b0462771acb2654fd303477 (patch)
tree571c7e5baabaf893c278f84482f4ae1e7baa1d0b /main/src
parent55224d5f44ef72491e2d15c62920d423165436c4 (diff)
Fixed 'Bug 4750 - Comment tasks no longer work'. The project cache
from the type system service can now be extended with meta data.
Diffstat (limited to 'main/src')
-rw-r--r--main/src/core/MonoDevelop.Ide/Makefile.am1
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksView.cs20
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs7
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/ProjectCommentTags.cs80
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs112
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj20
6 files changed, 221 insertions, 19 deletions
diff --git a/main/src/core/MonoDevelop.Ide/Makefile.am b/main/src/core/MonoDevelop.Ide/Makefile.am
index 74fe12890e..3bc36179de 100644
--- a/main/src/core/MonoDevelop.Ide/Makefile.am
+++ b/main/src/core/MonoDevelop.Ide/Makefile.am
@@ -691,6 +691,7 @@ FILES = \
MonoDevelop.Ide.TypeSystem/OutputSettings.cs \
MonoDevelop.Ide.TypeSystem/ParsedDocument.cs \
MonoDevelop.Ide.TypeSystem/PreProcessorDefine.cs \
+ MonoDevelop.Ide.TypeSystem/ProjectCommentTags.cs \
MonoDevelop.Ide.TypeSystem/ProjectContentEventArgs.cs \
MonoDevelop.Ide.TypeSystem/StockIcons.cs \
MonoDevelop.Ide.TypeSystem/Tag.cs \
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksView.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksView.cs
index a3214c193b..620076db39 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksView.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksView.cs
@@ -195,11 +195,18 @@ namespace MonoDevelop.Ide.Tasks
// Load all tags that are stored in pidb files
foreach (Project p in sln.GetAllProjects ()) {
- var pContext = TypeSystemService.GetProjectContext (p);
+ var pContext = TypeSystemService.GetProjectContentWrapper (p);
if (pContext == null)
continue;
- foreach (ProjectFile file in p.Files) {
- UpdateCommentTags (sln, file.Name, GetSpecialComments (pContext, file.Name));
+ var tags = pContext.GetExtensionObject<ProjectCommentTags> ();
+ if (tags == null) {
+ tags = new ProjectCommentTags ();
+ pContext.UpdateExtensionObject (tags);
+ tags.Update (pContext.Project);
+ } else {
+ foreach (var kv in tags.Tags) {
+ UpdateCommentTags (sln, kv.Key, kv.Value);
+ }
}
}
}
@@ -225,8 +232,11 @@ namespace MonoDevelop.Ide.Tasks
//because of parse queueing, it's possible for this event to come in after the solution is closed
//so we track which solutions are currently open so that we don't leak memory by holding
// on to references to closed projects
- if (e.Project != null && e.Project.ParentSolution != null && loadedSlns.Contains (e.Project.ParentSolution))
- UpdateCommentTags (e.Project.ParentSolution, e.FileName, e.TagComments);
+ if (e.Project != null && e.Project.ParentSolution != null && loadedSlns.Contains (e.Project.ParentSolution)) {
+ Application.Invoke (delegate {
+ UpdateCommentTags (e.Project.ParentSolution, e.FileName, e.TagComments);
+ });
+ }
}
void OnCommentTagsChanged (object sender, EventArgs e)
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs
index a209e06e22..e29aefd2d3 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs
@@ -183,6 +183,13 @@ namespace MonoDevelop.Ide.Tasks
if (handler != null)
handler (null, new TaskEventArgs (task));
}
+
+ internal static void InformCommentTasks (CommentTasksChangedEventArgs args)
+ {
+ var handler = CommentTasksChanged;
+ if (handler != null)
+ handler (null, args);
+ }
public static event EventHandler<CommentTasksChangedEventArgs> CommentTasksChanged;
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/ProjectCommentTags.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/ProjectCommentTags.cs
new file mode 100644
index 0000000000..dad1ebe4bb
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/ProjectCommentTags.cs
@@ -0,0 +1,80 @@
+//
+// ProjectCommentTags.cs
+//
+// Author:
+// Mike Krüger <mkrueger@xamarin.com>
+//
+// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Concurrent;
+using MonoDevelop.Projects;
+using MonoDevelop.Ide.Tasks;
+
+namespace MonoDevelop.Ide.TypeSystem
+{
+ [Serializable]
+ public class ProjectCommentTags
+ {
+ readonly Dictionary<string, List<Tag>> tags = new Dictionary<string, List<Tag>> ();
+
+ public IDictionary<string, List<Tag>> Tags {
+ get {
+ return tags;
+ }
+ }
+
+ public void UpdateTags (Project project, string fileName, IList<Tag> tagComments)
+ {
+ var list = tagComments == null || tagComments.Count == 0 ? null : new List<Tag> (tagComments);
+ lock (tags) {
+ List<Tag> oldList;
+ tags.TryGetValue (fileName, out oldList);
+ if (list == null && oldList == null)
+ return;
+ tags[fileName] = list;
+ TaskService.InformCommentTasks (new CommentTasksChangedEventArgs (fileName, tagComments, project));
+ }
+ }
+
+ public void RemoveFile (Project project, string fileName)
+ {
+ lock (tags) {
+ if (!tags.ContainsKey (fileName))
+ return;
+ tags[fileName] = null;
+ }
+
+ TaskService.InformCommentTasks (new CommentTasksChangedEventArgs (fileName, null, project));
+ }
+
+ public void Update (Project project)
+ {
+ System.Threading.Tasks.Task.Factory.StartNew (delegate {
+ foreach (var file in project.Files) {
+ TypeSystemService.ParseFile (project, file.FilePath);
+ }
+ });
+ }
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs
index fc1743f065..b72bd5dd06 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs
@@ -257,6 +257,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
if (wrapper != null && (result.Flags & ParsedDocumentFlags.NonSerializable) != ParsedDocumentFlags.NonSerializable) {
wrapper.UpdateContent (c => c.UpdateProjectContent (c.GetFile (fileName), result.ParsedFile));
+ UpdateParsedDocument (wrapper, result);
}
// The parsed file could be included in other projects as well, therefore
@@ -303,8 +304,10 @@ namespace MonoDevelop.Ide.TypeSystem
try {
var result = parser.Parse (true, fileName, content);
lock (projectWrapperUpdateLock) {
- if (wrapper != null && (result.Flags & ParsedDocumentFlags.NonSerializable) != ParsedDocumentFlags.NonSerializable)
+ if (wrapper != null && (result.Flags & ParsedDocumentFlags.NonSerializable) != ParsedDocumentFlags.NonSerializable) {
wrapper.UpdateContent (c => c.UpdateProjectContent (c.GetFile (fileName), result.ParsedFile));
+ UpdateParsedDocument (wrapper, result);
+ }
}
return result;
} catch (Exception e) {
@@ -522,7 +525,26 @@ namespace MonoDevelop.Ide.TypeSystem
LoggingService.LogError ("Error while touching cache directory " + cacheDir, e);
}
}
-
+
+ static void StoreExtensionObject (string cacheDir, object extensionObject)
+ {
+ if (cacheDir == null)
+ throw new ArgumentNullException ("cacheDir");
+ if (extensionObject == null)
+ throw new ArgumentNullException ("extensionObject");
+ var fileName = Path.GetTempFileName ();
+ SerializeObject (fileName, extensionObject);
+ var cacheFile = Path.Combine (cacheDir, extensionObject.GetType ().FullName + ".cache");
+
+ try {
+ if (File.Exists (cacheFile))
+ File.Delete (cacheFile);
+ File.Move (fileName, cacheFile);
+ } catch (Exception e) {
+ LoggingService.LogError ("Error whil saving cache " + cacheFile + " for extension object:"+ extensionObject, e);
+ }
+ }
+
static void StoreProjectCache (Project project, ProjectContentWrapper wrapper)
{
if (!wrapper.WasChanged)
@@ -538,11 +560,14 @@ namespace MonoDevelop.Ide.TypeSystem
try {
if (File.Exists (cacheFile))
System.IO.File.Delete (cacheFile);
-
System.IO.File.Move (fileName, cacheFile);
} catch (Exception e) {
LoggingService.LogError ("Error whil saving cache " + cacheFile, e);
}
+
+ foreach (var extensionObject in wrapper.ExtensionObjects) {
+ StoreExtensionObject (cacheDir, extensionObject);
+ }
}
#endregion
@@ -646,13 +671,71 @@ namespace MonoDevelop.Ide.TypeSystem
public class ProjectContentWrapper
{
IProjectContent content;
-
+ Dictionary<Type, object> extensionObjects = new Dictionary<Type, object> ();
+
public IProjectContent Content {
get {
return content;
}
}
-
+
+ /// <summary>
+ /// Gets the extension objects attached to the content wrapper.
+ /// </summary>
+ public IEnumerable<object> ExtensionObjects {
+ get {
+ return extensionObjects.Values;
+ }
+ }
+
+ /// <summary>
+ /// Updates an extension object for the wrapper. Note that only one extension object of a certain
+ /// type may be stored inside the project content wrapper.
+ ///
+ /// The extension objects need to be serializable and are stored in the project cache on project unload.
+ /// </summary>
+ public void UpdateExtensionObject (object ext)
+ {
+ if (ext == null)
+ throw new ArgumentNullException ("ext");
+ extensionObjects[ext.GetType ()] = ext;
+ }
+
+ /// <summary>
+ /// Gets a specific extension object. This may lazy load an existing extension object from disk,
+ /// if called the first time and a serialized extension object exists.
+ /// </summary>
+ /// <returns>
+ /// The extension object. Or null, if no extension object of the specified type was registered.
+ /// </returns>
+ /// <typeparam name='T'>
+ /// The type of the extension object.
+ /// </typeparam>
+ public T GetExtensionObject<T> () where T : class
+ {
+ object result;
+ if (extensionObjects.TryGetValue (typeof (T), out result))
+ return (T)result;
+
+ string cacheDir = GetCacheDirectory (Project.FileName);
+ if (cacheDir == null)
+ return default(T);
+
+ try {
+ string fileName = Path.Combine (cacheDir, typeof (T).FullName + ".cache");
+ if (File.Exists (fileName)) {
+ Console.WriteLine ("deserialize :" + fileName);
+ var deserialized = DeserializeObject<T> (fileName);
+ extensionObjects[typeof(T)] = deserialized;
+ return deserialized;
+ }
+ } catch (Exception) {
+ Console.WriteLine ("Can't deserialize :" + typeof (T).FullName);
+ }
+
+ return default (T);
+ }
+
public void UpdateContent (Func<IProjectContent, IProjectContent> updateFunc)
{
lock (this) {
@@ -980,7 +1063,12 @@ namespace MonoDevelop.Ide.TypeSystem
{
var project = (Project)sender;
foreach (ProjectFileEventInfo fargs in args) {
- projectContents [project].UpdateContent (c => c.UpdateProjectContent (c.GetFile (fargs.ProjectFile.Name), null));
+ var wrapper = projectContents [project];
+ var fileName = fargs.ProjectFile.Name;
+ wrapper.UpdateContent (c => c.UpdateProjectContent (c.GetFile (fileName), null));
+ var tags = wrapper.GetExtensionObject <ProjectCommentTags> ();
+ if (tags != null)
+ tags.RemoveFile (wrapper.Project, fileName);
}
}
@@ -1589,6 +1677,7 @@ namespace MonoDevelop.Ide.TypeSystem
continue;
using (var stream = new System.IO.StreamReader (fileName)) {
var parsedDocument = parser.Parse (false, fileName, stream, Context.Project);
+ UpdateParsedDocument (Context, parsedDocument);
Context.UpdateContent (c => c.UpdateProjectContent (c.GetFile (fileName), parsedDocument.ParsedFile));
}
}
@@ -1596,6 +1685,17 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
+ static void UpdateParsedDocument (ProjectContentWrapper context, ParsedDocument parsedDocument)
+ {
+ var tags = context.GetExtensionObject <ProjectCommentTags> ();
+ if (tags == null) {
+ tags = new ProjectCommentTags ();
+ context.UpdateExtensionObject (tags);
+ tags.Update (context.Project);
+ }
+ tags.UpdateTags (context.Project, parsedDocument.FileName, parsedDocument.TagComments);
+ }
+
public static event EventHandler<ProjectFileEventArgs> FileParsed;
static object parseQueueLock = new object ();
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
index 957b7a1c27..9ea3e7c521 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
@@ -44,18 +44,23 @@
<Reference Include="monodoc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
+ <Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
+ <Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
+ <Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
+ <Package>glib-sharp-2.0</Package>
</Reference>
<Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
+ <Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="System.Core" />
<Reference Include="ICSharpCode.SharpZipLib" />
@@ -64,12 +69,18 @@
<Reference Include="System.Xml.Linq" />
<Reference Include="Mono.Addins.Gui, Version=0.5.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
<SpecificVersion>False</SpecificVersion>
+ <Package>mono-addins-gui</Package>
</Reference>
<Reference Include="Mono.Addins, Version=0.5.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
<SpecificVersion>False</SpecificVersion>
+ <Package>mono-addins</Package>
</Reference>
<Reference Include="Mono.Addins.Setup, Version=0.5.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
<SpecificVersion>False</SpecificVersion>
+ <Package>mono-addins-setup</Package>
+ </Reference>
+ <Reference Include="Mono.Cecil">
+ <HintPath>..\..\..\build\bin\Mono.Cecil.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -97,14 +108,6 @@
<Name>ICSharpCode.NRefactory.CSharp</Name>
<Private>False</Private>
</ProjectReference>
- <ProjectReference Include="..\..\..\external\cecil\Mono.Cecil.csproj">
- <Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
- <Name>Mono.Cecil</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\external\cecil\symbols\mdb\Mono.Cecil.Mdb.csproj">
- <Project>{8559DD7F-A16F-46D0-A05A-9139FAEBA8FD}</Project>
- <Name>Mono.Cecil.Mdb</Name>
- </ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="templates\AppConfigFile.xft.xml">
@@ -1516,6 +1519,7 @@
<Compile Include="MonoDevelop.Ide.TypeSystem\MonoDocDocumentationProvider.cs" />
<Compile Include="MonoDevelop.Ide.Projects.OptionPanels\PortableRuntimeOptionsPanel.cs" />
<Compile Include="gtk-gui\MonoDevelop.Ide.Projects.OptionPanels.PortableRuntimeOptionsPanelWidget.cs" />
+ <Compile Include="MonoDevelop.Ide.TypeSystem\ProjectCommentTags.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Makefile.am" />