From 49f8c18d143588a76e99b4cc8a7132921f9badee Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 8 Nov 2009 22:36:52 +0000 Subject: [PATCH] Fixed SD2-1602: Order of nodes in AddIn tree path is not preserved. Fixed ArgumentNullException in TaskListPad / ParserService. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5239 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- ...efaultSchemaFileAssociationsTestFixture.cs | 22 +- .../DefaultXmlEditorOptionsTestFixture.cs | 5 +- .../XmlEditorFileExtensionsTestFixture.cs | 8 +- .../Project/Hornung.ResourceToolkit.addin | 4 - .../Properties/AssemblyInfo.cs | 5 +- .../Rendering/VisualLine.cs | 4 +- .../Project/ICSharpCode.SharpDevelop.csproj | 1 - .../ParserService/OldParserService.cs | 913 ------------------ .../Services/ParserService/ParserService.cs | 6 + .../Project/Configuration/AssemblyInfo.cs | 2 + src/Main/Core/Project/ICSharpCode.Core.csproj | 4 +- .../Core/Project/Src/AddInTree/AddIn/Codon.cs | 12 - .../Core/Project/Src/AddInTree/AddInTree.cs | 4 +- .../Project/Src/AddInTree/AddInTreeNode.cs | 121 +-- .../Project/Src/AddInTree/TopologicalSort.cs | 87 ++ src/Main/Core/Test/AssemblyInfo.cs | 6 - .../Core/Test/ICSharpCode.Core.Tests.csproj | 7 +- src/Main/Core/Test/TopologicalSortTest.cs | 39 +- .../Src/Refactoring/RefactoringProvider.cs | 3 - 19 files changed, 196 insertions(+), 1057 deletions(-) delete mode 100644 src/Main/Base/Project/Src/Services/ParserService/OldParserService.cs create mode 100644 src/Main/Core/Project/Src/AddInTree/TopologicalSort.cs diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/DefaultSchemaFileAssociationsTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/DefaultSchemaFileAssociationsTestFixture.cs index f011d6511a..c1092b8523 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/DefaultSchemaFileAssociationsTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/DefaultSchemaFileAssociationsTestFixture.cs @@ -34,16 +34,20 @@ namespace XmlEditor.Tests.Editor AddInTreeNode addinTreeNode = new AddInTreeNode(); - Properties properties = new Properties(); - properties.Set("id", ".xml"); - properties.Set("namespaceUri", "http://example.com"); - addinTreeNode.Codons.Add(new Codon(addin, "SchemaAssociation", properties, new ICondition[0])); + Properties properties1 = new Properties(); + properties1.Set("id", ".xml"); + properties1.Set("namespaceUri", "http://example.com"); - properties = new Properties(); - properties.Set("id", ".xsl"); - properties.Set("namespaceUri", "http://example.com/xsl"); - properties.Set("namespacePrefix", "xs"); - addinTreeNode.Codons.Add(new Codon(addin, "SchemaAssociation", properties, new ICondition[0])); + Properties properties2 = new Properties(); + properties2.Set("id", ".xsl"); + properties2.Set("namespaceUri", "http://example.com/xsl"); + properties2.Set("namespacePrefix", "xs"); + + addinTreeNode.AddCodons( + new Codon[] { + new Codon(addin, "SchemaAssociation", properties1, new ICondition[0]), + new Codon(addin, "SchemaAssociation", properties2, new ICondition[0]) + }); schemaAssociations = new DefaultXmlSchemaFileAssociations(addinTreeNode); } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/DefaultXmlEditorOptionsTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/DefaultXmlEditorOptionsTestFixture.cs index 80873cf464..803179533c 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/DefaultXmlEditorOptionsTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/DefaultXmlEditorOptionsTestFixture.cs @@ -51,7 +51,10 @@ namespace XmlEditor.Tests.Editor properties.Set("id", ".xml"); properties.Set("namespaceUri", "http://example.com"); properties.Set("namespacePrefix", "e"); - addinTreeNode.Codons.Add(new Codon(addin, "SchemaAssociation", properties, new ICondition[0])); + addinTreeNode.AddCodons( + new Codon[] { + new Codon(addin, "SchemaAssociation", properties, new ICondition[0]) + }); return new DefaultXmlSchemaFileAssociations(addinTreeNode); } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/XmlEditorFileExtensionsTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/XmlEditorFileExtensionsTestFixture.cs index 367bf63098..a318b42c10 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/XmlEditorFileExtensionsTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/XmlEditorFileExtensionsTestFixture.cs @@ -33,12 +33,16 @@ namespace XmlEditor.Tests.Editor AddIn addin = AddIn.Load(reader); AddInTreeNode addinTreeNode = new AddInTreeNode(); - addinTreeNode.Codons.Add(new Codon(addin, "CodeCompletionC#", new Properties(), new ICondition[0])); Properties properties = new Properties(); properties.Set("extensions", " .xml; .xsd "); properties.Set("id", "Xml"); - addinTreeNode.Codons.Add(new Codon(addin, "CodeCompletionXml", properties, new ICondition[0])); + + addinTreeNode.AddCodons( + new Codon[] { + new Codon(addin, "CodeCompletionC#", new Properties(), new ICondition[0]), + new Codon(addin, "CodeCompletionXml", properties, new ICondition[0]) + }); fileExtensions = new DefaultXmlFileExtensions(addinTreeNode); } diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Hornung.ResourceToolkit.addin b/src/AddIns/Misc/ResourceToolkit/Project/Hornung.ResourceToolkit.addin index e5699bc4e4..b66359dca9 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Hornung.ResourceToolkit.addin +++ b/src/AddIns/Misc/ResourceToolkit/Project/Hornung.ResourceToolkit.addin @@ -42,10 +42,6 @@ - - - - diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Properties/AssemblyInfo.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Properties/AssemblyInfo.cs index 55cb0f3254..29344b2922 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Properties/AssemblyInfo.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Properties/AssemblyInfo.cs @@ -9,12 +9,11 @@ using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("ICSharpCode.CodeEditor.Tests")] +[assembly: AssemblyTitle("ICSharpCode.AvalonEdit.Tests")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ICSharpCode.CodeEditor.Tests")] -[assembly: AssemblyCopyright("Copyright 2008")] +[assembly: AssemblyProduct("ICSharpCode.AvalonEdit.Tests")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs index 211c496370..a8d2977d14 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs @@ -117,8 +117,8 @@ namespace ICSharpCode.AvalonEdit.Rendering elements.Add(new VisualLineText(this, textPieceLength)); offset = textPieceEndOffset; } - // if no elements constructed / only zero-length elements constructed: - // prevent endless loop by asking the generators again for the same location + // If no elements constructed / only zero-length elements constructed: + // do not asking the generators again for the same location (would cause endless loop) askInterestOffset = 1; foreach (VisualLineElementGenerator g in generators) { if (g.cachedInterest == offset) { diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index ab51a88d22..5a59176e1f 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -285,7 +285,6 @@ Never - diff --git a/src/Main/Base/Project/Src/Services/ParserService/OldParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/OldParserService.cs deleted file mode 100644 index 6a59bb48a7..0000000000 --- a/src/Main/Base/Project/Src/Services/ParserService/OldParserService.cs +++ /dev/null @@ -1,913 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using ICSharpCode.SharpDevelop.Editor; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Text; -using System.Threading; -using ICSharpCode.Core; -using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Dom.Refactoring; -using ICSharpCode.SharpDevelop.Gui; -using ICSharpCode.SharpDevelop.Project; -using RegistryContentPair = System.Collections.Generic.KeyValuePair; - -namespace ICSharpCode.SharpDevelop -{ - public static class OldParserService - { - static IList parser; - static IList registries; - - static Dictionary projectContents = new Dictionary(); - static Dictionary parsings = new Dictionary(StringComparer.OrdinalIgnoreCase); - static ProjectContentRegistry defaultProjectContentRegistry = new ProjectContentRegistry(); - - static string domPersistencePath; - - internal static void InitializeParserService() - { - if (parser == null) { - parser = AddInTree.BuildItems("/Workspace/Parser", null, false); - registries = AddInTree.BuildItems("/Workspace/ProjectContentRegistry", null, false); - - if (!string.IsNullOrEmpty(domPersistencePath)) { - Directory.CreateDirectory(domPersistencePath); - defaultProjectContentRegistry.ActivatePersistence(domPersistencePath); - } - ProjectService.SolutionClosed += ProjectServiceSolutionClosed; - } - } - - /// - /// Gets/Sets the cache directory used for DOM persistence. - /// - public static string DomPersistencePath { - get { - return domPersistencePath; - } - set { - if (parser != null) - throw new InvalidOperationException("Cannot set DomPersistencePath after ParserService was initialized"); - domPersistencePath = value; - } - } - - public static ProjectContentRegistry DefaultProjectContentRegistry { - get { - return defaultProjectContentRegistry; - } - } - - public static IProjectContent CurrentProjectContent { - [DebuggerStepThrough] - get { - if (ProjectService.CurrentProject == null || !projectContents.ContainsKey(ProjectService.CurrentProject)) { - return DefaultProjectContent; - } - return projectContents[ProjectService.CurrentProject]; - } - } - - /// - /// Gets the list of project contents of all open projects. Does not include assembly project contents. - /// - public static IEnumerable AllProjectContents { - get { - return projectContents.Values; - } - } - - static void ProjectServiceSolutionClosed(object sender, EventArgs e) - { - abortLoadSolutionProjectsThread = true; - - lock (reParse1) { // clear queue of reparse thread - reParse1.Clear(); - reParse2.Clear(); - } - lock (projectContents) { - foreach (IProjectContent content in projectContents.Values) { - content.Dispose(); - } - projectContents.Clear(); - } - lock (parsings) { - parsings.Clear(); - } - lock (parseQueue) { - parseQueue.Clear(); - } - lastUpdateHash.Clear(); - } - - static Thread loadSolutionProjectsThread; - static bool abortLoadSolutionProjectsThread; - - // do not use an event for this because a solution might be loaded before ParserService - // is initialized - internal static void OnSolutionLoaded() - { - if (loadSolutionProjectsThread != null) { - if (!abortLoadSolutionProjectsThread) - throw new InvalidOperationException("Cannot open new solution without closing old solution!"); - if (!loadSolutionProjectsThread.Join(50)) { - // loadSolutionProjects might be waiting for main thread, so give it - // a chance to complete safethread calls by putting this method at - // the end of the invoking queue - WorkbenchSingleton.SafeThreadAsyncCall(OnSolutionLoaded); - return; - } - } - loadSolutionProjectsThread = new Thread(new ThreadStart(LoadSolutionProjects)); - loadSolutionProjectsThread.Name = "loadSolutionProjects"; - loadSolutionProjectsThread.Priority = ThreadPriority.BelowNormal; - loadSolutionProjectsThread.IsBackground = true; - loadSolutionProjectsThread.Start(); - } - - public static bool LoadSolutionProjectsThreadRunning { - get { - return loadSolutionProjectsThread != null; - } - } - - static void LoadSolutionProjects() - { - try { - abortLoadSolutionProjectsThread = false; - LoggingService.Info("Start LoadSolutionProjects thread"); - LoadSolutionProjectsInternal(); - } finally { - LoggingService.Info("LoadSolutionProjects thread ended"); - loadSolutionProjectsThread = null; - OnLoadSolutionProjectsThreadEnded(EventArgs.Empty); - } - } - - static void LoadSolutionProjectsInternal() - { - IProgressMonitor progressMonitor = StatusBarService.CreateProgressMonitor(); - List createdContents = new List(); - foreach (IProject project in ProjectService.OpenSolution.Projects) { - try { - ParseProjectContent newContent = project.CreateProjectContent(); - if (newContent != null) { - lock (projectContents) { - projectContents[project] = newContent; - } - createdContents.Add(newContent); - } - } catch (Exception e) { - MessageService.ShowException(e, "Error while retrieving project contents from " + project); - } - } - WorkbenchSingleton.SafeThreadAsyncCall(ProjectService.ParserServiceCreatedProjectContents); - try { - int workAmount = 0; - // multiply Count with 2 so that the progress bar is only at 50% when references are done - progressMonitor.BeginTask("Loading references...", createdContents.Count * 2, false); - - for (int i = 0; i < createdContents.Count; i++) { - if (abortLoadSolutionProjectsThread) return; - ParseProjectContent newContent = createdContents[i]; - progressMonitor.WorkDone = i; - try { - newContent.Initialize1(progressMonitor); - workAmount += newContent.GetInitializationWorkAmount(); - } catch (Exception e) { - MessageService.ShowException(e, "Error while initializing project references:" + newContent); - } - } - - // multiply workamount with two and start at workAmount so that the progress bar continues - // from 50% towards 100%. - progressMonitor.BeginTask("${res:ICSharpCode.SharpDevelop.Internal.ParserService.Parsing}...", workAmount * 2, false); - progressMonitor.WorkDone = workAmount; - foreach (ParseProjectContent newContent in createdContents) { - if (abortLoadSolutionProjectsThread) return; - try { - newContent.Initialize2(progressMonitor); - } catch (Exception e) { - MessageService.ShowException(e, "Error while initializing project contents:" + newContent); - } - } - } finally { - progressMonitor.Done(); - } - } - - static void InitAddedProject(object state) - { - ParseProjectContent newContent = (ParseProjectContent)state; - IProgressMonitor progressMonitor = StatusBarService.CreateProgressMonitor(); - newContent.Initialize1(progressMonitor); - progressMonitor.BeginTask("${res:ICSharpCode.SharpDevelop.Internal.ParserService.Parsing}...", newContent.GetInitializationWorkAmount(), false); - newContent.Initialize2(progressMonitor); - progressMonitor.Done(); - } - - #region Reparse projects - // queue of projects waiting to reparse references - static Queue reParse1 = new Queue(); - - // queue of projects waiting to reparse code - static Queue reParse2 = new Queue(); - static Thread reParseThread; - - static void ReparseProjects() - { - LoggingService.Info("reParse thread started"); - Thread.Sleep(100); // enable main thread to fill the queues completely - try { - ReparseProjectsInternal(); - } catch (Exception ex) { - MessageService.ShowException(ex); - } - } - - static void ReparseProjectsInternal() - { - bool parsing = false; - ParseProjectContent job; - IProgressMonitor progressMonitor = StatusBarService.CreateProgressMonitor(); - - while (true) { - // get next job - lock (reParse1) { - if (reParse1.Count > 0) { - if (parsing) { - progressMonitor.Done(); - } - parsing = false; - job = reParse1.Dequeue(); - } else if (reParse2.Count > 0) { - if (!parsing) { - int workAmount = 0; - foreach (ParseProjectContent ppc in reParse2) { - workAmount += ppc.GetInitializationWorkAmount(); - } - progressMonitor.BeginTask("${res:ICSharpCode.SharpDevelop.Internal.ParserService.Parsing}...", workAmount, false); - } - parsing = true; - job = reParse2.Dequeue(); - } else { - // all jobs done - reParseThread = null; - if (parsing) { - progressMonitor.Done(); - } - LoggingService.Info("reParse thread finished all jobs"); - return; - } - } - - // execute job - if (parsing) { - LoggingService.Info("reparsing code for " + job.Project); - job.ReInitialize2(progressMonitor); - } else { - LoggingService.Debug("reloading references for " + job.Project); - job.ReInitialize1(progressMonitor); - } - } - } - - public static void Reparse(IProject project, bool initReferences, bool parseCode) - { - ParseProjectContent pc = GetProjectContent(project) as ParseProjectContent; - if (pc != null) { - lock (reParse1) { - if (initReferences && !reParse1.Contains(pc)) { - LoggingService.Debug("Enqueue for reinitializing references: " + project); - reParse1.Enqueue(pc); - } - if (parseCode && !reParse2.Contains(pc)) { - LoggingService.Debug("Enqueue for reparsing code: " + project); - reParse2.Enqueue(pc); - } - if (reParseThread == null) { - LoggingService.Info("Starting reParse thread"); - reParseThread = new Thread(new ThreadStart(ReparseProjects)); - reParseThread.Name = "reParse"; - reParseThread.Priority = ThreadPriority.BelowNormal; - reParseThread.IsBackground = true; - reParseThread.Start(); - } - } - } - } - #endregion - - /// Can return null. - internal static IProjectContent CreateProjectContentForAddedProject(IProject project) - { - lock (projectContents) { - ParseProjectContent newContent = project.CreateProjectContent(); - if (newContent != null) { - projectContents[project] = newContent; - ThreadPool.QueueUserWorkItem(InitAddedProject, newContent); - } - return newContent; - } - } - - internal static void RemoveProjectContentForRemovedProject(IProject project) - { - lock (projectContents) { - projectContents.Remove(project); - } - } - - public static IProjectContent GetProjectContent(IProject project) - { - lock (projectContents) { - if (projectContents.ContainsKey(project)) { - return projectContents[project]; - } - } - return null; - } - - static Queue> parseQueue = new Queue>(); - - static void ParseQueue() - { - while (true) { - KeyValuePair entry; - lock (parseQueue) { - if (parseQueue.Count == 0) - return; - entry = parseQueue.Dequeue(); - } - ParseFile(entry.Key, entry.Value); - } - } - - public static void EnqueueForParsing(string fileName) - { - EnqueueForParsing(fileName, GetParseableFileContent(fileName)); - } - - public static void EnqueueForParsing(string fileName, ITextBuffer fileContent) - { - fileContent = fileContent.CreateSnapshot(); - lock (parseQueue) { - parseQueue.Enqueue(new KeyValuePair(fileName, fileContent)); - } - } - - public static void StartParserThread() - { - abortParserUpdateThread = false; - Thread parserThread = new Thread(new ThreadStart(ParserUpdateThread)); - parserThread.Name = "parser"; - parserThread.Priority = ThreadPriority.BelowNormal; - parserThread.IsBackground = true; - parserThread.Start(); - } - - public static void StopParserThread() - { - abortParserUpdateThread = true; - } - - static volatile bool abortParserUpdateThread = false; - - static Dictionary lastUpdateHash = new Dictionary(); - - static void ParserUpdateThread() - { - LoggingService.Info("ParserUpdateThread started"); - Thread.Sleep(750); - - // preload mscorlib, we're going to need it probably - IProjectContent dummyVar = defaultProjectContentRegistry.Mscorlib; - - while (!abortParserUpdateThread) { - try { - ParseQueue(); - ParserUpdateStep(); - } catch (Exception e) { - ICSharpCode.Core.MessageService.ShowException(e); - - // don't fire an exception every 2 seconds at the user, give him at least - // time to read the first :-) - Thread.Sleep(10000); - } - Thread.Sleep(2000); - } - LoggingService.Info("ParserUpdateThread stopped"); - } - - public static void ParseCurrentViewContent() - { - ParserUpdateStep(); - } - - static void ParserUpdateStep() - { - IViewContent activeViewContent = null; - string fileName = null; - bool isUntitled = false; - try { - WorkbenchSingleton.SafeThreadCall( - delegate { - try { - activeViewContent = WorkbenchSingleton.Workbench.ActiveViewContent; - if (activeViewContent != null && activeViewContent.PrimaryFile != null) { - fileName = activeViewContent.PrimaryFileName; - isUntitled = activeViewContent.PrimaryFile.IsUntitled; - } - } catch (Exception ex) { - MessageService.ShowError(ex.ToString()); - } - }); - } catch (InvalidOperationException ex) { // includes ObjectDisposedException - // maybe workbench has been disposed while waiting for the SafeThreadCall - // can occur after workbench unload or after aborting SharpDevelop with - // Application.Exit() - LoggingService.Warn("InvalidOperationException while trying to invoke GetActiveViewContent() " + ex); - return; // abort this thread - } - IEditable editable = activeViewContent as IEditable; - if (editable != null) { - if (!(fileName == null || fileName.Length == 0)) { - ParseInformation parseInformation = null; - bool updated = false; - ITextBuffer fileContent = editable.CreateSnapshot(); - if (fileContent == null) return; - parseInformation = ParseFile(fileName, fileContent, !isUntitled); - updated = true; - if (updated) { - if (parseInformation != null && editable is IParseInformationListener) { - ((IParseInformationListener)editable).ParseInformationUpdated(parseInformation); - } - } - OnParserUpdateStepFinished(new ParserUpdateStepEventArgs(fileName, fileContent, updated, parseInformation)); - } - } - } - - public static void ParseViewContent(IViewContent viewContent) - { - ITextBuffer text = ((IEditable)viewContent).CreateSnapshot(); - ParseInformation parseInformation = ParseFile(viewContent.PrimaryFileName, - text, !viewContent.PrimaryFile.IsUntitled); - if (parseInformation != null && viewContent is IParseInformationListener) { - ((IParseInformationListener)viewContent).ParseInformationUpdated(parseInformation); - } - } - - /// - /// This event is called every two seconds. It is called directly after the parser has updated the - /// project content and it is called after the parser noticed that there is nothing to update. - /// WARNING: This event is called on the parser thread - You need to use Invoke if you do - /// anything in your event handler that could touch the GUI. - /// - public static event ParserUpdateStepEventHandler ParserUpdateStepFinished; - - static void OnParserUpdateStepFinished(ParserUpdateStepEventArgs e) - { - if (ParserUpdateStepFinished != null) { - ParserUpdateStepFinished(typeof(ParserService), e); - } - } - - public static ParseInformation ParseFile(string fileName) - { - return ParseFile(fileName, null); - } - - public static ParseInformation ParseFile(string fileName, ITextBuffer fileContent) - { - return ParseFile(fileName, fileContent, true); - } - - static IProjectContent GetProjectContent(string fileName) - { - lock (projectContents) { - foreach (KeyValuePair projectContent in projectContents) { - if (projectContent.Key.IsFileInProject(fileName)) { - return projectContent.Value; - } - } - } - return null; - } - - static DefaultProjectContent defaultProjectContent; - - public static IProjectContent DefaultProjectContent { - get { - if (defaultProjectContent == null) { - lock (projectContents) { - if (defaultProjectContent == null) { - CreateDefaultProjectContent(); - } - } - } - return defaultProjectContent; - } - } - - static void CreateDefaultProjectContent() - { - LoggingService.Info("Creating default project content"); - //LoggingService.Debug("Stacktrace is:\n" + Environment.StackTrace); - defaultProjectContent = new DefaultProjectContent(); - defaultProjectContent.AddReferencedContent(defaultProjectContentRegistry.Mscorlib); - Thread t = new Thread(new ThreadStart(CreateDefaultProjectContentReferences)); - t.IsBackground = true; - t.Priority = ThreadPriority.BelowNormal; - t.Name = "CreateDefaultPC"; - t.Start(); - } - - static void CreateDefaultProjectContentReferences() - { - IList defaultReferences = AddInTree.BuildItems("/SharpDevelop/Services/ParserService/SingleFileGacReferences", null, false); - foreach (string defaultReference in defaultReferences) { - ReferenceProjectItem item = new ReferenceProjectItem(null, defaultReference); - defaultProjectContent.AddReferencedContent(ParserService.GetProjectContentForReference(item)); - } - if (WorkbenchSingleton.Workbench != null) { - WorkbenchSingleton.Workbench.ActiveViewContentChanged += delegate { - if (WorkbenchSingleton.Workbench.ActiveViewContent != null) { - string file = WorkbenchSingleton.Workbench.ActiveViewContent.PrimaryFileName; - if (file != null) { - IParser parser = GetParser(file); - if (parser != null && parser.Language != null) { - defaultProjectContent.Language = parser.Language; - defaultProjectContent.DefaultImports = parser.Language.CreateDefaultImports(defaultProjectContent); - } - } - } - }; - } - } - - public static ParseInformation ParseFile(string fileName, ITextBuffer fileContent, bool updateCommentTags) - { - return ParseFile(null, fileName, fileContent, updateCommentTags); - } - - public static ParseInformation ParseFile(IProjectContent fileProjectContent, string fileName, ITextBuffer fileContent, bool updateCommentTags) - { - if (fileName == null) throw new ArgumentNullException("fileName"); - - IParser parser = GetParser(fileName); - if (parser == null) { - return null; - } - - ICompilationUnit parserOutput = null; - - try { - if (fileProjectContent == null) { - // GetProjectContent is expensive because it compares all file names, so - // we accept the project content as optional parameter. - fileProjectContent = GetProjectContent(fileName); - if (fileProjectContent == null) { - fileProjectContent = DefaultProjectContent; - } - } - - if (fileContent == null) { - if (!File.Exists(fileName)) { - return null; - } - fileContent = GetParseableFileContent(fileName); - } - parserOutput = parser.Parse(fileProjectContent, fileName, fileContent); - parserOutput.Freeze(); - - ParseInformation parseInformation; - lock (parsings) { - if (!parsings.TryGetValue(fileName, out parseInformation)) { - parsings[fileName] = parseInformation = new ParseInformation(); - } - } - ICompilationUnit oldUnit = parseInformation.MostRecentCompilationUnit; - fileProjectContent.UpdateCompilationUnit(oldUnit, parserOutput, fileName); - parseInformation.SetCompilationUnit(parserOutput); - if (updateCommentTags) { - TaskService.UpdateCommentTags(fileName, parserOutput.TagComments); - } - try { - OnParseInformationUpdated(new ParseInformationEventArgs(fileName, fileProjectContent, oldUnit, parserOutput)); - } catch (Exception e) { - MessageService.ShowException(e); - } - return parseInformation; - } catch (Exception e) { - MessageService.ShowException(e, "Error parsing " + fileName); - } - return null; - } - - /// - /// Gets the content of the file using encoding auto-detection (or DefaultFileEncoding, if that fails). - /// If the file is already open, gets the text in the opened view content. - /// - public static ITextBuffer GetParseableFileContent(string fileName) - { - IViewContent viewContent = FileService.GetOpenFile(fileName); - IEditable editable = viewContent as IEditable; - if (editable != null) { - return editable.CreateSnapshot(); - } - //ITextBuffer res = project.GetParseableFileContent(fileName); - //if (res != null) - // return res; - - OpenedFile file = FileService.GetOpenedFile(fileName); - if (file != null) { - IFileDocumentProvider p = file.CurrentView as IFileDocumentProvider; - if (p != null) { - IDocument document = p.GetDocumentForFile(file); - if (document != null) { - return document.CreateSnapshot(); - } - } - - using(Stream s = file.OpenRead()) { - // load file - Encoding encoding = DefaultFileEncoding; - return new StringTextBuffer(ICSharpCode.TextEditor.Util.FileReader.ReadFileContent(s, ref encoding)); - } - } - - // load file - return new StringTextBuffer(ICSharpCode.TextEditor.Util.FileReader.ReadFileContent(fileName, DefaultFileEncoding)); - } - - public static Encoding DefaultFileEncoding { - get { - return DefaultEditor.Gui.Editor.SharpDevelopTextEditorProperties.Instance.Encoding; - } - } - - public static ParseInformation GetParseInformation(string fileName) - { - if (fileName == null || fileName.Length == 0) { - return null; - } - ParseInformation parseInfo; - lock (parsings) { - if (parsings.TryGetValue(fileName, out parseInfo)) - return parseInfo; - } - return ParseFile(fileName); - } - - /// - /// Registers a compilation unit in the parser service. - /// Does not fire the OnParseInformationUpdated event, please use this for unit tests only! - /// - public static ParseInformation RegisterParseInformation(string fileName, ICompilationUnit cu) - { - ParseInformation parseInformation; - lock (parsings) { - if (!parsings.TryGetValue(fileName, out parseInformation)) { - parsings[fileName] = parseInformation = new ParseInformation(); - } - } - parseInformation.SetCompilationUnit(cu); - return parseInformation; - } - - public static void ClearParseInformation(string fileName) - { - if (fileName == null || fileName.Length == 0) { - return; - } - LoggingService.Info("ClearParseInformation: " + fileName); - ParseInformation parseInfo; - lock (parsings) { - if (parsings.TryGetValue(fileName, out parseInfo)) - parsings.Remove(fileName); - else - return; - } - ICompilationUnit oldUnit = parseInfo.MostRecentCompilationUnit; - if (oldUnit != null) { - IProjectContent pc = parseInfo.MostRecentCompilationUnit.ProjectContent; - pc.RemoveCompilationUnit(oldUnit); - try { - OnParseInformationUpdated(new ParseInformationEventArgs(fileName, pc, oldUnit, null)); - } catch (Exception e) { - MessageService.ShowException(e); - } - } - } - - public static IExpressionFinder GetExpressionFinder(string fileName) - { - IParser parser = GetParser(fileName); - if (parser != null) { - return parser.CreateExpressionFinder(fileName); - } - return null; - } - - public static readonly string[] DefaultTaskListTokens = {"HACK", "TODO", "UNDONE", "FIXME"}; - - /// - /// Retrieves the IParser instance that can parse the specified file. - /// This method is thread-safe. - /// - public static IParser GetParser(string fileName) - { - if (fileName == null) - throw new ArgumentNullException("fileName"); - IParser curParser = null; - foreach (ParserDescriptor descriptor in parser) { - if (descriptor.CanParse(fileName)) { - curParser = descriptor.Parser; - break; - } - } - - if (curParser != null) { - curParser.LexerTags = PropertyService.Get("SharpDevelop.TaskListTokens", DefaultTaskListTokens); - } - - return curParser; - } - - //////////////////////////////////// - - public static ArrayList CtrlSpace(int caretLine, int caretColumn, - string fileName, string fileContent, ExpressionContext context) - { - IResolver resolver = CreateResolver(fileName); - if (resolver != null) { - return resolver.CtrlSpace(caretLine, caretColumn, GetParseInformation(fileName), fileContent, context); - } - return null; - } - - public static IResolver CreateResolver(string fileName) - { - IParser parser = GetParser(fileName); - if (parser != null) { - return parser.CreateResolver(); - } - return null; - } - - public static ResolveResult Resolve(ExpressionResult expressionResult, - int caretLineNumber, int caretColumn, - string fileName, string fileContent) - { - if (expressionResult.Region.IsEmpty) { - expressionResult.Region = new DomRegion(caretLineNumber, caretColumn); - } - IResolver resolver = CreateResolver(fileName); - if (resolver != null) { - ParseInformation parseInfo = GetParseInformation(fileName); - return resolver.Resolve(expressionResult, parseInfo, fileContent); - } - return null; - } - - static void OnParseInformationUpdated(ParseInformationEventArgs e) - { - ParseInformationEventHandler handler = ParseInformationUpdated; - if (handler != null) { - handler(null, e); - } - } - - static void OnLoadSolutionProjectsThreadEnded(EventArgs e) - { - EventHandler handler = LoadSolutionProjectsThreadEnded; - if (handler != null) { - handler(null, e); - } - } - - public static event EventHandler ParseInformationUpdated = delegate {}; - public static event EventHandler LoadSolutionProjectsThreadEnded; - - public static ProjectContentRegistry GetRegistryForReference(ReferenceProjectItem item) - { - if (item is ProjectReferenceProjectItem || item.Project == null) { - return defaultProjectContentRegistry; - } - foreach (ProjectContentRegistryDescriptor registry in registries) { - if (registry.UseRegistryForProject(item.Project)) { - ProjectContentRegistry r = registry.Registry; - if (r != null) { - return r; - } else { - return defaultProjectContentRegistry; // fallback when registry class not found - } - } - } - return defaultProjectContentRegistry; - } - - public static IProjectContent GetExistingProjectContentForReference(ReferenceProjectItem item) - { - if (item is ProjectReferenceProjectItem) { - if (((ProjectReferenceProjectItem)item).ReferencedProject == null) - { - return null; - } - return ParserService.GetProjectContent(((ProjectReferenceProjectItem)item).ReferencedProject); - } - return GetRegistryForReference(item).GetExistingProjectContent(item.FileName); - } - - public static IProjectContent GetProjectContentForReference(ReferenceProjectItem item) - { - if (item is ProjectReferenceProjectItem) { - if (((ProjectReferenceProjectItem)item).ReferencedProject == null) - { - return null; - } - return ParserService.GetProjectContent(((ProjectReferenceProjectItem)item).ReferencedProject); - } - return GetRegistryForReference(item).GetProjectContentForReference(item.Include, item.FileName); - } - - /// - /// Refreshes the project content for the specified reference if required. - /// This method does nothing if the reference is not an assembly reference, is not loaded or already is up-to-date. - /// - public static void RefreshProjectContentForReference(ReferenceProjectItem item) - { - if (item is ProjectReferenceProjectItem) { - return; - } - ProjectContentRegistry registry = GetRegistryForReference(item); - registry.RunLocked( - delegate { - IProjectContent rpc = GetExistingProjectContentForReference(item); - if (rpc == null) { - LoggingService.Debug("RefreshProjectContentForReference: not refreshing (rpc==null) " + item.FileName); - return; - } - if (rpc.IsUpToDate) { - LoggingService.Debug("RefreshProjectContentForReference: not refreshing (rpc.IsUpToDate) " + item.FileName); - return; - } - LoggingService.Debug("RefreshProjectContentForReference " + item.FileName); - - HashSet projectsToRefresh = new HashSet(); - HashSet unloadedReferenceContents = new HashSet(); - UnloadReferencedContent(projectsToRefresh, unloadedReferenceContents, registry, rpc); - - foreach (IProject p in projectsToRefresh) { - Reparse(p, true, false); - } - }); - } - - static void UnloadReferencedContent(HashSet projectsToRefresh, HashSet unloadedReferenceContents, ProjectContentRegistry referencedContentRegistry, IProjectContent referencedContent) - { - LoggingService.Debug("Unload referenced content " + referencedContent); - - List otherContentsToUnload = new List(); - foreach (ProjectContentRegistryDescriptor registry in registries) { - if (registry.IsRegistryLoaded) { - foreach (IProjectContent pc in registry.Registry.GetLoadedProjectContents()) { - if (pc.ReferencedContents.Contains(referencedContent)) { - if (unloadedReferenceContents.Add(pc)) { - LoggingService.Debug("Mark dependent content for unloading " + pc); - otherContentsToUnload.Add(new RegistryContentPair(registry.Registry, pc)); - } - } - } - } - } - - foreach (IProjectContent pc in ParserService.AllProjectContents) { - IProject project = (IProject)pc.Project; - if (projectsToRefresh.Contains(project)) - continue; - if (pc.ReferencedContents.Remove(referencedContent)) { - LoggingService.Debug("UnloadReferencedContent: Mark project for reparsing " + project.Name); - projectsToRefresh.Add(project); - } - } - - foreach (RegistryContentPair pair in otherContentsToUnload) { - UnloadReferencedContent(projectsToRefresh, unloadedReferenceContents, pair.Key, pair.Value); - } - - referencedContentRegistry.UnloadProjectContent(referencedContent); - } - } -} diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs index 03bfb0e939..bf2ec93967 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs @@ -532,6 +532,8 @@ namespace ICSharpCode.SharpDevelop /// The returned ParseInformation might be stale (re-parse is not forced). public static ParseInformation GetParseInformation(string fileName) { + if (string.IsNullOrEmpty(fileName)) + return null; return GetFileEntry(fileName, true).GetParseInformation(null); } @@ -542,6 +544,8 @@ namespace ICSharpCode.SharpDevelop /// Returns the ParseInformation for the specified file, or null if the file has not been parsed already. public static ParseInformation GetExistingParseInformation(string fileName) { + if (string.IsNullOrEmpty(fileName)) + return null; FileEntry entry = GetFileEntry(fileName, false); if (entry != null) return entry.GetExistingParseInformation(null); @@ -557,6 +561,8 @@ namespace ICSharpCode.SharpDevelop /// Returns the ParseInformation for the specified file, or null if the file has not been parsed for that project content. public static ParseInformation GetExistingParseInformation(IProjectContent content, string fileName) { + if (string.IsNullOrEmpty(fileName)) + return null; FileEntry entry = GetFileEntry(fileName, false); if (entry != null) return entry.GetExistingParseInformation(content); diff --git a/src/Main/Core/Project/Configuration/AssemblyInfo.cs b/src/Main/Core/Project/Configuration/AssemblyInfo.cs index e626e94bf0..7d1f6ee373 100644 --- a/src/Main/Core/Project/Configuration/AssemblyInfo.cs +++ b/src/Main/Core/Project/Configuration/AssemblyInfo.cs @@ -19,3 +19,5 @@ using System.Runtime.CompilerServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] + +[assembly:InternalsVisibleTo("ICSharpCode.Core.Tests,PublicKey=002400000480000094000000060200000024000052534131000400000100010063D5DB5957250F41969C79E88CBD8806165CA7D96D468A9D60F11704A8B0698684B5ACC16FC82E6CEDE459E1D6ED7384B044C47A67D68BAE1E08182473168E2AD92C6FABE32B9217EA59D05BB9A101318AEEC9F767991D2AE8D987B60C591B6020D2816C395DB7F3045A1C77C2B074C508C2B4F25DCD969688DA94EBC83F5F9B")] diff --git a/src/Main/Core/Project/ICSharpCode.Core.csproj b/src/Main/Core/Project/ICSharpCode.Core.csproj index a856555368..cb0bb5d2da 100644 --- a/src/Main/Core/Project/ICSharpCode.Core.csproj +++ b/src/Main/Core/Project/ICSharpCode.Core.csproj @@ -1,4 +1,5 @@ - + + Debug AnyCPU @@ -83,6 +84,7 @@ + diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/Codon.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/Codon.cs index a65bfc921a..8bf298ad6d 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddIn/Codon.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/Codon.cs @@ -41,26 +41,14 @@ namespace ICSharpCode.Core public string InsertAfter { get { - if (!properties.Contains("insertafter")) { - return ""; - } return properties["insertafter"]; } - set { - properties["insertafter"] = value; - } } public string InsertBefore { get { - if (!properties.Contains("insertbefore")) { - return ""; - } return properties["insertbefore"]; } - set { - properties["insertbefore"] = value; - } } public string this[string key] { diff --git a/src/Main/Core/Project/Src/AddInTree/AddInTree.cs b/src/Main/Core/Project/Src/AddInTree/AddInTree.cs index 92dfe51e36..feb66cb81a 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddInTree.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddInTree.cs @@ -225,9 +225,7 @@ namespace ICSharpCode.Core static void AddExtensionPath(ExtensionPath path) { AddInTreeNode treePath = CreatePath(rootNode, path.Name); - foreach (Codon codon in path.Codons) { - treePath.Codons.Add(codon); - } + treePath.AddCodons(path.Codons); } /// diff --git a/src/Main/Core/Project/Src/AddInTree/AddInTreeNode.cs b/src/Main/Core/Project/Src/AddInTree/AddInTreeNode.cs index 3c3f63673d..851206d31a 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddInTreeNode.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddInTreeNode.cs @@ -8,6 +8,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; namespace ICSharpCode.Core { @@ -16,9 +17,10 @@ namespace ICSharpCode.Core /// public sealed class AddInTreeNode { + readonly object lockObj = new object(); Dictionary childNodes = new Dictionary(); - List codons = new List(); - bool isSorted = false; + ReadOnlyCollection codons; + List> codonInput; /// /// A dictionary containing the child paths. @@ -29,12 +31,36 @@ namespace ICSharpCode.Core } } + public void AddCodons(ICollection newCodons) + { + if (newCodons == null) + throw new ArgumentNullException("newCodons"); + lock (lockObj) { + if (codonInput == null) { + codonInput = new List>(); + if (codons != null) + codonInput.Add(codons); + } + codonInput.Add(newCodons); + } + } + /// /// A list of child s. /// - public List Codons { + public ReadOnlyCollection Codons { get { - return codons; + lock (lockObj) { + if (codons == null) { + if (codonInput == null) { + codons = new ReadOnlyCollection(new Codon[0]); + } else { + codons = TopologicalSort.Sort(codonInput).AsReadOnly(); + codonInput = null; + } + } + return codons; + } } } @@ -57,92 +83,14 @@ namespace ICSharpCode.Core // } // } - /// - /// Supports sorting codons using InsertBefore/InsertAfter - /// - sealed class TopologicalSort - { - List codons; - bool[] visited; - List sortedCodons; - Dictionary indexOfName; - - public TopologicalSort(List codons) - { - this.codons = codons; - visited = new bool[codons.Count]; - sortedCodons = new List(codons.Count); - indexOfName = new Dictionary(codons.Count); - // initialize visited to false and fill the indexOfName dictionary - for (int i = 0; i < codons.Count; ++i) { - visited[i] = false; - indexOfName[codons[i].Id] = i; - } - } - - void InsertEdges() - { - // add the InsertBefore to the corresponding InsertAfter - for (int i = 0; i < codons.Count; ++i) { - string before = codons[i].InsertBefore; - if (before != null && before != "") { - if (indexOfName.ContainsKey(before)) { - string after = codons[indexOfName[before]].InsertAfter; - if (after == null || after == "") { - codons[indexOfName[before]].InsertAfter = codons[i].Id; - } else { - codons[indexOfName[before]].InsertAfter = after + ',' + codons[i].Id; - } - } else { - LoggingService.WarnFormatted("Codon ({0}) specified in the insertbefore of the {1} codon does not exist!", before, codons[i]); - } - } - } - } - - public List Execute() - { - InsertEdges(); - - // Visit all codons - for (int i = 0; i < codons.Count; ++i) { - Visit(i); - } - return sortedCodons; - } - - void Visit(int codonIndex) - { - if (visited[codonIndex]) { - return; - } - string[] after = codons[codonIndex].InsertAfter.Split(new char[] {','}); - foreach (string s in after) { - if (s == null || s.Length == 0) { - continue; - } - if (indexOfName.ContainsKey(s)) { - Visit(indexOfName[s]); - } else { - LoggingService.WarnFormatted("Codon ({0}) specified in the insertafter of the {1} codon does not exist!", codons[codonIndex].InsertAfter, codons[codonIndex]); - } - } - sortedCodons.Add(codons[codonIndex]); - visited[codonIndex] = true; - } - } - /// /// Builds the child items in this path. Ensures that all items have the type T. /// /// The owner used to create the objects. public List BuildChildItems(object caller) { + var codons = this.Codons; List items = new List(codons.Count); - if (!isSorted) { - codons = (new TopologicalSort(codons)).Execute(); - isSorted = true; - } foreach (Codon codon in codons) { ArrayList subItems = null; if (childNodes.ContainsKey(codon.Id)) { @@ -171,11 +119,8 @@ namespace ICSharpCode.Core /// The owner used to create the objects. public ArrayList BuildChildItems(object caller) { + var codons = this.Codons; ArrayList items = new ArrayList(codons.Count); - if (!isSorted) { - codons = (new TopologicalSort(codons)).Execute(); - isSorted = true; - } foreach (Codon codon in codons) { ArrayList subItems = null; if (childNodes.ContainsKey(codon.Id)) { @@ -207,7 +152,7 @@ namespace ICSharpCode.Core /// public object BuildChildItem(string childItemID, object caller, ArrayList subItems) { - foreach (Codon codon in codons) { + foreach (Codon codon in this.Codons) { if (codon.Id == childItemID) { return codon.BuildItem(caller, subItems); } diff --git a/src/Main/Core/Project/Src/AddInTree/TopologicalSort.cs b/src/Main/Core/Project/Src/AddInTree/TopologicalSort.cs new file mode 100644 index 0000000000..02b24fcdca --- /dev/null +++ b/src/Main/Core/Project/Src/AddInTree/TopologicalSort.cs @@ -0,0 +1,87 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; + +namespace ICSharpCode.Core +{ + /// + /// Supports sorting codons using InsertBefore/InsertAfter + /// + static class TopologicalSort + { + sealed class Node + { + internal Codon codon; + internal bool visited; + internal List previous = new List(); + + internal void Visit(List output) + { + if (visited) + return; + visited = true; + foreach (Node n in previous) + n.Visit(output); + output.Add(codon); + } + } + + public static List Sort(IEnumerable> codonInput) + { + // Step 1: create nodes for graph + Dictionary nameToNodeDict = new Dictionary(); + List allNodes = new List(); + foreach (IEnumerable codonList in codonInput) { + // create entries to preserve order within + Node previous = null; + foreach (Codon codon in codonList) { + Node node = new Node(); + node.codon = codon; + if (!string.IsNullOrEmpty(codon.Id)) + nameToNodeDict[codon.Id] = node; + // add implicit edges + if (previous != null) + node.previous.Add(previous); + + allNodes.Add(node); + previous = node; + } + } + // Step 2: create edges from InsertBefore/InsertAfter values + foreach (Node node in allNodes) { + if (!string.IsNullOrEmpty(node.codon.InsertBefore)) { + foreach (string beforeReference in node.codon.InsertBefore.Split(',')) { + Node referencedNode; + if (nameToNodeDict.TryGetValue(beforeReference, out referencedNode)) { + referencedNode.previous.Add(node); + } else { + LoggingService.WarnFormatted("Codon ({0}) specified in the insertbefore of the {1} codon does not exist!", beforeReference, node.codon); + } + } + } + if (!string.IsNullOrEmpty(node.codon.InsertAfter)) { + foreach (string afterReference in node.codon.InsertAfter.Split(',')) { + Node referencedNode; + if (nameToNodeDict.TryGetValue(afterReference, out referencedNode)) { + node.previous.Add(referencedNode); + } else { + LoggingService.WarnFormatted("Codon ({0}) specified in the insertafter of the {1} codon does not exist!", afterReference, node.codon); + } + } + } + } + // Step 3: Perform Topological Sort + List output = new List(); + foreach (Node node in allNodes) { + node.Visit(output); + } + return output; + } + } +} diff --git a/src/Main/Core/Test/AssemblyInfo.cs b/src/Main/Core/Test/AssemblyInfo.cs index a9f97766a1..b4884d2513 100644 --- a/src/Main/Core/Test/AssemblyInfo.cs +++ b/src/Main/Core/Test/AssemblyInfo.cs @@ -31,9 +31,3 @@ using System.Runtime.CompilerServices; // numbers with the '*' character (the default): [assembly: AssemblyVersion("2.0.0.1")] - -// The following attributes specify the key for the sign of your assembly. See the -// .NET Framework documentation for more information about signing. -// This is not required, if you don't want signing let these attributes like they're. -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile("")] diff --git a/src/Main/Core/Test/ICSharpCode.Core.Tests.csproj b/src/Main/Core/Test/ICSharpCode.Core.Tests.csproj index c95591acf9..ae27b48b8f 100644 --- a/src/Main/Core/Test/ICSharpCode.Core.Tests.csproj +++ b/src/Main/Core/Test/ICSharpCode.Core.Tests.csproj @@ -1,4 +1,5 @@ - + + Debug AnyCPU @@ -22,6 +23,10 @@ AnyCPU false v4.0 + True + ..\..\ICSharpCode.SharpDevelop.snk + False + File true diff --git a/src/Main/Core/Test/TopologicalSortTest.cs b/src/Main/Core/Test/TopologicalSortTest.cs index 50f36a243c..1c4c064398 100644 --- a/src/Main/Core/Test/TopologicalSortTest.cs +++ b/src/Main/Core/Test/TopologicalSortTest.cs @@ -10,20 +10,43 @@ using System.Collections.Generic; using System.IO; using NUnit.Framework; -namespace ICSharpCode.Core.Tests.AddInTreeTests.Tests +namespace ICSharpCode.Core.Tests { - /* [TestFixture] public class TopologicalSortTest { - [Test, Ignore("TODO: Write test")] + [Test] public void Test() { - List codons = new List(); - for (int i = 0; i < 5; ++i) { - codons.Add(new Codon(null, "codon" + i, null, null)); - } + var input = new List> { + new List { + CreateCodon("1"), + CreateCodon("2"), + CreateCodon("3") + }, + new List { + CreateCodon("4"), + CreateCodon("5"), + CreateCodon("6"), + }, + new List { + CreateCodon("7", insertAfter: "3"), + CreateCodon("8"), + CreateCodon("9", insertBefore: "4") + } + }; + + Assert.AreEqual(new string[] { "1", "2", "3", "7", "8", "9", "4", "5", "6" }, + TopologicalSort.Sort(input).ConvertAll(c => c.Id).ToArray()); + } + + Codon CreateCodon(string id, string insertBefore = null, string insertAfter = null) + { + Properties p = new Properties(); + p["id"] = id; + p["insertbefore"] = insertBefore; + p["insertafter"] = insertAfter; + return new Codon(null, id, p, null); } } - */ } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/RefactoringProvider.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/RefactoringProvider.cs index 7896f666ab..e8e58c07cf 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/RefactoringProvider.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/RefactoringProvider.cs @@ -95,6 +95,3 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring #endregion } } - - -