3 changed files with 102 additions and 0 deletions
			
			
		@ -0,0 +1,100 @@
				@@ -0,0 +1,100 @@
					 | 
				
			||||
// 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.IO; | 
				
			||||
using System.Threading.Tasks; | 
				
			||||
using ICSharpCode.Core; | 
				
			||||
using ICSharpCode.NRefactory.CSharp; | 
				
			||||
using ICSharpCode.NRefactory.TypeSystem; | 
				
			||||
using ICSharpCode.SharpDevelop; | 
				
			||||
using ICSharpCode.SharpDevelop.Parser; | 
				
			||||
using ICSharpCode.SharpDevelop.Project; | 
				
			||||
using ICSharpCode.SharpDevelop.Refactoring; | 
				
			||||
using CSharpBinding.Parser; | 
				
			||||
 | 
				
			||||
namespace CSharpBinding.Refactoring | 
				
			||||
{ | 
				
			||||
	[ContextAction("Rename file to match type name", Description = "Renames the file so that it matches the type name.")] | 
				
			||||
	public class RenameFileToMatchTypeNameContextAction : ContextAction | 
				
			||||
	{ | 
				
			||||
		public override async Task<bool> IsAvailableAsync(EditorRefactoringContext context, System.Threading.CancellationToken cancellationToken) | 
				
			||||
		{ | 
				
			||||
			SyntaxTree st = await context.GetSyntaxTreeAsync().ConfigureAwait(false); | 
				
			||||
			Identifier identifier = (Identifier) st.GetNodeAt(context.CaretLocation, node => node.Role == Roles.Identifier); | 
				
			||||
			if (identifier == null) | 
				
			||||
				return false; | 
				
			||||
			if (identifier.Name.Equals(Path.GetFileNameWithoutExtension(context.FileName), StringComparison.OrdinalIgnoreCase)) | 
				
			||||
				return false; | 
				
			||||
			if (identifier.Parent.Parent is TypeDeclaration) | 
				
			||||
				return false; | 
				
			||||
			ParseInformation info = await context.GetParseInformationAsync().ConfigureAwait(false); | 
				
			||||
			if (info.UnresolvedFile.TopLevelTypeDefinitions.Count > 1) | 
				
			||||
				return false; | 
				
			||||
			return identifier.Parent is TypeDeclaration || identifier.Parent is DelegateDeclaration || identifier.Parent is EnumMemberDeclaration; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		public override void Execute(EditorRefactoringContext context) | 
				
			||||
		{ | 
				
			||||
			CSharpFullParseInformation parseInformation = context.GetParseInformation() as CSharpFullParseInformation; | 
				
			||||
			if (parseInformation != null) { | 
				
			||||
				SyntaxTree st = parseInformation.SyntaxTree; | 
				
			||||
				Identifier identifier = (Identifier) st.GetNodeAt(context.CaretLocation, node => node.Role == Roles.Identifier); | 
				
			||||
				if (identifier == null) | 
				
			||||
					return; | 
				
			||||
				 | 
				
			||||
				ICompilation compilation = context.GetCompilation(); | 
				
			||||
				IProject project = compilation.GetProject(); | 
				
			||||
				RenameFile(project, context.FileName, Path.Combine(Path.GetDirectoryName(context.FileName), MakeValidFileName(identifier.Name))); | 
				
			||||
				if (project != null) { | 
				
			||||
					project.Save(); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		public override string DisplayName { | 
				
			||||
			get { | 
				
			||||
				// TODO Use the string from resource file! But this needs to become GetDisplayName(context) first.
 | 
				
			||||
				return "Rename file to match type name"; | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		string MakeValidFileName(string name) | 
				
			||||
		{ | 
				
			||||
			if (name == null) | 
				
			||||
				throw new ArgumentNullException("name"); | 
				
			||||
			if (name.IndexOfAny(Path.GetInvalidFileNameChars()) > -1) | 
				
			||||
				return name.RemoveAny(Path.GetInvalidFileNameChars()) + ".cs"; | 
				
			||||
			return name + ".cs"; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		/// <summary>
 | 
				
			||||
		/// Renames file as well as files it is dependent upon.
 | 
				
			||||
		/// </summary>
 | 
				
			||||
		static void RenameFile(IProject p, string oldFileName, string newFileName) | 
				
			||||
		{ | 
				
			||||
			FileService.RenameFile(oldFileName, newFileName, false); | 
				
			||||
			if (p != null) { | 
				
			||||
				string oldPrefix = Path.GetFileNameWithoutExtension(oldFileName) + "."; | 
				
			||||
				string newPrefix = Path.GetFileNameWithoutExtension(newFileName) + "."; | 
				
			||||
				foreach (ProjectItem item in p.Items) { | 
				
			||||
					FileProjectItem fileItem = item as FileProjectItem; | 
				
			||||
					if (fileItem == null) | 
				
			||||
						continue; | 
				
			||||
					string dependentUpon = fileItem.DependentUpon; | 
				
			||||
					if (string.IsNullOrEmpty(dependentUpon)) | 
				
			||||
						continue; | 
				
			||||
					string directory = Path.GetDirectoryName(fileItem.FileName); | 
				
			||||
					dependentUpon = Path.Combine(directory, dependentUpon); | 
				
			||||
					if (FileUtility.IsEqualFileName(dependentUpon, oldFileName)) { | 
				
			||||
						fileItem.DependentUpon = FileUtility.GetRelativePath(directory, newFileName); | 
				
			||||
						string fileName = Path.GetFileName(fileItem.FileName); | 
				
			||||
						if (fileName.StartsWith(oldPrefix)) { | 
				
			||||
							RenameFile(p, fileItem.FileName, Path.Combine(directory, newPrefix + fileName.Substring(oldPrefix.Length))); | 
				
			||||
						} | 
				
			||||
					} | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue