⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 languageconverter.cs

📁 SharpDevelop2.0.0 c#开发免费工具
💻 CS
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
//     <version>$Revision: 1420 $</version>
// </file>

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project.Commands;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.AST;
using ICSharpCode.NRefactory.PrettyPrinter;

namespace ICSharpCode.SharpDevelop.Project.Converter
{
	/// <summary>
	/// Converts projects from one language to another, for example C# &lt;-&gt; VB
	/// </summary>
	public abstract class LanguageConverter : AbstractMenuCommand
	{
		protected abstract IProject CreateProject(string targetProjectDirectory, IProject sourceProject);
		protected virtual void AfterConversion(IProject targetProject) {}
		
		public abstract string TargetLanguageName { get; }
		
		protected virtual void ConvertFile(FileProjectItem sourceItem, FileProjectItem targetItem)
		{
			if (!File.Exists(targetItem.FileName)) {
				File.Copy(sourceItem.FileName, targetItem.FileName);
			}
		}
		
		protected virtual void CopyProperties(IProject sourceProject, IProject targetProject)
		{
			AbstractProject sp = sourceProject as AbstractProject;
			AbstractProject tp = targetProject as AbstractProject;
			if (sp != null && tp != null) {
				tp.Configurations.Clear();
				tp.UserConfigurations.Clear();
				foreach (KeyValuePair<string, PropertyGroup> pair in sp.Configurations) {
					tp.Configurations.Add(pair.Key, pair.Value.Clone());
				}
				foreach (KeyValuePair<string, PropertyGroup> pair in sp.UserConfigurations) {
					tp.UserConfigurations.Add(pair.Key, pair.Value.Clone());
				}
				tp.BaseConfiguration.Merge(sp.BaseConfiguration);
				tp.UserBaseConfiguration.Merge(sp.UserBaseConfiguration);
			}
		}
		
		/// <summary>
		/// Changes a property in the <paramref name="project"/> by applying a method to its value.
		/// </summary>
		protected void FixProperty(AbstractProject project, string propertyName, Converter<string, string> method)
		{
			if (project.BaseConfiguration.IsSet(propertyName))
				project.BaseConfiguration[propertyName] = method(project.BaseConfiguration[propertyName]);
			if (project.UserBaseConfiguration.IsSet(propertyName))
				project.UserBaseConfiguration[propertyName] = method(project.UserBaseConfiguration[propertyName]);
			foreach (PropertyGroup pg in project.Configurations.Values) {
				if (pg.IsSet(propertyName))
					pg[propertyName] = method(pg[propertyName]);
			}
			foreach (PropertyGroup pg in project.UserConfigurations.Values) {
				if (pg.IsSet(propertyName))
					pg[propertyName] = method(pg[propertyName]);
			}
		}
		
		protected virtual void FixExtensionOfExtraProperties(FileProjectItem item, string sourceExtension, string targetExtension)
		{
			sourceExtension = sourceExtension.ToLowerInvariant();
			
			List<KeyValuePair<string, string>> replacements = new List<KeyValuePair<string, string>>();
			foreach (KeyValuePair<string, string> pair in item.Properties) {
				if ("Include".Equals(pair.Key, StringComparison.OrdinalIgnoreCase))
					continue;
				if (pair.Value.ToLowerInvariant().EndsWith(sourceExtension)) {
					replacements.Add(pair);
				}
			}
			foreach (KeyValuePair<string, string> pair in replacements) {
				item.Properties[pair.Key] = Path.ChangeExtension(pair.Value, targetExtension);
			}
		}
		
		protected virtual void CopyItems(IProject sourceProject, IProject targetProject)
		{
			foreach (ProjectItem item in sourceProject.Items) {
				FileProjectItem fileItem = item as FileProjectItem;
				if (fileItem != null && FileUtility.IsBaseDirectory(sourceProject.Directory, fileItem.FileName)) {
					FileProjectItem targetItem = new FileProjectItem(targetProject, fileItem.ItemType);
					fileItem.CopyExtraPropertiesTo(targetItem);
					targetItem.Include = fileItem.Include;
					if (File.Exists(fileItem.FileName)) {
						if (!Directory.Exists(Path.GetDirectoryName(targetItem.FileName))) {
							Directory.CreateDirectory(Path.GetDirectoryName(targetItem.FileName));
						}
						ConvertFile(fileItem, targetItem);
					}
					targetProject.Items.Add(targetItem);
				} else {
					// Adding the same item to two projects is only allowed because we will save and reload
					// the target project.
					targetProject.Items.Add(item);
				}
			}
		}
		
		protected StringBuilder conversionLog;
		
		public override void Run()
		{
			conversionLog = new StringBuilder();
			conversionLog.AppendLine("SharpDevelop Project Converter");
			conversionLog.AppendLine("==============================");
			conversionLog.AppendLine("");
			IProject sourceProject = ProjectService.CurrentProject;
			string targetProjectDirectory = sourceProject.Directory + ".ConvertedTo" + TargetLanguageName;
			if (Directory.Exists(targetProjectDirectory)) {
				MessageService.ShowMessage(targetProjectDirectory + " already exists, cannot convert.");
				return;
			}
			conversionLog.AppendLine("Source: " + sourceProject.Directory);
			conversionLog.AppendLine("Target: " + targetProjectDirectory);
			
			Directory.CreateDirectory(targetProjectDirectory);
			IProject targetProject = CreateProject(targetProjectDirectory, sourceProject);
			CopyProperties(sourceProject, targetProject);
			conversionLog.AppendLine();
			CopyItems(sourceProject, targetProject);
			conversionLog.AppendLine();
			AfterConversion(targetProject);
			conversionLog.AppendLine("Conversion complete.");
			targetProject.Save();
			targetProject.Dispose();
			TreeNode node = ProjectBrowserPad.Instance.SelectedNode;
			if (node == null) {
				node = ProjectBrowserPad.Instance.SolutionNode;
			}
			while (node != null) {
				if (node is ISolutionFolderNode) {
					AddExitingProjectToSolution.AddProject((ISolutionFolderNode)node, targetProject.FileName);
					ProjectService.SaveSolution();
					break;
				}
				node = node.Parent;
			}
			ICSharpCode.SharpDevelop.Gui.IWorkbenchWindow newFileWindow;
			newFileWindow = FileService.NewFile("Conversion Results", "Text", conversionLog.ToString());
			if (newFileWindow != null) {
				newFileWindow.ViewContent.IsDirty = false;
			}
		}
	}
	
	public abstract class NRefactoryLanguageConverter : LanguageConverter
	{
		protected abstract void ConvertAst(CompilationUnit compilationUnit, List<ISpecial> specials);
		
		protected void ConvertFile(FileProjectItem sourceItem, FileProjectItem targetItem,
		                           string sourceExtension, string targetExtension,
		                           SupportedLanguage sourceLanguage, IOutputASTVisitor outputVisitor)
		{
			FixExtensionOfExtraProperties(targetItem, sourceExtension, targetExtension);
			if (sourceExtension.Equals(Path.GetExtension(sourceItem.FileName), StringComparison.OrdinalIgnoreCase)) {
				string code = ParserService.GetParseableFileContent(sourceItem.FileName);
				IParser p = ParserFactory.CreateParser(sourceLanguage, new StringReader(code));
				p.Parse();
				if (p.Errors.count > 0) {
					conversionLog.AppendLine();
					conversionLog.AppendLine(sourceItem.FileName + " is not converted:");
					conversionLog.AppendLine("Parser found " + p.Errors.count + " error(s)");
					conversionLog.AppendLine(p.Errors.ErrorOutput);
					base.ConvertFile(sourceItem, targetItem);
					return;
				}
				
				List<ISpecial> specials = p.Lexer.SpecialTracker.CurrentSpecials;
				
				ConvertAst(p.CompilationUnit, specials);
				
				using (SpecialNodesInserter.Install(specials, outputVisitor)) {
					outputVisitor.Visit(p.CompilationUnit, null);
				}
				
				p.Dispose();
				
				if (outputVisitor.Errors.count > 0) {
					conversionLog.AppendLine();
					conversionLog.AppendLine(outputVisitor.Errors.count + " error(s) converting " + sourceItem.FileName + ":");
					conversionLog.AppendLine(outputVisitor.Errors.ErrorOutput);
				}
				
				targetItem.Include = Path.ChangeExtension(targetItem.Include, targetExtension);
				File.WriteAllText(targetItem.FileName, outputVisitor.Text);
			} else {
				base.ConvertFile(sourceItem, targetItem);
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -