예제 #1
0
		public void Run (RefactoringContext context)
		{
			var expr = GetEmptyString (context);
			using (var script = context.StartScript ()) {
				script.Replace (expr, new MemberReferenceExpression (new TypeReferenceExpression (new PrimitiveType ("string")), "Empty"));
			}
		}
예제 #2
0
		public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var property = context.GetNode<PropertyDeclaration>();
			if (property == null || !property.NameToken.Contains(context.Location))
				yield break;

			var field = RemoveBackingStoreAction.GetBackingField(context);
			if (field == null)
				yield break;
			var resolvedType = ReflectionHelper.ParseReflectionName ("System.EventHandler").Resolve (context.Compilation);
			if (resolvedType == null)
				yield break;
			var type = (TypeDeclaration)property.Parent;

			yield return new CodeAction(context.TranslateString("Create changed event"), script => {
				var eventDeclaration = CreateChangedEventDeclaration (context, property);
				var methodDeclaration = CreateEventInvocatorAction.CreateEventInvocator (context, type, eventDeclaration, eventDeclaration.Variables.First (), resolvedType.GetDelegateInvokeMethod (), false);
				var stmt = new ExpressionStatement (new InvocationExpression (
					new IdentifierExpression (methodDeclaration.Name),
					new MemberReferenceExpression (context.CreateShortType("System", "EventArgs"), "Empty")
				));
				script.InsertWithCursor(
					context.TranslateString("Create event invocator"),
					Script.InsertPosition.After,
					new AstNode[] { eventDeclaration, methodDeclaration }
				).ContinueScript(delegate {
					script.InsertBefore (property.Setter.Body.RBraceToken, stmt);
					script.FormatText (stmt);
				});
			}, property.NameToken);
		}
예제 #3
0
		public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			if (!context.IsSomethingSelected)
				yield break;
			var selected = new List<AstNode>(context.GetSelectedNodes());
			if (selected.Count == 0)
				yield break;
			
			if (selected.Count == 1 && selected [0] is Expression) {
				var codeAction = CreateFromExpression(context, (Expression)selected [0]);
				if (codeAction == null)
					yield break;
				yield return codeAction;
			}

			foreach (var node in selected) {
				if (!(node is Statement) && !(node is Comment) && !(node is NewLineNode) && !(node is PreProcessorDirective))
					yield break;
				if (node.DescendantNodesAndSelf().Any(n => n is YieldBreakStatement || n is YieldReturnStatement))
					yield break;
			}
			var action = CreateFromStatements (context, new List<AstNode> (selected));
			if (action != null)
				yield return action;
		}
		public IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var initializer = GetVariableInitializer(context);
			if (initializer == null || !initializer.NameToken.Contains(context.Location.Line, context.Location.Column)) {
				yield break;
			}
			var type = initializer.Parent.Parent as TypeDeclaration;
			if (type == null) {
				yield break;
			}
			foreach (var member in type.Members) {
				if (member is PropertyDeclaration && ContainsGetter((PropertyDeclaration)member, initializer)) {
					yield break;
				}
			}
			var field = initializer.Parent as FieldDeclaration;
			if (field == null) {
				yield break;
			}
			
			yield return new CodeAction(context.TranslateString("Create getter"), script => {
				script.InsertWithCursor(
					context.TranslateString("Create getter"),
					Script.InsertPosition.After,
					GeneratePropertyDeclaration(context, field, initializer));
			});
		}
예제 #5
0
		static SwitchStatement GetSwitchStatement (RefactoringContext context)
		{
			var switchStatment = context.GetNode<SwitchStatement> ();
			if (switchStatment != null && switchStatment.SwitchSections.Count == 0)
				return switchStatment;
			return null;
		}
예제 #6
0
		static ForeachStatement GetForeachStatement (RefactoringContext context)
		{
			var result = context.GetNode<ForeachStatement> ();
			if (result != null && result.VariableType.Contains (context.Location) && !result.VariableType.IsVar ())
				return result;
			return null;
		}
		public IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var type = context.GetNode<AstType>();
			if (type == null || type.Role != Roles.BaseType)
				yield break;
			var state = context.GetResolverStateBefore(type);
			if (state.CurrentTypeDefinition == null)
				yield break;

			var resolveResult = context.Resolve(type);
			if (resolveResult.Type.Kind != TypeKind.Interface)
				yield break;

			var toImplement = ImplementInterfaceAction.CollectMembersToImplement(
				state.CurrentTypeDefinition,
				resolveResult.Type,
				false
			);
			if (toImplement.Count == 0)
				yield break;

			yield return new CodeAction(context.TranslateString("Implement interface explicit"), script => {
				script.InsertWithCursor(
					context.TranslateString("Implement Interface"),
					state.CurrentTypeDefinition,
					ImplementInterfaceAction.GenerateImplementation (context, toImplement.Select (t => Tuple.Create (t.Item1, true)))
				);
			});
		}
예제 #8
0
		public IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var initializer = context.GetNode<VariableInitializer>();
			if (initializer == null || !initializer.NameToken.Contains(context.Location.Line, context.Location.Column)) {
				yield break;
			}
			var type = initializer.Parent.Parent as TypeDeclaration;
			if (type == null) {
				yield break;
			}
			foreach (var member in type.Members) {
				if (member is PropertyDeclaration && ContainsGetter((PropertyDeclaration)member, initializer)) {
					yield break;
				}
			}
			var field = initializer.Parent as FieldDeclaration;
			if (field == null || field.HasModifier(Modifiers.Readonly) || field.HasModifier(Modifiers.Const)) {
				yield break;
			}
			var resolveResult = context.Resolve(initializer) as MemberResolveResult;
			if (resolveResult == null)
				yield break;
			yield return new CodeAction(context.TranslateString("Create property"), script => {
				var fieldName = context.GetNameProposal(initializer.Name, true);
				if (initializer.Name == context.GetNameProposal(initializer.Name, false)) {
					script.Rename(resolveResult.Member, fieldName);
				}
				script.InsertWithCursor(
					context.TranslateString("Create property"),
					Script.InsertPosition.After, GeneratePropertyDeclaration(context, field, fieldName));
			});
		}
        public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
        {
            var node = context.GetNode<InvocationExpression>();
            if (node == null)
                yield break;
            if ((node.Target is IdentifierExpression) && !node.Target.IsInside(context.Location))
                yield break;
            if ((node.Target is MemberReferenceExpression) && !((MemberReferenceExpression)node.Target).MemberNameToken.IsInside(context.Location))
                yield break;
            var rr = context.Resolve(node) as CSharpInvocationResolveResult;
            if (rr == null || rr.IsError || rr.Member.Name != "Equals" || !rr.Member.DeclaringType.IsKnownType(KnownTypeCode.Object))
                yield break;
            Expression expr = node;
            bool useEquality = true;
            var uOp = node.Parent as UnaryOperatorExpression;
            if (uOp != null && uOp.Operator == UnaryOperatorType.Not) {
                expr = uOp;
                useEquality = false;
            }

            yield return new CodeAction(
                useEquality ? context.TranslateString("Use '=='") : context.TranslateString("Use '!='"),
                script => {
                    script.Replace(
                        expr,
                        new BinaryOperatorExpression(
                            node.Arguments.First().Clone(),
                            useEquality ? BinaryOperatorType.Equality :  BinaryOperatorType.InEquality,
                            node.Arguments.Last().Clone()
                        )
                    );
                },
                node.Target
            );
        }
예제 #10
0
		static AstNode GenerateFieldDeclaration (RefactoringContext context, IdentifierExpression identifier)
		{
			return new FieldDeclaration () {
				ReturnType = GuessType (context, identifier),
				Variables = { new VariableInitializer (identifier.Identifier) }
			};
		}
		CodeAction CreateFromExpression(RefactoringContext context, Expression expression)
		{
			var resolveResult = context.Resolve(expression);
			if (resolveResult.IsError)
				return null;
			
			return new CodeAction(context.TranslateString("Extract method"), script => {
				string methodName = "NewMethod";
				var method = new MethodDeclaration() {
					ReturnType = context.CreateShortType(resolveResult.Type),
					Name = methodName,
					Body = new BlockStatement() {
						new ReturnStatement(expression.Clone())
					}
				};
				if (!StaticVisitor.UsesNotStaticMember(context, expression))
					method.Modifiers |= Modifiers.Static;
				var task = script.InsertWithCursor(context.TranslateString("Extract method"), Script.InsertPosition.Before, method);

				Action<Task> replaceStatements = delegate {
					var target = new IdentifierExpression(methodName);
					script.Replace(expression, new InvocationExpression(target));
					script.Link(target, method.NameToken);
				};

				if (task.IsCompleted) {
					replaceStatements (null);
				} else {
					task.ContinueWith (replaceStatements, TaskScheduler.FromCurrentSynchronizationContext ());
				}
			});
		}
        public IEnumerable<CodeAction> GetActions(RefactoringContext context)
        {
            IType type;
            var anonymousMethodExpression = GetAnonymousMethodExpression(context, out type);
            if (anonymousMethodExpression == null) {
                yield break;
            }
            yield return new CodeAction (context.TranslateString("Insert anonymous method signature"), script => {
                var delegateMethod = type.GetDelegateInvokeMethod();

                var sb = new StringBuilder ("(");
                for (int k = 0; k < delegateMethod.Parameters.Count; k++) {
                    if (k > 0) {
                        sb.Append(", ");
                    }

                    var paramType = delegateMethod.Parameters [k].Type;

                    sb.Append(context.CreateShortType(paramType));
                    sb.Append(" ");
                    sb.Append(delegateMethod.Parameters [k].Name);
                }
                sb.Append(")");

                script.InsertText(context.GetOffset(anonymousMethodExpression.DelegateToken.EndLocation), sb.ToString());
            }, anonymousMethodExpression);
        }
예제 #13
0
        IEnumerable<CodeAction> GetActionsForAddNamespaceUsing(RefactoringContext context, AstNode node)
        {
            var nrr = context.Resolve(node) as NamespaceResolveResult;
            if (nrr == null)
                return EmptyList<CodeAction>.Instance;

            var trr = context.Resolve(node.Parent) as TypeResolveResult;
            if (trr == null)
                return EmptyList<CodeAction>.Instance;
            ITypeDefinition typeDef = trr.Type.GetDefinition();
            if (typeDef == null)
                return EmptyList<CodeAction>.Instance;

            IList<IType> typeArguments;
            ParameterizedType parameterizedType = trr.Type as ParameterizedType;
            if (parameterizedType != null)
                typeArguments = parameterizedType.TypeArguments;
            else
                typeArguments = EmptyList<IType>.Instance;

            var resolver = context.GetResolverStateBefore(node.Parent);
            if (resolver.ResolveSimpleName(typeDef.Name, typeArguments) is UnknownIdentifierResolveResult) {
                // It's possible to remove the explicit namespace usage and introduce a using instead
                return new[] { NewUsingAction(context, node, typeDef.Namespace) };
            }
            return EmptyList<CodeAction>.Instance;
        }
        public IEnumerable<CodeAction> GetActions(RefactoringContext context)
        {
            if (context.IsSomethingSelected) {
                yield break;
            }
            AstType type;
            var varDecl = GetVariableDeclarationStatement(context, out type);
            if (varDecl == null) {
                yield break;
            }
            yield return new CodeAction(context.TranslateString("Split local variable declaration and assignment"), script => {
                var assign = new AssignmentExpression (new IdentifierExpression (varDecl.Variables.First().Name), AssignmentOperatorType.Assign, varDecl.Variables.First().Initializer.Clone());

                var newVarDecl = (VariableDeclarationStatement)varDecl.Clone();
                newVarDecl.Role = BlockStatement.StatementRole;

                if (newVarDecl.Type.IsMatch(new SimpleType ("var"))) {
                    newVarDecl.Type = type;
                }

                newVarDecl.Variables.First().Initializer = Expression.Null;

                script.InsertBefore(varDecl, newVarDecl);
                script.Replace(varDecl, varDecl.Parent is ForStatement ? (AstNode)assign : new ExpressionStatement (assign));
            }, varDecl.Variables.First ().AssignToken);
        }
		public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			if (context.IsSomethingSelected) {
				yield break;
			}
			var node = context.GetNode<VariableDeclarationStatement>();
			if (node == null || node.Variables.Count != 1) {
				yield break;
			}
			var initializer = node.Variables.First();
			if (!initializer.NameToken.Contains(context.Location) || initializer.Initializer.IsNull) {
				yield break;
			}
			var resolveResult = context.Resolve(initializer) as LocalResolveResult;
			if (resolveResult == null || resolveResult.IsError) {
				yield break;
			}
			var unit = context.RootNode as SyntaxTree;
			if (unit == null) {
				yield break;
			}
			yield return new CodeAction(context.TranslateString("Inline local variable"), script => {
				refFinder.FindLocalReferences(resolveResult.Variable, context.UnresolvedFile, unit, context.Compilation, (n, r) => script.Replace(n, AddParensIfRequired (n, initializer.Initializer.Clone())), default(CancellationToken));
				script.Remove(node);
			}, initializer);
		}
예제 #16
0
		CodeAction ActionFromUsingStatement(RefactoringContext context)
		{
			var initializer = context.GetNode<VariableInitializer>();
			if (initializer == null)
				return null;
			var initializerRR = context.Resolve(initializer) as LocalResolveResult;
			if (initializerRR == null)
				return null;
			var elementType = GetElementType(initializerRR, context);
			if (elementType == null)
				return null;
			var usingStatement = initializer.Parent.Parent as UsingStatement;
			if (usingStatement == null)
				return null;
			return new CodeAction(context.TranslateString("Iterate via foreach"), script => {
				var iterator = MakeForeach(new IdentifierExpression(initializer.Name), elementType, context);
				if (usingStatement.EmbeddedStatement is EmptyStatement) {
					var blockStatement = new BlockStatement();
					blockStatement.Statements.Add(iterator);
					script.Replace(usingStatement.EmbeddedStatement, blockStatement);
					script.FormatText(blockStatement);
				} else if (usingStatement.EmbeddedStatement is BlockStatement) {
					var anchorNode = usingStatement.EmbeddedStatement.FirstChild;
					script.InsertAfter(anchorNode, iterator);
					script.FormatText(usingStatement.EmbeddedStatement);
				}
			});
		}
        public IEnumerable<CodeAction> GetActions(RefactoringContext context)
        {
            var createExpression = context.GetNode<Expression>() as ObjectCreateExpression;
            if (createExpression == null)
                yield break;

            var resolveResult = context.Resolve(createExpression) as CSharpInvocationResolveResult;
            if (resolveResult == null || !resolveResult.IsError || resolveResult.Member.DeclaringTypeDefinition == null || resolveResult.Member.DeclaringTypeDefinition.IsSealed || resolveResult.Member.DeclaringTypeDefinition.Region.IsEmpty)
                yield break;

            yield return new CodeAction(context.TranslateString("Create constructor"), script => {
                var decl = new ConstructorDeclaration() {
                    Name = resolveResult.Member.DeclaringTypeDefinition.Name,
                    Modifiers = Modifiers.Public,
                    Body = new BlockStatement() {
                        new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
                    }
                };
                decl.Parameters.AddRange(CreateMethodDeclarationAction.GenerateParameters(context, createExpression.Arguments));

                script.InsertWithCursor(
                    context.TranslateString("Create constructor"),
                    resolveResult.Member.DeclaringTypeDefinition,
                    decl
                );
            }, createExpression);
        }
		public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var property = context.GetNode<PropertyDeclaration>();
			if (property == null || !property.NameToken.Contains(context.Location))
				yield break;

			var field = GetBackingField(context, property);
			if (!IsValidField(field, property.GetParent<TypeDeclaration>())) {
				yield break;
			}
			// create new auto property
			var newProperty = (PropertyDeclaration)property.Clone();
			newProperty.Getter.Body = BlockStatement.Null;
			newProperty.Setter.Body = BlockStatement.Null;
			
			yield return new CodeAction(context.TranslateString("Convert to auto property"), script => {
				script.Rename((IEntity)field, newProperty.Name);
				var oldField = context.RootNode.GetNodeAt<FieldDeclaration>(field.Region.Begin);
				if (oldField.Variables.Count == 1) {
					script.Remove(oldField);
				} else {
					var newField = (FieldDeclaration)oldField.Clone();
					foreach (var init in newField.Variables) {
						if (init.Name == field.Name) {
							init.Remove();
							break;
						}
					}
					script.Replace(oldField, newField);
				}
				script.Replace (property, newProperty);
			}, property.NameToken);
		}
		public static IEnumerable<AstNode> GenerateImplementation(RefactoringContext context, IEnumerable<Tuple<IMember, bool>> toImplement)
		{
			var nodes = new Dictionary<IType, List<AstNode>>();
			
			foreach (var member in toImplement) {
				if (!nodes.ContainsKey(member.Item1.DeclaringType)) 
					nodes [member.Item1.DeclaringType] = new List<AstNode>();
				nodes [member.Item1.DeclaringType].Add(GenerateMemberImplementation(context, member.Item1, member.Item2));
			}
			
			foreach (var kv in nodes) {
				if (kv.Key.Kind == TypeKind.Interface) {
					yield return new PreProcessorDirective(
						PreProcessorDirectiveType.Region,
						string.Format("{0} implementation", kv.Key.Name));
				} else {
					yield return new PreProcessorDirective(
						PreProcessorDirectiveType.Region,
						string.Format("implemented abstract members of {0}", kv.Key.Name));
				}
				foreach (var member in kv.Value)
					yield return member;
				yield return new PreProcessorDirective(
					PreProcessorDirectiveType.Endregion
				);
			}
		}
		static AnonymousMethodExpression GetAnonymousMethodExpression (RefactoringContext context, out IType delegateType)
		{
			delegateType = null;
			
			var anonymousMethodExpression = context.GetNode<AnonymousMethodExpression> ();
			if (anonymousMethodExpression == null || !anonymousMethodExpression.DelegateToken.Contains (context.Location) || anonymousMethodExpression.HasParameterList)
				return null;
			
			IType resolvedType = null;
			var parent = anonymousMethodExpression.Parent;
			
			if (parent is AssignmentExpression) {
				resolvedType = context.Resolve (((AssignmentExpression)parent).Left).Type;
			} else if (parent is VariableInitializer) {
				resolvedType = context.Resolve (((VariableDeclarationStatement)parent.Parent).Type).Type;
			} else if (parent is InvocationExpression) {
				// TODO: handle invocations
			}
			if (resolvedType == null)
				return null;
			delegateType = resolvedType;
			if (delegateType.Kind != TypeKind.Delegate) 
				return null;
			
			return anonymousMethodExpression;
		}
		public IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var expr = GetCreatePropertyOrFieldNode(context);
			if (expr == null)
				yield break;
			if (!(expr is MemberReferenceExpression))
				yield break;
			var propertyName = CreatePropertyAction.GetPropertyName(expr);
			if (propertyName == null)
				yield break;
			if (IsInvocationTarget(expr))
				yield break;
			var statement = expr.GetParent<Statement>();
			if (statement == null)
				yield break;
			if (!(context.Resolve(expr).IsError))
				yield break;
			var guessedType = CreateFieldAction.GuessType(context, expr);
			if (guessedType == null || guessedType.Kind != TypeKind.Enum)
				yield break;
			var state = context.GetResolverStateBefore(expr);
			if (state.CurrentMember == null || state.CurrentTypeDefinition == null)
				yield break;

			yield return new CodeAction(context.TranslateString("Create enum value"), script => {
				var decl = new EnumMemberDeclaration {
					Name = propertyName
				};
				script.InsertWithCursor(context.TranslateString("Create enum value"), guessedType.GetDefinition (), decl);
			});
			
		}
예제 #22
0
		public bool IsValid (RefactoringContext context)
		{
			var identifier = CreateField.GetIdentifier (context);
			if (identifier == null)
				return false;
			return context.Resolve (identifier) == null && CreateField.GuessType (context, identifier) != null;
		}
		static AnonymousMethodExpression GetAnonymousMethodExpression (RefactoringContext context, out ITypeDefinition delegateType)
		{
			delegateType = null;
			
			var anonymousMethodExpression = context.GetNode<AnonymousMethodExpression> ();
			if (anonymousMethodExpression == null || !anonymousMethodExpression.DelegateToken.Contains (context.Location.Line, context.Location.Column) || anonymousMethodExpression.HasParameterList)
				return null;
			
			AstType resolvedType = null;
			var parent = anonymousMethodExpression.Parent;
			if (parent is AssignmentExpression) {
				resolvedType = context.ResolveType (((AssignmentExpression)parent).Left);
			} else if (parent is VariableDeclarationStatement) {
				resolvedType = context.ResolveType (((VariableDeclarationStatement)parent).Type);
			} else if (parent is InvocationExpression) {
				// TODO: handle invocations
			}
			
			if (resolvedType == null)
				return null;
			delegateType = context.GetDefinition (resolvedType);
			if (delegateType == null || delegateType.ClassType != ClassType.Delegate) 
				return null;
			
			return anonymousMethodExpression;
		}
예제 #24
0
		public void Run (RefactoringContext context)
		{
			var identifier = GetIdentifier (context);
			using (var script = context.StartScript ()) {
				script.InsertWithCursor ("Create property", GeneratePropertyDeclaration (context, identifier), Script.InsertPosition.Before);
			}
		}
		public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var service = (CodeGenerationService)context.GetService(typeof(CodeGenerationService)); 
			if (service == null)
				yield break;

			var type = context.GetNode<AstType>();
			if (type == null || type.Role != Roles.BaseType)
				yield break;
			var state = context.GetResolverStateBefore(type);
			if (state.CurrentTypeDefinition == null)
				yield break;

			var resolveResult = context.Resolve(type);
			if (resolveResult.Type.Kind != TypeKind.Interface)
				yield break;

			bool interfaceMissing;
			var toImplement = ImplementInterfaceAction.CollectMembersToImplement(
				state.CurrentTypeDefinition,
				resolveResult.Type,
				false,
				out interfaceMissing
			);
			if (toImplement.Count == 0)
				yield break;

			yield return new CodeAction(context.TranslateString("Implement interface explicit"), script =>
				script.InsertWithCursor(
					context.TranslateString("Implement Interface"),
					state.CurrentTypeDefinition,
					(s, c) => ImplementInterfaceAction.GenerateImplementation (c, toImplement.Select (t => Tuple.Create (t.Item1, true)), interfaceMissing).ToList()
				)
			, type);
		}
		public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var pdecl = context.GetNode<PropertyDeclaration> ();
			if (pdecl == null || !pdecl.Getter.IsNull && !pdecl.Setter.IsNull || !pdecl.NameToken.Contains(context.Location)) { 
				yield break;
			}

			var type = pdecl.Parent as TypeDeclaration;
			if (type != null && type.ClassType == ClassType.Interface) {
				yield break;
			}
			yield return new CodeAction (pdecl.Setter.IsNull ? context.TranslateString("Add setter") : context.TranslateString("Add getter"), script => {
				Statement accessorStatement = null;
			
				var accessor = new Accessor ();
				if (!pdecl.Getter.IsNull && !pdecl.Getter.Body.IsNull || !pdecl.Setter.IsNull && !pdecl.Setter.Body.IsNull) {
					accessorStatement = BuildAccessorStatement(context, pdecl);
					accessor.Body = new BlockStatement { accessorStatement };
				}

				accessor.Role = pdecl.Setter.IsNull ? PropertyDeclaration.SetterRole : PropertyDeclaration.GetterRole;

				if (pdecl.Setter.IsNull && !pdecl.Getter.IsNull) {
					script.InsertAfter(pdecl.Getter, accessor);
				} else if (pdecl.Getter.IsNull && !pdecl.Setter.IsNull) {
					script.InsertBefore(pdecl.Setter, accessor);
				} else {
					script.InsertBefore(pdecl.Getter, accessor);
				}
				script.FormatText(pdecl);
				if (accessorStatement != null)
					script.Select(accessorStatement);
			}, pdecl.NameToken);
		}
예제 #27
0
		static IfElseStatement GetIfElseStatement (RefactoringContext context)
		{
			var result = context.GetNode<IfElseStatement> ();
			if (result != null && result.IfToken.Contains (context.Location))
				return result;
			return null;
		}
		static PropertyDeclaration GetPropertyDeclaration (RefactoringContext context)
		{
			var node = context.GetNode ();
			if (node == null)
				return null;
			return node.Parent as PropertyDeclaration;
		}
예제 #29
0
		static VariableDeclarationStatement GetVariableDeclarationStatement (RefactoringContext context)
		{
			var result = context.GetNode<VariableDeclarationStatement> ();
			if (result != null && result.Variables.Count == 1 && !result.Variables.First ().Initializer.IsNull && result.Type.Contains (context.Location) && !result.Type.IsVar ())
				return result;
			return null;
		}
예제 #30
0
		static PrimitiveExpression GetEmptyString (RefactoringContext context)
		{
			var node = context.GetNode<PrimitiveExpression> ();
			if (node == null || !(node.Value is string) || node.Value.ToString () != "")
				return null;
			return  node;
		}
예제 #31
0
        protected override CodeAction GetAction(RefactoringContext context, Expression expression)
        {
            if (expression == null)
            {
                return(null);
            }
            if (expression.Role != Roles.Argument || expression is NamedArgumentExpression)
            {
                return(null);
            }
            if (context.Location != expression.StartLocation)
            {
                return(null);
            }
            var parent = expression.Parent;

            if (!(parent is Al.Attribute) && !(parent is IndexerExpression) && !(parent is InvocationExpression))
            {
                return(null);
            }

            var attribute = parent as Al.Attribute;

            if (attribute != null)
            {
                var resolvedResult = context.Resolve(attribute) as AlInvocationResolveResult;
                if (resolvedResult == null || resolvedResult.IsError)
                {
                    return(null);
                }
                var     arguments = attribute.Arguments;
                IMember member    = resolvedResult.Member;

                int index = 0;
                int temp  = 0;
                List <Expression> nodes = new List <Expression>();
                foreach (var argument in arguments)
                {
                    if (argument.Equals(expression))
                    {
                        nodes = CollectNodes(parent, expression);
                        break;
                    }
                    temp++;
                }
                index = temp;
                if (!nodes.Any())
                {
                    return(null);
                }
                var method = member as IMethod;
                if (method == null || method.Parameters.Count == 0 || method.Parameters.Last().IsParams)
                {
                    return(null);
                }

                var parameterMap = resolvedResult.GetArgumentToParameterMap();
                var parameters   = method.Parameters;
                if (index >= parameterMap.Count)
                {
                    return(null);
                }
                var name = parameters[parameterMap[index]].Name;
                return(new CodeAction(string.Format(context.TranslateString("Add argument name '{0}'"), name), script => {
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        int p = index + i;
                        if (p >= parameterMap.Count)
                        {
                            break;
                        }
                        name = parameters[parameterMap[p]].Name;
                        var namedArgument = new NamedArgumentExpression(name, arguments.ElementAt(p).Clone());
                        script.Replace(arguments.ElementAt(p), namedArgument);
                    }
                },
                                      expression
                                      ));
            }

            var indexerExpression = parent as IndexerExpression;

            if (indexerExpression != null)
            {
                var resolvedResult = context.Resolve(indexerExpression) as AlInvocationResolveResult;
                if (resolvedResult == null || resolvedResult.IsError)
                {
                    return(null);
                }
                var     arguments = indexerExpression.Arguments;
                IMember member    = resolvedResult.Member;

                int index = 0;
                int temp  = 0;
                List <Expression> nodes = new List <Expression>();
                foreach (var argument in arguments)
                {
                    if (argument.Equals(expression))
                    {
                        nodes = CollectNodes(parent, expression);
                        break;
                    }
                    temp++;
                }
                index = temp;
                if (!nodes.Any())
                {
                    return(null);
                }
                var property = member as IProperty;
                if (property == null || property.Parameters.Count == 0 || property.Parameters.Last().IsParams)
                {
                    return(null);
                }
                var parameterMap = resolvedResult.GetArgumentToParameterMap();
                var parameters   = property.Parameters;
                if (index >= parameterMap.Count)
                {
                    return(null);
                }
                var name = parameters[parameterMap[index]].Name;
                return(new CodeAction(string.Format(context.TranslateString("Add argument name '{0}'"), name), script => {
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        int p = index + i;
                        if (p >= parameterMap.Count)
                        {
                            break;
                        }
                        name = parameters[parameterMap[p]].Name;
                        var namedArgument = new NamedArgumentExpression(name, arguments.ElementAt(p).Clone());
                        script.Replace(arguments.ElementAt(p), namedArgument);
                    }
                },
                                      expression
                                      ));
            }

            var invocationExpression = parent as InvocationExpression;

            if (invocationExpression != null)
            {
                var resolvedResult = context.Resolve(invocationExpression) as AlInvocationResolveResult;
                if (resolvedResult == null || resolvedResult.IsError)
                {
                    return(null);
                }
                var     arguments = invocationExpression.Arguments;
                IMember member    = resolvedResult.Member;

                int index = 0;
                int temp  = 0;
                List <Expression> nodes = new List <Expression>();
                foreach (var argument in arguments)
                {
                    if (argument.Equals(expression))
                    {
                        nodes = CollectNodes(parent, expression);
                        break;
                    }
                    temp++;
                }
                index = temp;
                if (!nodes.Any())
                {
                    return(null);
                }

                var method = member as IMethod;
                if (method == null || method.Parameters.Count == 0 || method.Parameters.Last().IsParams)
                {
                    return(null);
                }

                var parameterMap = (resolvedResult as AlInvocationResolveResult).GetArgumentToParameterMap();
                var parameters   = method.Parameters;
                if (index >= parameterMap.Count)
                {
                    return(null);
                }
                var name = parameters[parameterMap[index]].Name;
                return(new CodeAction(string.Format(context.TranslateString("Add argument name '{0}'"), name), script => {
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        int p = index + i;
                        if (p >= parameterMap.Count)
                        {
                            break;
                        }
                        name = parameters[parameterMap[p]].Name;
                        var namedArgument = new NamedArgumentExpression(name, arguments.ElementAt(p).Clone());
                        script.Replace(arguments.ElementAt(p), namedArgument);
                    }
                },
                                      expression
                                      ));
            }
            return(null);
        }
        CodeAction CreateFromStatements(RefactoringContext context, List <AstNode> statements)
        {
            if (!(statements [0].Parent is Statement))
            {
                return(null);
            }

            return(new CodeAction(context.TranslateString("Extract method"), script => {
                string methodName = "NewMethod";
                var method = new MethodDeclaration()
                {
                    ReturnType = new PrimitiveType("sub"),
                    Name = methodName,
                    Body = new BlockStatement()
                };
                bool usesNonStaticMember = false;
                foreach (var node in statements)
                {
                    usesNonStaticMember |= StaticVisitor.UsesNotStaticMember(context, node);
                    if (node is Statement)
                    {
                        method.Body.Add((Statement)node.Clone());
                    }
                    else
                    {
                        method.Body.AddChildUnsafe(node.Clone(), node.Role);
                    }
                }
                if (!usesNonStaticMember)
                {
                    method.Modifiers |= Modifiers.Static;
                }

                var target = new IdentifierExpression(methodName);
                var invocation = new InvocationExpression(target);

                var usedVariables = VariableLookupVisitor.Analyze(context, statements);

                var inExtractedRegion = new VariableUsageAnalyzation(context, usedVariables);
                var lastStatement = statements [statements.Count - 1];

                var stmt = statements [0].GetParent <BlockStatement>();
                while (stmt.GetParent <BlockStatement> () != null)
                {
                    stmt = stmt.GetParent <BlockStatement>();
                }

                inExtractedRegion.SetAnalyzedRange(statements [0], lastStatement);
                stmt.AcceptVisitor(inExtractedRegion);

                var beforeExtractedRegion = new VariableUsageAnalyzation(context, usedVariables);
                beforeExtractedRegion.SetAnalyzedRange(statements [0].Parent, statements [0], true, false);
                stmt.AcceptVisitor(beforeExtractedRegion);

                var afterExtractedRegion = new VariableUsageAnalyzation(context, usedVariables);
                afterExtractedRegion.SetAnalyzedRange(lastStatement, stmt.Statements.Last(), false, true);
                stmt.AcceptVisitor(afterExtractedRegion);
                usedVariables.Sort((l, r) => l.Region.Begin.CompareTo(r.Region.Begin));

                IVariable generatedReturnVariable = null;
                foreach (var variable in usedVariables)
                {
                    if ((variable is IParameter) || beforeExtractedRegion.Has(variable) || !afterExtractedRegion.Has(variable))
                    {
                        continue;
                    }
                    generatedReturnVariable = variable;
                    method.ReturnType = context.CreateShortType(variable.Type);
                    method.Body.Add(new ReturnStatement(new IdentifierExpression(variable.Name)));
                    break;
                }

                int parameterOutCount = 0;
                foreach (var variable in usedVariables)
                {
                    if (!(variable is IParameter) && !beforeExtractedRegion.Has(variable) && !afterExtractedRegion.Has(variable))
                    {
                        continue;
                    }
                    if (variable == generatedReturnVariable)
                    {
                        continue;
                    }
                    Expression argumentExpression = new IdentifierExpression(variable.Name);

                    ParameterModifier mod = ParameterModifier.None;
                    if (inExtractedRegion.GetStatus(variable) == VariableState.Changed)
                    {
                        if (beforeExtractedRegion.GetStatus(variable) == VariableState.None)
                        {
                            mod = ParameterModifier.Out;
                            argumentExpression = new DirectionExpression(FieldDirection.Out, argumentExpression);
                            parameterOutCount++;
                        }
                        else
                        {
                            mod = ParameterModifier.Ref;
                            argumentExpression = new DirectionExpression(FieldDirection.Ref, argumentExpression);
                        }
                    }

                    method.Parameters.Add(new ParameterDeclaration(context.CreateShortType(variable.Type), variable.Name, mod));
                    invocation.Arguments.Add(argumentExpression);
                }

                ParameterDeclaration parameterToTransform = null;
                bool transformParameterToReturn = method.ReturnType is PrimitiveType &&
                                                  ((PrimitiveType)method.ReturnType).Keyword == "sub" &&
                                                  parameterOutCount == 1;
                if (transformParameterToReturn)
                {
                    parameterToTransform = method.Parameters.First(p => p.ParameterModifier == ParameterModifier.Out);
                    parameterToTransform.Remove();
                    var argumentExpression = invocation.Arguments.OfType <DirectionExpression>().First(a => a.FieldDirection == FieldDirection.Out);
                    argumentExpression.Remove();
                    method.ReturnType = parameterToTransform.Type.Clone();
                    var argumentDecl = new VariableDeclarationStatement(parameterToTransform.Type.Clone(), parameterToTransform.Name);
                    method.Body.InsertChildBefore(method.Body.First(), argumentDecl, BlockStatement.StatementRole);
                    method.Body.Add(new ReturnStatement(new IdentifierExpression(parameterToTransform.Name)));
                }

                script
                .InsertWithCursor(context.TranslateString("Extract method"), Script.InsertPosition.Before, method)
                .ContinueScript(delegate {
                    foreach (var node in statements.Skip(1))
                    {
                        if (node is NewLineNode)
                        {
                            continue;
                        }
                        script.Remove(node);
                    }
                    foreach (var variable in usedVariables)
                    {
                        if ((variable is IParameter) || beforeExtractedRegion.Has(variable) || !afterExtractedRegion.Has(variable))
                        {
                            continue;
                        }
                        if (variable == generatedReturnVariable)
                        {
                            continue;
                        }
                        script.InsertBefore(statements [0], new VariableDeclarationStatement(context.CreateShortType(variable.Type), variable.Name));
                    }
                    Statement invocationStatement;

                    if (generatedReturnVariable != null)
                    {
                        invocationStatement = new VariableDeclarationStatement(new SimpleType("var"), generatedReturnVariable.Name, invocation);
                    }
                    else if (transformParameterToReturn)
                    {
                        invocationStatement = new AssignmentExpression(new IdentifierExpression(parameterToTransform.Name), invocation);
                    }
                    else
                    {
                        invocationStatement = invocation;
                    }

                    script.Replace(statements [0], invocationStatement);


                    script.Link(target, method.NameToken);
                });
            }, statements.First().StartLocation, statements.Last().EndLocation));
        }
        public override IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            var node = context.GetNode <EntityDeclaration>();

            if (node == null)
            {
                yield break;
            }

            var selectedNode = node.GetNodeAt(context.Location);

            if (selectedNode == null)
            {
                yield break;
            }

            if (selectedNode.Role != PropertyDeclaration.SetKeywordRole &&
                selectedNode.Role != PropertyDeclaration.GetKeywordRole &&
                selectedNode != node.NameToken)
            {
                if (selectedNode.Role == EntityDeclaration.ModifierRole)
                {
                    var mod = (AlModifierToken)selectedNode;
                    if ((mod.Modifier & Modifiers.VisibilityMask) == 0)
                    {
                        yield break;
                    }
                }
                else
                {
                    yield break;
                }
            }

            if (node is EnumMemberDeclaration)
            {
                yield break;
            }

            if (node.HasModifier(Modifiers.Override))
            {
                yield break;
            }

            var parentTypeDeclaration = node.GetParent <TypeDeclaration>();

            if (parentTypeDeclaration != null && parentTypeDeclaration.ClassType == ClassType.Interface)
            {
                //Interface members have no access modifiers
                yield break;
            }

            var resolveResult = context.Resolve(node) as MemberResolveResult;

            if (resolveResult != null)
            {
                if (resolveResult.Member.ImplementedInterfaceMembers.Any())
                {
                    yield break;
                }
            }

            foreach (var accessName in accessibilityLevels.Keys)
            {
                var access = accessibilityLevels [accessName];

                if (parentTypeDeclaration == null && ((access & (Modifiers.Private | Modifiers.Protected)) != 0))
                {
                    //Top-level declarations can only be public or internal
                    continue;
                }

                var accessor = node as Accessor;
                if (accessor != null)
                {
                    //Allow only converting to modifiers stricter than the parent entity

                    var actualParentAccess = GetActualAccess(parentTypeDeclaration, accessor.GetParent <EntityDeclaration>());
                    if (access != actualParentAccess && !IsStricterThan(access, actualParentAccess))
                    {
                        continue;
                    }
                }

                if (GetActualAccess(parentTypeDeclaration, node) != access)
                {
                    yield return(GetActionForLevel(context, accessName, access, node, selectedNode));
                }
            }
        }
예제 #34
0
 StaticVisitor(RefactoringContext context)
 {
     this.context = context;
 }
예제 #35
0
        public override System.Collections.Generic.IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            Expression expr = null;
            AstNode    token;

            if (!NegateRelationalExpressionAction.GetLogicalExpression(context, out expr, out token))
            {
                yield break;
            }

            var uOp = expr as UnaryOperatorExpression;

            if (uOp != null)
            {
                yield return(new CodeAction(
                                 string.Format(context.TranslateString("Invert '{0}'"), expr),
                                 script => {
                    script.Replace(uOp, AlUtil.InvertCondition(AlUtil.GetInnerMostExpression(uOp.Expression)));
                }, token
                                 ));

                yield break;
            }

            var negativeExpression = AlUtil.InvertCondition(expr);

            if (expr.Parent is ParenthesizedExpression && expr.Parent.Parent is UnaryOperatorExpression)
            {
                var unaryOperatorExpression = expr.Parent.Parent as UnaryOperatorExpression;
                if (unaryOperatorExpression.Operator == UnaryOperatorType.Not)
                {
                    yield return(new CodeAction(
                                     string.Format(context.TranslateString("Invert '{0}'"), unaryOperatorExpression),
                                     script => {
                        script.Replace(unaryOperatorExpression, negativeExpression);
                    }, token
                                     ));

                    yield break;
                }
            }
            var newExpression = new UnaryOperatorExpression(UnaryOperatorType.Not, new ParenthesizedExpression(negativeExpression));

            yield return(new CodeAction(
                             string.Format(context.TranslateString("Invert '{0}'"), expr),
                             script => {
                script.Replace(expr, newExpression);
            }, token
                             ));
        }
예제 #36
0
        public async Task ComputeRefactoringsAsync(RefactoringContext context, TNode node)
        {
            if (!ValidateNode(node, context.Span))
            {
                return;
            }

            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            TSymbol symbol = GetMemberSymbol(node, semanticModel, context.CancellationToken);

            if (EqualityComparer <TSymbol> .Default.Equals(symbol, default(TSymbol)))
            {
                return;
            }

            TDeclaration declaration = await GetMemberDeclarationAsync(symbol, context.CancellationToken).ConfigureAwait(false);

            if (declaration == null)
            {
                return;
            }

            for (SyntaxNode parent = node.Parent; parent != null; parent = parent.Parent)
            {
                if (object.ReferenceEquals(declaration, parent))
                {
                    return;
                }
            }

            (ExpressionSyntax expression, SyntaxList <StatementSyntax> statements) = GetExpressionOrStatements(declaration);

            SyntaxNode nodeIncludingConditionalAccess = node.WalkUp(SyntaxKind.ConditionalAccessExpression);

            if (expression != null ||
                (statements.Any() && nodeIncludingConditionalAccess.IsParentKind(SyntaxKind.ExpressionStatement)))
            {
                ImmutableArray <ParameterInfo> parameterInfos = GetParameterInfos(node, symbol);

                if (parameterInfos.IsDefault)
                {
                    return;
                }

                INamedTypeSymbol enclosingType = semanticModel.GetEnclosingNamedType(node.SpanStart, context.CancellationToken);

                SemanticModel declarationSemanticModel = (node.SyntaxTree == declaration.SyntaxTree)
                    ? semanticModel
                    : await context.Solution.GetDocument(declaration.SyntaxTree).GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

                InlineRefactoring <TNode, TDeclaration, TSymbol> refactoring = CreateRefactoring(context.Document, nodeIncludingConditionalAccess, enclosingType, symbol, declaration, parameterInfos, semanticModel, declarationSemanticModel, context.CancellationToken);

                string title = CSharpFacts.GetTitle(declaration);

                if (expression != null)
                {
                    context.RegisterRefactoring($"Inline {title}", cancellationToken => refactoring.InlineAsync(nodeIncludingConditionalAccess, expression, cancellationToken));

                    context.RegisterRefactoring($"Inline and remove {title}", cancellationToken => refactoring.InlineAndRemoveAsync(nodeIncludingConditionalAccess, expression, cancellationToken));
                }
                else
                {
                    var expressionStatement = (ExpressionStatementSyntax)nodeIncludingConditionalAccess.Parent;

                    context.RegisterRefactoring($"Inline {title}", cancellationToken => refactoring.InlineAsync(expressionStatement, statements, cancellationToken));

                    context.RegisterRefactoring($"Inline and remove {title}", cancellationToken => refactoring.InlineAndRemoveAsync(expressionStatement, statements, cancellationToken));
                }
            }
        }
예제 #37
0
 public VariableUsageAnalyzation(RefactoringContext context, List <IVariable> usedVariables)
 {
     this.context       = context;
     this.usedVariables = usedVariables;
 }
예제 #38
0
        protected override CodeAction GetAction(RefactoringContext context, IfElseStatement node)
        {
            if (!node.IfToken.Contains(context.Location))
            {
                return(null);
            }
            Expression rightSide;
            var        comparedNode = CheckNode(node, out rightSide);

            if (comparedNode == null)
            {
                return(null);
            }

            return(new CodeAction(context.TranslateString("Replace with '??'"),
                                  script => {
                var previousNode = node.GetPrevSibling(sibling => sibling is Statement);

                var previousDeclaration = previousNode as VariableDeclarationStatement;
                if (previousDeclaration != null && previousDeclaration.Variables.Count() == 1)
                {
                    var variable = previousDeclaration.Variables.First();

                    var comparedNodeIdentifierExpression = comparedNode as IdentifierExpression;
                    if (comparedNodeIdentifierExpression != null &&
                        comparedNodeIdentifierExpression.Identifier == variable.Name)
                    {
                        script.Replace(variable.Initializer, new BinaryOperatorExpression(variable.Initializer.Clone(),
                                                                                          BinaryOperatorType.NullCoalescing,
                                                                                          rightSide.Clone()));
                        script.Remove(node);

                        return;
                    }
                }

                var previousExpressionStatement = previousNode as ExpressionStatement;
                if (previousExpressionStatement != null)
                {
                    var previousAssignment = previousExpressionStatement.Expression as AssignmentExpression;
                    if (previousAssignment != null &&
                        comparedNode.IsMatch(previousAssignment.Left))
                    {
                        var newExpression = new BinaryOperatorExpression(previousAssignment.Right.Clone(),
                                                                         BinaryOperatorType.NullCoalescing,
                                                                         rightSide.Clone());

                        script.Replace(previousAssignment.Right, newExpression);
                        script.Remove(node);
                        return;
                    }
                }

                var coalescedExpression = new BinaryOperatorExpression(comparedNode.Clone(),
                                                                       BinaryOperatorType.NullCoalescing,
                                                                       rightSide.Clone());

                var newAssignment = new ExpressionStatement(new AssignmentExpression(comparedNode.Clone(), coalescedExpression));
                script.Replace(node, newAssignment);
            }, node));
        }
예제 #39
0
        public IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            // return
            var returnStatement = context.GetNode <ReturnStatement> ();

            if (returnStatement != null)
            {
                var action = GetAction(context, returnStatement, returnStatement.Expression,
                                       expr => new Statement[]
                {
                    new IfElseStatement(expr.Condition.Clone(),
                                        new ReturnStatement(expr.TrueExpression.Clone()),
                                        new ReturnStatement(expr.FalseExpression.Clone()))
                });
                if (action != null)
                {
                    yield return(action);
                }
                yield break;
            }

            // assignment
            var assignment = context.GetNode <AssignmentExpression> ();

            if (assignment != null)
            {
                var statement = assignment.Parent as ExpressionStatement;
                if (statement == null)
                {
                    yield break;
                }

                // statement is in for initializer/iterator
                if (statement.Parent is ForStatement &&
                    statement != ((ForStatement)statement.Parent).EmbeddedStatement)
                {
                    yield break;
                }

                // statement is in using resource-acquisition
                if (statement.Parent is UsingStatement &&
                    statement != ((UsingStatement)statement.Parent).EmbeddedStatement)
                {
                    yield break;
                }

                var action = GetAction(context, statement, assignment.Right,
                                       expr => new Statement [] { ConvertAssignment(assignment.Left, assignment.Operator, expr) });
                if (action != null)
                {
                    yield return(action);
                }

                yield break;
            }

            // variable initializer
            var initializer = context.GetNode <VariableInitializer> ();

            if (initializer != null && initializer.Parent is VariableDeclarationStatement &&
                initializer.Parent.Parent is BlockStatement)
            {
                var variableDecl    = (VariableDeclarationStatement)initializer.Parent;
                var newVariableDecl = (VariableDeclarationStatement)variableDecl.Clone();
                foreach (var variable in newVariableDecl.Variables)
                {
                    if (variable.Name == initializer.Name)
                    {
                        variable.Initializer = Expression.Null;
                    }
                }

                var action = GetAction(context, variableDecl, initializer.Initializer,
                                       expr => new Statement []
                {
                    newVariableDecl,
                    ConvertAssignment(new IdentifierExpression(initializer.Name), AssignmentOperatorType.Assign,
                                      expr)
                });
                if (action != null)
                {
                    yield return(action);
                }
            }
        }