diff options
Diffstat (limited to 'main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions')
9 files changed, 0 insertions, 1728 deletions
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/Actions/ConvertToEnumAction.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/Actions/ConvertToEnumAction.cs deleted file mode 100644 index 30a5296645..0000000000 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/Actions/ConvertToEnumAction.cs +++ /dev/null @@ -1,503 +0,0 @@ -// -// Author: -// Luís Reis <luiscubal@gmail.com> -// -// Copyright (c) 2013 Luís Reis -// -// 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.Linq; -using ICSharpCode.NRefactory.Semantics; -using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.NRefactory.TypeSystem.Implementation; -using ICSharpCode.NRefactory.PatternMatching; -using MonoDevelop.CodeActions; -using ICSharpCode.NRefactory; -using System.Threading; -using ICSharpCode.NRefactory.CSharp; -using ICSharpCode.NRefactory.CSharp.Refactoring; -using ICSharpCode.Decompiler.ILAst; -using MonoDevelop.Core; - -namespace MonoDevelop.CSharp.Refactoring.CodeActions -{ - /// <summary> - /// Generates an enumeration from const fields - /// </summary> - class ConvertToEnumAction : MonoDevelop.CodeActions.CodeActionProvider - { - public override IEnumerable<MonoDevelop.CodeActions.CodeAction> GetActions(MonoDevelop.Ide.Gui.Document document, object refactoringContext, TextLocation loc, CancellationToken cancellationToken) - { - var context = refactoringContext as MDRefactoringContext; - - if (context == null || context.IsInvalid) - yield break; - - VariableInitializer currentVariable = context.GetNode<VariableInitializer>(); - if (currentVariable == null) { - yield break; - } - - FieldDeclaration currentField = currentVariable.Parent as FieldDeclaration; - if (currentField == null) { - yield break; - } - - if (!currentField.Modifiers.HasFlag(Modifiers.Const)) { - yield break; - } - - PrimitiveType baseType = TypeToIntegerPrimitive(context, currentField.ReturnType); - if (baseType == null) { - //Can't make enums of these types - yield break; - } - - TypeDeclaration containerType = currentVariable.GetParent<TypeDeclaration>(); - - //Get all the fields/variables that the enum can possibly cover - //Don't check the name just yet. That'll come later. - - var constFields = containerType.Members.OfType<FieldDeclaration>() - .Where(field => field.GetParent<TypeDeclaration>() == containerType && field.HasModifier(Modifiers.Const)).ToList(); - - var constVariables = constFields.SelectMany(field => field.Variables).ToList(); - - //Now, it's time to check the name of the selected variable - //We'll use this to search for prefixes later - - var names = constVariables.Select(variable => variable.Name).ToList(); - string currentName = currentVariable.Name; - - //Now, find the common name prefixes - //If the variable is called 'A_B_C_D', then 'A', 'A_B' and 'A_B_C' are - //the potentially available prefixes. - //Note that the common prefixes are the ones that more than one variable - //has. - //Each prefix has an associated action. - - foreach (var prefix in GetCommonPrefixes (currentName, names)) { - string title = string.Format(GettextCatalog.GetString("Create enum '{0}'"), prefix); - - yield return new DefaultCodeAction(title, (ctx, script) => { - PrepareToRunAction (prefix, baseType, containerType, constVariables, cancellationToken, ctx, script); - }); - } - } - - void PrepareToRunAction (string prefix, PrimitiveType baseType, TypeDeclaration containerType, List<VariableInitializer> variables, CancellationToken cancellationToken, RefactoringContext context, Script script) - { - List<string> names = variables.Select(variable => variable.Name).ToList(); - Dictionary<string, string> newNames = names.ToDictionary(originalName => originalName, originalName => { - if (!originalName.StartsWith(prefix)) { - return originalName; - } - int startName = prefix.Length; - while (startName < originalName.Length - 1 && originalName[startName] == '_') { - ++startName; - } - return originalName.Substring(startName); - }); - - string enumName; - using (var dialog = new ConvertToEnumDialog (prefix, variables, variables.Where(variable => variable.Name.StartsWith(prefix, StringComparison.InvariantCulture) - && VariableHasSpecifiedIntegerType(context, variable, baseType)).ToList(), newNames)) - { - if (dialog.Run (/*MonoDevelop.Ide.IdeApp.Workbench.RootWindow*/) != Xwt.Command.Ok) { - return; - } - enumName = dialog.EnumName; - variables = dialog.SelectedVariables; - newNames = dialog.NewNames; - } - - RunAction (context, baseType, enumName, newNames, containerType, variables, script); - - } - - void RunAction(RefactoringContext context, AstType baseType, string enumName, Dictionary<string, string> newNames, TypeDeclaration containerTypeDeclaration, List<VariableInitializer> variables, Script script) - { - var names = variables.Select (variable => variable.Name).ToList (); - var containerType = (context.Resolve(containerTypeDeclaration) as TypeResolveResult).Type; - - var fields = containerTypeDeclaration.Members.OfType<FieldDeclaration>().Where(field => field.Modifiers.HasFlag(Modifiers.Const)).ToList(); - List<VariableInitializer> variableUnitsToRemove = new List<VariableInitializer>(variables); - List<FieldDeclaration> fieldsToRemove = new List<FieldDeclaration>(); - - foreach (var field in fields) { - if (field.Variables.All(variableUnitsToRemove.Contains)) { - fieldsToRemove.Add(field); - - variableUnitsToRemove.RemoveAll(field.Variables.Contains); - } - } - - var generatedEnum = CreateEnumDeclaration(baseType, enumName, variables, names, newNames); - - AstNode root = GetRootNodeOf(containerTypeDeclaration); - var newRoot = root.Clone(); - - FixIdentifiers(context, enumName, variables, containerType, baseType, names, newNames, root, newRoot); - foreach (var member in root.Descendants.OfType<MemberReferenceExpression>().Where (member => names.Contains (member.MemberName))) { - if (variables.Any(variable => variable.Descendants.Contains(member))) { - //Already handled - continue; - } - - var resolvedIdentifier = context.Resolve(member) as MemberResolveResult; - if (resolvedIdentifier == null) { - continue; - } - - if (resolvedIdentifier.Type.Equals(containerType)) { - continue; - } - - var equivalentMember = GetEquivalentNodeFor(root, newRoot, member); - MemberReferenceExpression memberToReplace = (MemberReferenceExpression)equivalentMember; - - var replacement = CreateReplacementMemberReference(enumName, baseType, newNames, memberToReplace); - memberToReplace.ReplaceWith(replacement); - } - - //Fix the file - InsertAfterEquivalent(root, newRoot, containerTypeDeclaration.LBraceToken, generatedEnum, Roles.TypeMemberRole); - - foreach (var variableToRemove in variableUnitsToRemove) { - GetEquivalentNodeFor(root, newRoot, variableToRemove).Remove(); - } - foreach (var fieldToRemove in fieldsToRemove) { - GetEquivalentNodeFor(root, newRoot, fieldToRemove).Remove(); - } - - script.Replace(root, newRoot); - - ReplaceVariableReferences(context, root, baseType, enumName, script, newNames, variables); - } - - static void ReplaceVariableReferences(RefactoringContext context, AstNode root, AstType baseType, string enumName, Script script, Dictionary<string, string> newNames, IEnumerable<VariableInitializer> variables) - { - var resolveResults = variables.Select(variable => (MemberResolveResult)context.Resolve(variable)); - var resolvedFields = resolveResults.Select(resolveResult => resolveResult.Member); - script.DoGlobalOperationOn(resolvedFields, (newCtx, newScript, foundNodes) => { - foreach (var foundNode in foundNodes) { - TypeDeclaration newContainerType = foundNode.GetParent<TypeDeclaration>(); - if (root.Descendants.OfType<TypeDeclaration>().Select(type => ((TypeResolveResult)context.Resolve(type)).Type.FullName).ToList().Contains(((TypeResolveResult)newCtx.Resolve(newContainerType)).Type.FullName)) { - //This file has already been fixed - return; - } - var identifierExpr = foundNode as IdentifierExpression; - if (identifierExpr != null) { - newScript.Replace(identifierExpr, CreateIdentifierReplacement(enumName, baseType, newNames, identifierExpr)); - continue; - } - var memberRef = foundNode as MemberReferenceExpression; - if (memberRef != null) { - var replacement = CreateReplacementMemberReference(enumName, baseType, newNames, memberRef); - newScript.Replace(memberRef, replacement); - } - } - }); - } - - TypeDeclaration CreateEnumDeclaration(AstType baseType, string enumName, List<VariableInitializer> variables, List<string> names, Dictionary<string, string> newNames) - { - TypeDeclaration generatedEnum = new TypeDeclaration(); - generatedEnum.ClassType = ClassType.Enum; - generatedEnum.BaseTypes.Add(baseType.Clone()); - generatedEnum.Name = enumName; - generatedEnum.Modifiers = GetCombinedModifier((Modifiers)variables.Select(variable => ((FieldDeclaration)variable.Parent).Modifiers).Aggregate(0, (prev, newModifier) => prev | (int)newModifier)); - foreach (var variable in variables) { - var generatedMember = new EnumMemberDeclaration(); - generatedMember.Name = newNames[variable.Name]; - var value = variable.Initializer.Clone(); - foreach (var identifier in value.DescendantsAndSelf.OfType<IdentifierExpression>().Where(identifier => names.Contains(identifier.Identifier))) { - var newIdentifier = new IdentifierExpression(newNames[identifier.Identifier]); - if (identifier == value) { - value = newIdentifier; - break; - } - identifier.ReplaceWith(newIdentifier); - } - generatedMember.Initializer = value; - generatedEnum.Members.Add(generatedMember); - } - return generatedEnum; - } - - /// <summary> - /// Determines whether the initialized variable has the specified primitive integer type - /// </summary> - /// <returns><c>true</c> if the initialized variable has the specified type; otherwise, <c>false</c>.</returns> - /// <param name="context">The context to use.</param> - /// <param name="variable">The variable initializer to check.</param> - /// <param name="type">The type to compare with.</param> - bool VariableHasSpecifiedIntegerType(RefactoringContext context, VariableInitializer variable, AstType type) - { - return TypeToIntegerPrimitive(context, variable.GetParent<FieldDeclaration>().ReturnType).Match(type).Success; - } - - static Dictionary<string, PrimitiveType> primitiveTypes = new Dictionary<string, PrimitiveType>(); - - static ConvertToEnumAction() - { - primitiveTypes.Add(typeof(byte).FullName, new PrimitiveType("byte")); - primitiveTypes.Add(typeof(sbyte).FullName, new PrimitiveType("sbyte")); - - primitiveTypes.Add(typeof(short).FullName, new PrimitiveType("short")); - primitiveTypes.Add(typeof(int).FullName, new PrimitiveType("int")); - primitiveTypes.Add(typeof(long).FullName, new PrimitiveType("long")); - - primitiveTypes.Add(typeof(ushort).FullName, new PrimitiveType("ushort")); - primitiveTypes.Add(typeof(uint).FullName, new PrimitiveType("uint")); - primitiveTypes.Add(typeof(ulong).FullName, new PrimitiveType("ulong")); - } - - /// <summary> - /// Gets a PrimitiveType instance from an AstType. - /// Only returns integer types (and never the char type) - /// </summary> - /// <returns>The integer primitive.</returns> - /// <param name="context">The context to use.</param> - /// <param name="type">The AstType to get the primitive from.</param> - PrimitiveType TypeToIntegerPrimitive(RefactoringContext context, AstType type) - { - var resolvedType = context.ResolveType(type) as DefaultResolvedTypeDefinition; - - PrimitiveType primitiveType; - if (!primitiveTypes.TryGetValue(resolvedType.FullName, out primitiveType)) { - return null; - } - - return primitiveType; - } - - static Expression CreateReplacementMemberReference(string enumName, AstType baseType, Dictionary<string, string> newNames, MemberReferenceExpression memberToReplace) - { - return new ParenthesizedExpression(new CastExpression(baseType.Clone(), new MemberReferenceExpression(new MemberReferenceExpression(memberToReplace.Target.Clone(), enumName), newNames [memberToReplace.MemberName]))); - } - - void FixIdentifiers(RefactoringContext context, string enumName, List<VariableInitializer> variables, IType containerType, AstType baseType, List<string> names, Dictionary<string, string> newNames, AstNode root, AstNode newRoot) - { - foreach (var identifier in root.Descendants.OfType<IdentifierExpression> ().Where (identifier => names.Contains (identifier.Identifier))) { - if (variables.Any(variable => variable.Descendants.Contains(identifier))) { - //Already handled - continue; - } - var resolvedIdentifier = context.Resolve(identifier) as MemberResolveResult; - if (resolvedIdentifier == null) { - continue; - } - if (resolvedIdentifier.Type.Equals(containerType)) { - continue; - } - var replacement = CreateIdentifierReplacement(enumName, baseType, newNames, identifier); - GetEquivalentNodeFor(root, newRoot, identifier).ReplaceWith(replacement); - } - } - - static ParenthesizedExpression CreateIdentifierReplacement(string enumName, AstType baseType, Dictionary<string, string> newNames, IdentifierExpression identifier) - { - var replacement = new ParenthesizedExpression(new CastExpression(baseType.Clone(), new MemberReferenceExpression(new IdentifierExpression(enumName), newNames [identifier.Identifier]))); - return replacement; - } - - /// <summary> - /// Finds the corresponding node in another ("new") AST. - /// Assumes entities have not been renamed and no statements have been removed. - /// </summary> - /// <returns>The equivalent node in the new AST.</returns> - /// <param name="root">The root of the first ("old") AST.</param> - /// <param name="newRoot">The root of the new AST.</param> - /// <param name="nodeToFind">Node (from the old AST) to find in the new one.</param> - AstNode GetEquivalentNodeFor(AstNode root, AstNode newRoot, AstNode nodeToFind) - { - if (nodeToFind == null) { - throw new ArgumentNullException("nodeToFind"); - } - - if (nodeToFind.Parent != root) { - AstNode foundRoot = GetEquivalentNodeFor(root, newRoot, nodeToFind.Parent); - if (foundRoot == null) { - //If the equivalent of the parent does not exist in the new AST, - //then neither does this node. - return null; - } - newRoot = foundRoot; - root = nodeToFind.Parent; - } - - //At this point, the roots are the parents of the nodes to check - //root is the parent of the nodeToFind, and newRoot is the parent of the node to return - - var block = root as BlockStatement; - if (block != null && nodeToFind.Role == BlockStatement.StatementRole) { - //This could be a problem if statements were removed in the new AST, - //but fortunately that's not the problem we're trying to solve. - return ((BlockStatement)newRoot).Statements.ElementAt(block.TakeWhile(statement => statement != nodeToFind).Count()); - } - - //First, we'll narrow down the search - the equivalent node *always* has the same type and role as nodeToFind - //The Role check will help e.g. in binary expressions (where there is a 'Left' and a 'Right' role) - var candidates = newRoot.Children.Where(child => child.GetType() == nodeToFind.GetType() && child.Role == nodeToFind.Role); - var entity = nodeToFind as EntityDeclaration; - if (entity != null) { - var field = nodeToFind as FieldDeclaration; - if (field != null) { - //Fields have to be treated separately because fields have no names - candidates = candidates.Where(candidate => IsEquivalentField((FieldDeclaration) candidate, field)); - } - else { - //Some entities can be distinguished by name. - candidates = candidates.Where(candidate => ((EntityDeclaration)candidate).Name == entity.Name); - - var method = nodeToFind as MethodDeclaration; - if (method != null) { - //Methods, however, can be overloaded - so their names aren't enough. - candidates = candidates.Where(candidate => CheckIfMethodsHaveSameParameters((MethodDeclaration) candidate, method)); - } - } - } - - var ns = nodeToFind as NamespaceDeclaration; - if (ns != null) { - candidates = candidates.Where(candidate => ((NamespaceDeclaration)candidate).Name == ns.Name).ToList(); - if (candidates.Count() > 1) { - throw new NotImplementedException("Two or more namespace declarations with the same name are siblings. This case is not currently supported by this action."); - } - } - - var initializer = nodeToFind as VariableInitializer; - if (initializer != null) { - candidates = candidates.Where(candidate => ((VariableInitializer)candidate).Name == initializer.Name); - } - - var equivalentNode = candidates.SingleOrDefault(); - return equivalentNode; - } - - bool IsEquivalentField(FieldDeclaration field1, FieldDeclaration field2) { - return field1.Variables.Any(variable1 => { - return field2.Variables.Any(variable2 => variable1.Name == variable2.Name); - }); - } - - bool CheckIfMethodsHaveSameParameters(MethodDeclaration methodDeclaration, MethodDeclaration comparedMethod) - { - if (methodDeclaration.Parameters.Count != comparedMethod.Parameters.Count) { - return false; - } - - ParameterDeclaration param1 = methodDeclaration.Parameters.FirstOrDefault(); - ParameterDeclaration param2 = comparedMethod.Parameters.FirstOrDefault(); - - while (param1 != null) { - //If the names or initializers are different, this will still match. - //But if the type or order changes, this will complain - if (!param1.Type.Match(param2.Type).Success) { - return false; - } - - param1 = (ParameterDeclaration) param1.GetNextSibling(node => node is ParameterDeclaration); - param2 = (ParameterDeclaration) param2.GetNextSibling(node => node is ParameterDeclaration); - } - - return true; - } - - void InsertAfterEquivalent<T>(AstNode root, AstNode newRoot, AstNode prevNode, T newNode, Role<T> role) - where T : AstNode - { - AstNode equivalentPrevNode = GetEquivalentNodeFor(root, newRoot, prevNode); - equivalentPrevNode.Parent.InsertChildAfter<T>(equivalentPrevNode, newNode, role); - } - - /// <summary> - /// Gets the least permissive access modifier that still allows access to - /// fields or methods with the specified modifiers. - /// This will ignore all modifiers unrelated to access - such as const and readonly - /// </summary> - /// <returns>A modifier that is at least as permissive as all provided modifiers.</returns> - /// <param name="modifiers">The modifiers to use.</param> - Modifiers GetCombinedModifier(Modifiers modifiers) - { - if (modifiers.HasFlag(Modifiers.Public)) - return Modifiers.Public; - - Modifiers combinedModifier = 0; - if (modifiers.HasFlag(Modifiers.Protected)) { - combinedModifier |= Modifiers.Protected; - } - if (modifiers.HasFlag(Modifiers.Internal)) { - combinedModifier |= Modifiers.Internal; - } - - //No modifier if the fields are all private. - return combinedModifier; - } - - /// <summary> - /// Gets all prefixes that more than one name have. - /// </summary> - /// <returns>The common prefixes.</returns> - /// <param name="currentName">The name to use.</param> - /// <param name="names">The names to check.</param> - IEnumerable<string> GetCommonPrefixes(string currentName, IEnumerable<string> names) - { - //Find the indexes that 'split' words in the variable name - var boundariesForCurrentWord = GetWordsBoundaries(currentName); - - //Get the candidate prefixes - List<string> proposedPrefixes = boundariesForCurrentWord.Select(boundary => currentName.Substring(0, boundary)).ToList(); - - //Return only the prefixes that more than one variable has. - return proposedPrefixes.Where(prefix => names.Count(name => name.StartsWith(prefix, StringComparison.InvariantCulture)) > 1); - } - - List<int> GetWordsBoundaries(string name) - { - List<int> foundBoundaries = new List<int>(); - for (int i = 1; i < name.Length - 1; ++i) { - char chr = name [i]; - if (chr == '_') { - foundBoundaries.Add(i); - continue; - } - - if (char.IsUpper(chr) && char.IsLower(name [i - 1])) { - foundBoundaries.Add(i); - continue; - } - } - - return foundBoundaries; - } - - AstNode GetRootNodeOf(AstNode node) - { - while (node.Parent != null) { - node = node.Parent; - } - - return node; - } - } -} - diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/Actions/ConvertToEnumDialog.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/Actions/ConvertToEnumDialog.cs deleted file mode 100644 index 26c3a299a2..0000000000 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/Actions/ConvertToEnumDialog.cs +++ /dev/null @@ -1,122 +0,0 @@ -// -// ConvertToEnumDialog.cs -// -// Author: -// Luís Reis <luiscubal@gmail.com> -// -// Copyright (c) 2013 Luís Reis -// -// 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.Linq; -using MonoDevelop.Core; -using System.Collections.Generic; -using ICSharpCode.NRefactory.CSharp; - -namespace MonoDevelop.CSharp.Refactoring.CodeActions -{ - class ConvertToEnumDialog : Xwt.Dialog - { - Xwt.TextEntry enumNameEntry; - Xwt.ListView variableList; - Xwt.ListStore variableStore; - Xwt.DataField<bool> enabledField; - Xwt.ListViewColumn enabledColumn; - Xwt.DataField<string> oldNameField; - Xwt.ListViewColumn oldNameColumn; - Xwt.DataField<string> newNameField; - Xwt.ListViewColumn newNameColumn; - List<VariableInitializer> variables; - - public ConvertToEnumDialog(string proposedEnumName, List<VariableInitializer> variables, List<VariableInitializer> defaultActiveVariables, Dictionary<string, string> newNames) { - this.variables = variables; - - Title = GettextCatalog.GetString("Convert fields to enumeration"); - - Xwt.VBox vbox = new Xwt.VBox (); - - vbox.PackStart(new Xwt.Label(GettextCatalog.GetString("Name of enum"))); - - enumNameEntry = new Xwt.TextEntry (); - enumNameEntry.Text = proposedEnumName; - vbox.PackStart (enumNameEntry); - - vbox.PackStart (new Xwt.Label (GettextCatalog.GetString ("Variables to include"))); - - variableList = new Xwt.ListView (); - enabledField = new Xwt.DataField<bool> (); - oldNameField = new Xwt.DataField<string> (); - newNameField = new Xwt.DataField<string> (); - - variableStore = new Xwt.ListStore (enabledField, oldNameField, newNameField); - variableList.DataSource = variableStore; - - enabledColumn = new Xwt.ListViewColumn (GettextCatalog.GetString ("Included"), new Xwt.CheckBoxCellView(enabledField) { Editable = true }); - variableList.Columns.Add (enabledColumn); - oldNameColumn = new Xwt.ListViewColumn(GettextCatalog.GetString("Field name"), new Xwt.TextCellView(oldNameField) { Editable = false }); - variableList.Columns.Add (oldNameColumn); - newNameColumn = new Xwt.ListViewColumn(GettextCatalog.GetString("Enum name"), new Xwt.TextCellView(newNameField) { Editable = true, }); - variableList.Columns.Add (newNameColumn); - - for (int i = 0; i < variables.Count; ++i) { - var variable = variables[i]; - - variableStore.AddRow (); - variableStore.SetValue (i, enabledField, defaultActiveVariables.Contains(variable)); - variableStore.SetValue (i, oldNameField, variable.Name); - - variableStore.SetValue (i, newNameField, newNames [variable.Name]); - } - - vbox.PackStart (variableList, true, true); - - vbox.PackStart (new Xwt.Label (GettextCatalog.GetString ("Warning: This may take a while..."))); - - Content = vbox; - - Buttons.Add (new Xwt.DialogButton(Xwt.Command.Ok)); - Buttons.Add (new Xwt.DialogButton(Xwt.Command.Cancel)); - } - - public string EnumName { - get { return enumNameEntry.Text; } - } - - public List<VariableInitializer> SelectedVariables - { - get { - return variables.Where((variable, idx) => variableStore.GetValue<bool>(idx, enabledField)).ToList(); - } - } - - public Dictionary<string, string> NewNames - { - get { - var newNames = new Dictionary<string, string> (); - - for (int i = 0; i < variableStore.RowCount; ++i) { - newNames[variableStore.GetValue<string>(i, oldNameField)] = variableStore.GetValue<string>(i, newNameField); - } - - return newNames; - } - } - } -} - diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/Actions/MoveTypeToFile.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/Actions/MoveTypeToFile.cs deleted file mode 100644 index 31232cb27f..0000000000 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/Actions/MoveTypeToFile.cs +++ /dev/null @@ -1,167 +0,0 @@ -// -// MoveTypeToFile.cs -// -// Author: -// Mike Krüger <mkrueger@novell.com> -// -// Copyright (c) 2011 Novell, Inc (http://www.novell.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 ICSharpCode.NRefactory.CSharp; -using ICSharpCode.NRefactory.PatternMatching; -using MonoDevelop.Core; -using System.Collections.Generic; -using Mono.TextEditor; -using System.Linq; -using MonoDevelop.Refactoring; -using System.IO; -using System.Text; -using MonoDevelop.Ide.StandardHeader; -using MonoDevelop.Core.ProgressMonitoring; -using ICSharpCode.NRefactory; -using System.Threading; -using ICSharpCode.NRefactory.CSharp.Refactoring; - -namespace MonoDevelop.CSharp.Refactoring.CodeActions -{ - class MoveTypeToFile : MonoDevelop.CodeActions.CodeActionProvider - { - public override IEnumerable<MonoDevelop.CodeActions.CodeAction> GetActions (MonoDevelop.Ide.Gui.Document document, object refactoringContext, TextLocation loc, CancellationToken cancellationToken) - { - var context = refactoringContext as MDRefactoringContext; - if (context == null) - return Enumerable.Empty<MonoDevelop.CodeActions.CodeAction> (); - return GetActions (context); - } - protected IEnumerable<MonoDevelop.CodeActions.CodeAction> GetActions (MDRefactoringContext context) - { - if (context.IsInvalid) - yield break; - var type = GetTypeDeclaration (context); - if (type == null) - yield break; - if (Path.GetFileNameWithoutExtension (context.TextEditor.FileName) == type.Name) - yield break; - string title; - if (IsSingleType (context)) { - title = String.Format (GettextCatalog.GetString ("Rename file to '{0}'"), Path.GetFileName (GetCorrectFileName (context, type))); - } else { - title = String.Format (GettextCatalog.GetString ("Move type to file '{0}'"), Path.GetFileName (GetCorrectFileName (context, type))); - } - yield return new MonoDevelop.CodeActions.DefaultCodeAction (title, (c, s) => { - var ctx = (MDRefactoringContext) c; - var script = (Script) s; - string correctFileName = GetCorrectFileName (ctx, type); - if (IsSingleType (ctx)) { - FileService.RenameFile (ctx.TextEditor.FileName, correctFileName); - if (ctx.FileContainerProject != null) - ctx.FileContainerProject.SaveAsync (new ProgressMonitor ()); - return; - } - - CreateNewFile (ctx, type, correctFileName); - script.Remove (type); - }); - } - - static void CreateNewFile (MDRefactoringContext context, TypeDeclaration type, string correctFileName) - { - var content = context.TextEditor.Text; - - var types = new List<EntityDeclaration> (context.Unit.GetTypes ().Where (t => t.StartLocation != type.StartLocation)); - types.Sort ((x, y) => y.StartLocation.CompareTo (x.StartLocation)); - - foreach (var removeType in types) { - var start = context.GetOffset (removeType.StartLocation); - var end = context.GetOffset (removeType.EndLocation); - content = content.Remove (start, end - start); - } - - if (context.FileContainerProject != null) { - string header = StandardHeaderService.GetHeader (context.FileContainerProject, correctFileName, true); - if (!string.IsNullOrEmpty (header)) - content = header + context.TextEditor.EolMarker + StripHeader (content); - } - content = StripDoubleBlankLines (content); - - File.WriteAllText (correctFileName, content); - context.FileContainerProject.AddFile (correctFileName); - MonoDevelop.Ide.IdeApp.ProjectOperations.SaveAsync (context.FileContainerProject); - } - - static bool IsBlankLine (TextDocument doc, int i) - { - var line = doc.GetLine (i); - return line.Length == line.GetIndentation (doc).Length; - } - - static string StripDoubleBlankLines (string content) - { - var doc = new Mono.TextEditor.TextDocument (content); - for (int i = 1; i + 1 <= doc.LineCount; i++) { - if (IsBlankLine (doc, i) && IsBlankLine (doc, i + 1)) { - doc.Remove (doc.GetLine (i).SegmentIncludingDelimiter); - i--; - continue; - } - } - return doc.Text; - } - - static string StripHeader (string content) - { - var doc = new Mono.TextEditor.TextDocument (content); - while (true) { - string lineText = doc.GetLineText (1); - if (lineText == null) - break; - if (lineText.StartsWith ("//")) { - doc.Remove (doc.GetLine (1).SegmentIncludingDelimiter); - continue; - } - break; - } - return doc.Text; - } - - bool IsSingleType (MDRefactoringContext context) - { - return context.Unit.GetTypes ().Count () == 1; - } - - TypeDeclaration GetTypeDeclaration (MDRefactoringContext context) - { - var result = context.GetNode<TypeDeclaration> (); - if (result == null || result.Parent is TypeDeclaration) - return null; - if (result != null && result.NameToken.Contains (context.Location)) - return result; - return null; - } - - internal static string GetCorrectFileName (MDRefactoringContext context, EntityDeclaration type) - { - if (type == null) - return context.TextEditor.FileName; - return Path.Combine (Path.GetDirectoryName (context.TextEditor.FileName), type.Name + Path.GetExtension (context.TextEditor.FileName)); - } - } -} - diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/ContextActionExtensions.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/ContextActionExtensions.cs deleted file mode 100644 index a08ea332e3..0000000000 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/ContextActionExtensions.cs +++ /dev/null @@ -1,69 +0,0 @@ -// -// ContextActionExtensions.cs -// -// Author: -// Mike Krüger <mkrueger@novell.com> -// -// Copyright (c) 2011 Novell, Inc (http://www.novell.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 Mono.TextEditor; -using ICSharpCode.NRefactory.CSharp; -using MonoDevelop.CSharp.Resolver; -using ICSharpCode.NRefactory.CSharp.Resolver; - -namespace MonoDevelop.CSharp.Refactoring.CodeActions -{ - static class ContextActionExtensions - { - public static int CalcIndentLevel (this MonoDevelop.Ide.Gui.Document doc, string indent) - { - int col = GetColumn (indent, 0, doc.Editor.Options.TabSize); - return System.Math.Max (0, col / doc.Editor.Options.TabSize); - } - - public static int GetColumn (string wrapper, int i, int tabSize) - { - int j = i; - int col = 0; - for (; j < wrapper.Length && (wrapper[j] == ' ' || wrapper[j] == '\t'); j++) { - if (wrapper[j] == ' ') { - col++; - } else { - col = GetNextTabstop (col, tabSize); - } - } - return col; - } - - static int GetNextTabstop (int currentColumn, int tabSize) - { - int result = currentColumn + tabSize; - return (result / tabSize) * tabSize; - } - - public static void FormatText (this AstNode node, MonoDevelop.Ide.Gui.Document doc) - { - doc.UpdateParseDocument (); - MonoDevelop.CSharp.Formatting.OnTheFlyFormatter.Format (doc, node.StartLocation); - } - } -} - diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/MDRefactoringContext.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/MDRefactoringContext.cs deleted file mode 100644 index c8c7d60632..0000000000 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/MDRefactoringContext.cs +++ /dev/null @@ -1,271 +0,0 @@ -// -// MDRefactoringContext.cs -// -// Author: -// Mike Krüger <mkrueger@novell.com> -// -// Copyright (c) 2011 Novell, Inc (http://www.novell.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.Linq; -using ICSharpCode.NRefactory.CSharp; -using MonoDevelop.Projects; -using MonoDevelop.Core; -using MonoDevelop.Refactoring; -using ICSharpCode.NRefactory.CSharp.Refactoring; -using MonoDevelop.Ide.TypeSystem; -using ICSharpCode.NRefactory; -using System.Threading; -using MonoDevelop.Ide.Gui; -using System.Diagnostics; -using MonoDevelop.CSharp.Refactoring.CodeIssues; -using Mono.TextEditor; -using ICSharpCode.NRefactory.CSharp.Resolver; -using MonoDevelop.CSharp.Formatting; -using System.Threading.Tasks; - -namespace MonoDevelop.CSharp.Refactoring.CodeActions -{ - public class MDRefactoringContext : RefactoringContext, IRefactoringContext - { - MonoDevelop.Projects.Project fileContainerProject; - - public TextEditorData TextEditor { - get; - private set; - } - - public DotNetProject Project { - get; - private set; - } - - public MonoDevelop.Projects.Project FileContainerProject { - get { - if (fileContainerProject == null) - fileContainerProject = FindProjectContainingFile () ?? Project; - return fileContainerProject; - } - } - - MonoDevelop.Projects.Project FindProjectContainingFile () - { - var file = TextEditor.FileName; - if (string.IsNullOrEmpty (file) || Project == null) - return null; - - var pf = Project.GetProjectFile (file); - if (pf != null && (pf.Flags & ProjectItemFlags.Hidden) != 0) { - // The file is hidden in this project, so it may also be part of another project. - // Try to find a project in which this file is not hidden - foreach (var p in Project.ParentSolution.GetAllProjects ()) { - pf = p.GetProjectFile (file); - if (pf != null && (pf.Flags & ProjectItemFlags.Hidden) == 0) - return p; - } - } - return null; - } - - public bool IsInvalid { - get { - if (Resolver == null || TextEditor == null) - return true; - return ParsedDocument == null; - } - } - - public ParsedDocument ParsedDocument { - get; - private set; - } - - public SyntaxTree Unit { - get { - Debug.Assert (!IsInvalid); - return Resolver.RootNode as SyntaxTree; - } - } - - public override string DefaultNamespace { - get { - var p = FileContainerProject as IDotNetFileContainer; - if (p == null || TextEditor == null || string.IsNullOrEmpty (TextEditor.FileName)) - return null; - return p.GetDefaultNamespace (TextEditor.FileName); - } - } - - public override bool Supports (Version version) - { - var project = Project; - if (project == null) - return true; - switch (project.TargetFramework.ClrVersion) { - case ClrVersion.Net_1_1: - return version.Major > 1 || version.Major == 1 && version.Minor >= 1; - case ClrVersion.Net_2_0: - return version.Major >= 2; - case ClrVersion.Clr_2_1: - return version.Major > 2 || version.Major == 2 && version.Minor >= 1; - default: - return true; - } - } - - public override ICSharpCode.NRefactory.CSharp.TextEditorOptions TextEditorOptions { - get { - return TextEditor.CreateNRefactoryTextEditorOptions (); - } - } - - public override bool IsSomethingSelected { - get { - return TextEditor.IsSomethingSelected; - } - } - - public override string SelectedText { - get { - return TextEditor.SelectedText; - } - } - - public override TextLocation SelectionStart { - get { - return TextEditor.MainSelection.Start; - } - } - - public override TextLocation SelectionEnd { - get { - return TextEditor.MainSelection.End; - } - } - - public override int GetOffset (TextLocation location) - { - return TextEditor.LocationToOffset (location); - } - - public override TextLocation GetLocation (int offset) - { - return TextEditor.OffsetToLocation (offset); - } - - public override string GetText (int offset, int length) - { - return TextEditor.GetTextAt (offset, length); - } - - public override string GetText (ICSharpCode.NRefactory.Editor.ISegment segment) - { - return TextEditor.GetTextAt (segment.Offset, segment.Length); - } - - public override ICSharpCode.NRefactory.Editor.IDocumentLine GetLineByOffset (int offset) - { - return TextEditor.GetLineByOffset (offset); - } - - readonly Document document; - TextLocation location; - - public override TextLocation Location { - get { - return location; - } - } - - internal void SetLocation (TextLocation loc) - { - if (document != null) - location = RefactoringService.GetCorrectResolveLocation (document, loc); - else - location = loc; - } - - readonly CSharpFormattingOptions formattingOptions; - - public CSharpFormattingOptions FormattingOptions { - get { - return formattingOptions; - } - } - - public Script StartScript () - { - return new MDRefactoringScript (this, formattingOptions); - } - - public IDisposable CreateScript () - { - return StartScript (); - } - - internal static Task<MDRefactoringContext> Create (Document document, TextLocation loc, CancellationToken cancellationToken = default (CancellationToken)) - { - var shared = document.GetSharedResolver (); - if (shared == null) { - var tcs = new TaskCompletionSource<MDRefactoringContext> (); - tcs.SetResult (null); - return tcs.Task; - } - - return shared.ContinueWith (t => { - var sharedResolver = t.Result; - if (sharedResolver == null) - return null; - return new MDRefactoringContext (document, sharedResolver, loc, cancellationToken); - // Do not add TaskContinuationOptions.ExecuteSynchronously - // https://bugzilla.xamarin.com/show_bug.cgi?id=25065 - // adding ExecuteSynchronously appears to create a deadlock situtation in TypeSystemParser.Parse() - }); - } - - internal MDRefactoringContext (Document document, CSharpAstResolver resolver, TextLocation loc, CancellationToken cancellationToken = default (CancellationToken)) : base (resolver, cancellationToken) - { - if (document == null) - throw new ArgumentNullException ("document"); - this.document = document; - this.TextEditor = document.Editor; - this.ParsedDocument = document.ParsedDocument; - this.Project = document.Project as DotNetProject; - this.formattingOptions = document.GetFormattingOptions (); - this.location = loc; - var policy = document.HasProject ? document.Project.Policies.Get<NameConventionPolicy> () : MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<NameConventionPolicy> (); - Services.AddService (typeof(NamingConventionService), policy.CreateNRefactoryService ()); - Services.AddService (typeof(ICSharpCode.NRefactory.CSharp.CodeGenerationService), new CSharpCodeGenerationService()); - } - - public MDRefactoringContext (DotNetProject project, TextEditorData data, ParsedDocument parsedDocument, CSharpAstResolver resolver, TextLocation loc, CancellationToken cancellationToken = default (CancellationToken)) : base (resolver, cancellationToken) - { - this.TextEditor = data; - this.ParsedDocument = parsedDocument; - this.Project = project; - var policy = Project.Policies.Get<CSharpFormattingPolicy> (); - this.formattingOptions = policy.CreateOptions (); - this.location = loc; - var namingPolicy = Project.Policies.Get<NameConventionPolicy> (); - Services.AddService (typeof(NamingConventionService), namingPolicy.CreateNRefactoryService ()); - } - } -} diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/MDRefactoringScript.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/MDRefactoringScript.cs deleted file mode 100644 index 02e35f0e04..0000000000 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/MDRefactoringScript.cs +++ /dev/null @@ -1,377 +0,0 @@ -// -// MDRefactoringScript.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.Linq; -using ICSharpCode.NRefactory.CSharp.Refactoring; -using MonoDevelop.Ide.Gui; -using ICSharpCode.NRefactory.CSharp; -using Mono.TextEditor; -using MonoDevelop.Ide.TypeSystem; -using MonoDevelop.Core; -using System.Collections.Generic; -using ICSharpCode.NRefactory.TypeSystem; -using MonoDevelop.Refactoring.Rename; -using ICSharpCode.NRefactory.CSharp.Resolver; -using System.IO; -using MonoDevelop.CSharp.Formatting; -using MonoDevelop.Ide; -using System.Threading.Tasks; -using MonoDevelop.Ide.FindInFiles; -using MonoDevelop.Projects; -using ICSharpCode.NRefactory.CSharp.TypeSystem; -using MonoDevelop.Ide.Gui.Content; - -namespace MonoDevelop.CSharp.Refactoring.CodeActions -{ - class MDRefactoringScript : DocumentScript - { - readonly MDRefactoringContext context; - readonly IDisposable undoGroup; - readonly ICSharpCode.NRefactory.Editor.ITextSourceVersion startVersion; - int operationsRunning; - - public MDRefactoringScript (MDRefactoringContext context, CSharpFormattingOptions formattingOptions) : base(context.TextEditor.Document, formattingOptions, context.TextEditor.CreateNRefactoryTextEditorOptions ()) - { - this.context = context; - undoGroup = this.context.TextEditor.OpenUndoGroup (); - this.startVersion = this.context.TextEditor.Version; - - } - - void Rollback () - { - DisposeOnClose (true); - foreach (var ver in context.TextEditor.Version.GetChangesTo (startVersion)) { - context.TextEditor.Document.Replace (ver.Offset, ver.RemovalLength, ver.InsertedText.Text); - } - } - - public override void Select (AstNode node) - { - var seg = GetSegment (node); - var startOffset = seg.Offset; - var endOffset = seg.EndOffset; - while (startOffset < endOffset) { - char ch = context.TextEditor.GetCharAt (startOffset); - if (!char.IsWhiteSpace (ch)) - break; - startOffset++; - } - while (startOffset < endOffset && endOffset > 0) { - char ch = context.TextEditor.GetCharAt (endOffset - 1); - if (!char.IsWhiteSpace (ch)) - break; - endOffset--; - } - - context.TextEditor.Caret.Offset = endOffset; - context.TextEditor.SelectionRange = new TextSegment (startOffset, endOffset - startOffset); - } - - public override Task<Script> InsertWithCursor (string operation, InsertPosition defaultPosition, IList<AstNode> nodes) - { - var tcs = new TaskCompletionSource<Script> (); - var editor = context.TextEditor; - DocumentLocation loc = context.TextEditor.Caret.Location; - var declaringType = context.ParsedDocument.GetInnermostTypeDefinition (loc); - var mode = new InsertionCursorEditMode ( - editor.Parent, - MonoDevelop.Ide.TypeSystem.CodeGenerationService.GetInsertionPoints (context.TextEditor, context.ParsedDocument, declaringType)); - if (mode.InsertionPoints.Count == 0) { - MessageService.ShowError ( - GettextCatalog.GetString ("No valid insertion point can be found in type '{0}'.", declaringType.Name) - ); - return tcs.Task; - } - var helpWindow = new Mono.TextEditor.PopupWindow.InsertionCursorLayoutModeHelpWindow (); - helpWindow.TitleText = operation; - mode.HelpWindow = helpWindow; - - switch (defaultPosition) { - case InsertPosition.Start: - mode.CurIndex = 0; - break; - case InsertPosition.End: - mode.CurIndex = mode.InsertionPoints.Count - 1; - break; - case InsertPosition.Before: - for (int i = 0; i < mode.InsertionPoints.Count; i++) { - if (mode.InsertionPoints [i].Location < loc) - mode.CurIndex = i; - } - break; - case InsertPosition.After: - for (int i = 0; i < mode.InsertionPoints.Count; i++) { - if (mode.InsertionPoints [i].Location > loc) { - mode.CurIndex = i; - break; - } - } - break; - } - operationsRunning++; - mode.StartMode (); - mode.Exited += delegate(object s, InsertionCursorEventArgs iCArgs) { - if (iCArgs.Success) { - if (iCArgs.InsertionPoint.LineAfter == NewLineInsertion.None && - iCArgs.InsertionPoint.LineBefore == NewLineInsertion.None && nodes.Count () > 1) { - iCArgs.InsertionPoint.LineAfter = NewLineInsertion.BlankLine; - } - foreach (var node in nodes.Reverse ()) { - var output = OutputNode (MonoDevelop.Ide.TypeSystem.CodeGenerationService.CalculateBodyIndentLevel (declaringType), node); - var offset = context.TextEditor.LocationToOffset (iCArgs.InsertionPoint.Location); - var delta = iCArgs.InsertionPoint.Insert (editor, output.Text); - output.RegisterTrackedSegments (this, delta + offset); - } - tcs.SetResult (this); - } else { - Rollback (); - } - DisposeOnClose (); - }; - return tcs.Task; - } - - readonly List<Script> startedScripts = new List<Script> (); - - public override Task<Script> InsertWithCursor (string operation, ITypeDefinition parentType, Func<Script, RefactoringContext, IList<AstNode>> nodeCallback) - { - var tcs = new TaskCompletionSource<Script>(); - if (parentType == null) - return tcs.Task; - var part = parentType.Parts.FirstOrDefault (); - if (part == null) - return tcs.Task; - - var loadedDocument = IdeApp.Workbench.OpenDocument (new FileOpenInformation (part.Region.FileName, null)); - loadedDocument.RunWhenLoaded (delegate { - var editor = loadedDocument.Editor; - var loc = part.Region.Begin; - var parsedDocument = loadedDocument.UpdateParseDocument (); - var declaringType = parsedDocument.GetInnermostTypeDefinition (loc); - MDRefactoringScript script; - - if (loadedDocument.Editor != context.TextEditor) { - script = new MDRefactoringScript (MDRefactoringContext.Create (loadedDocument, loc, context.CancellationToken).Result, FormattingOptions); - startedScripts.Add (script); - } else { - script = this; - } - var nodes = nodeCallback (script, script.context); - var mode = new InsertionCursorEditMode ( - editor.Parent, - MonoDevelop.Ide.TypeSystem.CodeGenerationService.GetInsertionPoints (loadedDocument, declaringType)); - if (mode.InsertionPoints.Count == 0) { - MessageService.ShowError ( - GettextCatalog.GetString ("No valid insertion point can be found in type '{0}'.", declaringType.Name) - ); - return; - } - if (declaringType.Kind == TypeKind.Enum) { - foreach (var node in nodes.Reverse ()) { - var output = OutputNode (MonoDevelop.Ide.TypeSystem.CodeGenerationService.CalculateBodyIndentLevel (declaringType), node); - var point = mode.InsertionPoints.First (); - var offset = loadedDocument.Editor.LocationToOffset (point.Location); - var text = output.Text + ","; - var delta = point.Insert (editor, text); - output.RegisterTrackedSegments (script, delta + offset); - } - tcs.SetResult (script); - return; - } - - var helpWindow = new Mono.TextEditor.PopupWindow.InsertionCursorLayoutModeHelpWindow (); - helpWindow.TitleText = operation; - mode.HelpWindow = helpWindow; - - mode.CurIndex = 0; - operationsRunning++; - mode.StartMode (); - mode.Exited += delegate(object s, InsertionCursorEventArgs iCArgs) { - if (iCArgs.Success) { - if (iCArgs.InsertionPoint.LineAfter == NewLineInsertion.None && - iCArgs.InsertionPoint.LineBefore == NewLineInsertion.None && nodes.Count > 1) { - iCArgs.InsertionPoint.LineAfter = NewLineInsertion.BlankLine; - } - foreach (var node in nodes.Reverse ()) { - var output = OutputNode (MonoDevelop.Ide.TypeSystem.CodeGenerationService.CalculateBodyIndentLevel (declaringType), node); - var offset = loadedDocument.Editor.LocationToOffset (iCArgs.InsertionPoint.Location); - var text = output.Text; - var delta = iCArgs.InsertionPoint.Insert (editor, text); - output.RegisterTrackedSegments (script, delta + offset); - } - tcs.SetResult (script); - } else { - Rollback (); - } - DisposeOnClose (); - }; - }); - - return tcs.Task; - } - - public override Task Link (params AstNode[] nodes) - { - var tcs = new TaskCompletionSource<object> (); - var segments = new List<TextSegment> (nodes.Select (node => new TextSegment (GetSegment (node))).OrderBy (s => s.Offset)); - - var link = new TextLink ("name"); - segments.ForEach (link.AddLink); - var links = new List<TextLink> (); - links.Add (link); - var tle = new TextLinkEditMode (context.TextEditor.Parent, 0, links); - tle.SetCaretPosition = false; - if (tle.ShouldStartTextLinkMode) { - operationsRunning++; - context.TextEditor.Caret.Offset = segments [0].EndOffset; - tle.OldMode = context.TextEditor.CurrentMode; - tle.Cancel += (sender, e) => Rollback (); - tle.Exited += (sender, e) => DisposeOnClose (); - tle.StartMode (); - context.TextEditor.CurrentMode = tle; - if (IdeApp.Workbench.ActiveDocument != null) - IdeApp.Workbench.ActiveDocument.ReparseDocument (); - } - return tcs.Task; - } - - bool isDisposed; - void DisposeOnClose (bool force = false) - { - if (isDisposed) - return; - if (force) - operationsRunning = 0; - if (operationsRunning-- == 0) { - isDisposed = true; - undoGroup.Dispose (); - try { - base.Dispose (); - } catch (Exception e) { - LoggingService.LogError ("Error while disposing refactoring script", e); - } - } - foreach (var script in startedScripts) - script.Dispose (); - } - - public override void Dispose () - { - DisposeOnClose (); - } - - public override void Rename (ISymbol symbol, string name = null) - { - if (symbol is IEntity) { - RenameRefactoring.Rename ((IEntity)symbol, name); - } else if (symbol is IVariable) { - RenameRefactoring.RenameVariable ((IVariable)symbol, name); - } else if (symbol is INamespace) { - RenameRefactoring.RenameNamespace ((INamespace)symbol, name); - } else if (symbol is ITypeParameter) { - RenameRefactoring.RenameTypeParameter ((ITypeParameter)symbol, name); - } - } - - public override void DoGlobalOperationOn (IEnumerable<IEntity> entities, Action<RefactoringContext, Script, IEnumerable<AstNode>> callback, string operationName = null) - { - using (var monitor = IdeApp.Workbench.ProgressMonitors.GetBackgroundProgressMonitor (operationName ?? GettextCatalog.GetString ("Performing refactoring task..."), null)) { - var col = entities.SelectMany (entity => ReferenceFinder.FindReferences (entity, true, monitor)).OfType<CSharpReferenceFinder.CSharpMemberReference> ().GroupBy(reference => reference.FileName); - - foreach (var r in col) { - string filename = r.Key; - - bool isOpen; - System.Text.Encoding encoding; - bool hadBom; - - var data = TextFileProvider.Instance.GetTextEditorData (filename, out hadBom, out encoding, out isOpen); - - var firstReference = r.First (); - - var project = firstReference.Project; - - ParsedDocument parsedDocument; - using (var reader = new StreamReader (data.OpenStream ())) - parsedDocument = new MonoDevelop.CSharp.Parser.TypeSystemParser ().Parse (true, filename, reader, project); - - var resolver = new CSharpAstResolver (TypeSystemService.GetCompilation (project), firstReference.SyntaxTree, parsedDocument.ParsedFile as CSharpUnresolvedFile); - - var ctx = new MDRefactoringContext (project as DotNetProject, data, parsedDocument, resolver, firstReference.AstNode.StartLocation, context.CancellationToken); - var script = new MDRefactoringScript (ctx, FormattingOptions); - - callback (ctx, script, r.Select (reference => reference.AstNode)); - - if (!isOpen) { - script.Dispose (); - Mono.TextEditor.Utils.TextFileUtility.WriteText (filename, data.Text, encoding, hadBom); - } - } - } - } - - public override void CreateNewType (AstNode newType, NewTypeContext ntctx = NewTypeContext.CurrentNamespace) - { - if (newType == null) - throw new ArgumentNullException ("newType"); - var correctFileName = MoveTypeToFile.GetCorrectFileName (context, (EntityDeclaration)newType); - - var content = context.TextEditor.Text; - - var types = new List<EntityDeclaration> (context.Unit.GetTypes ()); - types.Sort ((x, y) => y.StartLocation.CompareTo (x.StartLocation)); - - foreach (var removeType in types) { - var start = context.GetOffset (removeType.StartLocation); - var end = context.GetOffset (removeType.EndLocation); - content = content.Remove (start, end - start); - } - - var insertLocation = types.Count > 0 ? context.GetOffset (types.Last ().StartLocation) : -1; - if (insertLocation < 0 || insertLocation > content.Length) - insertLocation = content.Length; - content = content.Substring (0, insertLocation) + newType.ToString (FormattingOptions) + content.Substring (insertLocation); - - var project = context.FileContainerProject; - if (project != null) { - var policy = project.Policies.Get<CSharpFormattingPolicy> (); - var textPolicy = project.Policies.Get<TextStylePolicy> (); - content = MonoDevelop.CSharp.Formatting.CSharpFormatter.FormatText (policy, textPolicy, MonoDevelop.CSharp.Formatting.CSharpFormatter.MimeType, content, 0, content.Length); - } - - File.WriteAllText (correctFileName, content); - - if (project != null) { - project.AddFile (correctFileName); - IdeApp.ProjectOperations.SaveAsync (project); - } - IdeApp.Workbench.OpenDocument (correctFileName, project); - } - - } -} - diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/NRefactoryCodeAction.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/NRefactoryCodeAction.cs deleted file mode 100644 index adec92c9d5..0000000000 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/NRefactoryCodeAction.cs +++ /dev/null @@ -1,82 +0,0 @@ -// -// NRefactoryCodeAction.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.Collections.Generic; -using ICSharpCode.NRefactory.CSharp.Refactoring; -using MonoDevelop.Ide.Gui; -using ICSharpCode.NRefactory; -using MonoDevelop.Ide.TypeSystem; - -namespace MonoDevelop.CSharp.Refactoring.CodeActions -{ - class NRefactoryCodeAction : MonoDevelop.CodeActions.CodeAction - { - readonly CodeAction act; - - public NRefactoryCodeAction (string id, string title, CodeAction act, object siblingKey = null) - { - this.IdString = id; - this.Title = title; - this.act = act; - this.SiblingKey = siblingKey; - this.Severity = act.Severity; - this.DocumentRegion = new Mono.TextEditor.DocumentRegion (act.Start, act.End); - } - - public override void Run (IRefactoringContext context, object script) - { - act.Run ((Script) script); - } - - /// <summary> - /// All the sibling actions of this action, ie those actions which represent the same kind - /// of fix. This list includes the current action. - /// </summary> - /// <value>The sibling actions.</value> - public IList<MonoDevelop.CodeActions.CodeAction> SiblingActions { get; set; } - - public override bool SupportsBatchRunning { - get{ - return SiblingActions != null;// && SiblingActions.Count > 1; - } - } - - public override void BatchRun (Document document, TextLocation loc) - { - base.BatchRun (document, loc); - var context = MDRefactoringContext.Create (document, loc).Result; - if (context == null) - return; - using (var script = context.StartScript ()) { - foreach (var action in SiblingActions) { - context.SetLocation (action.DocumentRegion.Begin); - action.Run (context, script); - } - } - } - } - -} diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/NRefactoryCodeActionProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/NRefactoryCodeActionProvider.cs deleted file mode 100644 index ec7ec5754e..0000000000 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/NRefactoryCodeActionProvider.cs +++ /dev/null @@ -1,86 +0,0 @@ -// -// NRefactoryContextActionWrapper.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 ICSharpCode.NRefactory.CSharp; -using ICSharpCode.NRefactory.CSharp.Refactoring; -using MonoDevelop.Ide.Gui; -using ICSharpCode.NRefactory; -using System.Threading; -using MonoDevelop.Core; - -namespace MonoDevelop.CSharp.Refactoring.CodeActions -{ - class NRefactoryCodeActionProvider : MonoDevelop.CodeActions.CodeActionProvider - { - readonly List<string> actionId = new List<string> (); - readonly CodeActionProvider provider; - - public NRefactoryCodeActionProvider (CodeActionProvider provider, ContextActionAttribute attr) - { - if (provider == null) - throw new ArgumentNullException ("provider"); - if (attr == null) - throw new ArgumentNullException ("attr"); - this.provider = provider; - Title = GettextCatalog.GetString (attr.Title ?? ""); - Description = GettextCatalog.GetString (attr.Description ?? ""); - Category = GettextCatalog.GetString (attr.Category ?? ""); - MimeType = "text/x-csharp"; - } - - public override IEnumerable<MonoDevelop.CodeActions.CodeAction> GetActions (Document document, object _context, TextLocation loc, CancellationToken cancellationToken) - { - if (cancellationToken.IsCancellationRequested) - yield break; - var context = _context as MDRefactoringContext; - if (context == null || context.IsInvalid || context.RootNode == null) - yield break; - var actions = provider.GetActions (context); - if (actions == null) { - LoggingService.LogWarning (provider + " returned null actions."); - yield break; - } - int num = 0; - foreach (var action_ in actions) { - var action = action_; - if (actionId.Count <= num) { - actionId.Add (provider.GetType ().FullName + "'" + num); - } - yield return new NRefactoryCodeAction (actionId[num], GettextCatalog.GetString (action.Description ?? ""), action); - num++; - } - } - - public override string IdString { - get { - return provider.GetType ().FullName; - } - } - - } -} diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/NRefactoryCodeActionSource.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/NRefactoryCodeActionSource.cs deleted file mode 100644 index ba431c6e0f..0000000000 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeActions/NRefactoryCodeActionSource.cs +++ /dev/null @@ -1,51 +0,0 @@ -// -// NRefactoryCodeActionSource.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 MonoDevelop.CodeActions; -using System.Collections.Generic; - -namespace MonoDevelop.CSharp.Refactoring.CodeActions -{ - class NRefactoryCodeActionSource : ICodeActionProviderSource - { - #region ICodeActionProviderSource implementation - public IEnumerable<CodeActionProvider> GetProviders () - { - foreach (var t in typeof (ICSharpCode.NRefactory.CSharp.Refactoring.AbstractAndVirtualConversionAction).Assembly.GetTypes ()) { - var attr = t.GetCustomAttributes (typeof(ICSharpCode.NRefactory.CSharp.ContextActionAttribute), false); - if (attr == null || attr.Length != 1) - continue; - if (t.Name == "AddUsingAction") - continue; - yield return new NRefactoryCodeActionProvider ( - (ICSharpCode.NRefactory.CSharp.Refactoring.CodeActionProvider)Activator.CreateInstance (t), - (ICSharpCode.NRefactory.CSharp.ContextActionAttribute)attr [0]); - } - } - #endregion - } -} - |